?? 電機無級調制控制系統.cpp
字號:
/* 電機無級調速控制系統 */
#include <stdio.h>
#include <conio.h>
#include "ApiEx.h"
#pragma comment(lib,"ApiEx.lib")
#define ioport 0x2b0 //8279 數據口
#define ioport1 0x2b1 //8279 控制口
#define time 0x280 //8253 定時器0口地址
#define time1 0x281 //8253 定時器1口地址
#define timec 0x283 //8253 控制口地址
int k;
int disled[6]={0x00,0x00,0x00,0x00,0x00,0x00};//led從右到左顯示,最左顯示功能鍵
int realkey[4]={0x00,0x00,0x00,0x00};//得到真實的按鍵值
int led[] ={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7C,
0x39,0x5E,0x79,0x71,0x80,0x40};//0,1,2,3,4,5,6,7,8,9,A,b,C,d,E,F,g,m,P,r,w,x,y,.,-
int table[]={0x1b,0x13,0x0b,0x03,0x1a,0x12,0x0a,0x02,0x19,0x11,0x09,0x01,0x18,0x10,0x08,0x00};
int keyin=0;
void key(); //鍵盤顯示
void disp(); //顯示
void int_proc(); //中斷處理程序
void motorstart();//啟動電機
void measurespeed();//測量轉速
void pidadapt();//PID調速
int funkey=0;//0表示是功能鍵,1表示數字鍵
int datakey=0;//表示之前未按功能鍵,1表示按下了功能鍵
int keydatanum=0;//表示按下數字鍵的個數
int keycdown=0;//表示按下了E鍵
int keyedown=0;//表示按下了C鍵
int keyadaptspeed=0xff;
int getspeed=0;//測得的轉速
int j=0;
int jj=0;
int d=0;//存放給定的速度換算成高電平持續時間
int saved=0;
int keysave=0;//保存初始轉速的鍵值
BYTE data;//存放按鍵值
BYTE data1=0x00;//存計數的低8位
BYTE data2=0x00;//存計數的高8位
int count=0;//得到定時器2的當前計數值
int count1=0;//測到的轉速值
int mspeed[2]={0x00,0x00};
void main()
{
printf("--------------------EXP29_21_SYB---------------------\n");
printf("Press any key to begin!\n\n");
getch();
printf("Press small keybord:\n");
printf("A--please input the given speed;\n");
printf("B--STOP MOTOR \n");
printf("c--start the motor according the given speed;\n");
printf("F--EXIT\n");
if(!Startup()) /*打開設備*/
{
printf("ERROR: Open Device Error!\n");
return;
}
PortWriteByte(ioport1,0xd3); //8279 清零
PortWriteByte(ioport1,0x40); //讀FIFO存儲器命令
PortWriteByte(ioport1,0x00); //置鍵盤顯示模式
PortWriteByte(ioport1,0x80); //寫顯示緩沖區命令
PortWriteByte(0x283,0x36); //設置8253工作方式,定時器0工作方式3
PortWriteByte(0x280,0x50); //設置定時器0的初始計數值50000,低位為50
PortWriteByte(0x280,0xc3); //設置定時器0的初始計數值50000,高位為c3產生50ms的脈沖
PortWriteByte(0x283,0xb0); //設置8253工作方式,定時器2工作方式0,(計脈沖的個數)
PortWriteByte(0x282,0xff); //設置定時器2的初始計數值ffff,低位為ff
PortWriteByte(0x282,0xff); //設置定時器2的初始計數值ffff,高位為ff
PortWriteByte(0x28b,0x81); //設置8255工作方式,C口低四位輸入, C口高四位輸出,A口輸入,B口輸入
PortWriteByte(0x283,0x50); //設置8253工作方式,定時器1工作方式0
PortWriteByte(0x281,0x0a); //設置定時器1的初始計數值20,低位為14,定時1s
RegisterLocalISR(int_proc); /*注冊中斷程序*/
EnableIntr(); /*開中斷*/
do{
key(); //調鍵盤顯示子程序
if(keyin==0x0a) //是否'a'命令,啟動輸入電機起始值
{
disled[5]=led[0x0a];//顯示鍵A
for(jj=0;jj<4;jj++)//清真實的數字鍵值
{ realkey[jj]=0; }
disled[0]=led[0];//顯示給定值為00
disled[1]=led[0];
disled[2]=led[0];//顯示測速值為00
disled[3]=led[0];
funkey=0;//表示按下了功能鍵
keycdown=0;//表示沒有按下功能鍵E
keyedown=0;//表示沒有按下功能鍵C
datakey=1;//表示當前按下A功能鍵
mspeed[0]=0;//測定的速度顯示為00
mspeed[1]=0;
d=0;//給定的脈寬值為0
}
else if(keyin==0x0b) //是否'b' 命令,停止電機
{
disled[5]=led[0x0b];//顯示鍵B
disled[0]=led[0];//顯示給定值為00
disled[1]=led[0];
disled[2]=led[0];//顯示測速值為00
disled[3]=led[0];
disled[4]=0x00;
for(jj=0;jj<4;jj++)
{
realkey[jj]=0;
}
mspeed[0]=0;//測定的速度顯示為00
mspeed[1]=0;
funkey=0;//表示按下了功能鍵
keycdown=0;//表示沒有按下功能鍵E
keyedown=0;//表示沒有按下功能鍵C
datakey=0;//表示當前沒按下A功能鍵
d=0;//給定的脈寬值為0
keydatanum=0; //計錄的按下數字鍵值為0個
PortWriteByte(0x290,0x80); /*D/A 輸出*/
}
else if(keyin==0x0c) //是否'c' 命令,按照a給定的值使電機轉動
{
d=realkey[0]+realkey[1]*10;
disled[5]=led[0x0e];
disled[0]=led[realkey[0]];//顯示給定值
disled[1]=led[realkey[1]];
disled[2]=led[0];//顯示測速值為0
disled[3]=led[0];
disled[4]=0x00;
mspeed[0]=0;//測定的速度顯示為00
mspeed[1]=0;
funkey=0;//表示按下了功能鍵
keycdown=1;//表示沒有按下功能鍵C
keyedown=0;//表示按下功能鍵E
keydatanum=0; //計錄的按下數字鍵值為0個
disled[2]=led[mspeed[0]];//顯示測速值的低位
disled[3]=led[mspeed[1]];//顯示測速值的高位
}
else //按下的是數字鍵
{
mspeed[0]=0;//測定的速度顯示為00
mspeed[1]=0;
if ((datakey==1)&&(keycdown==0))//如果按下了A鍵之后,可以繼續按數字鍵,此時輸入的是給定的轉速值
{
keycdown=0;//表示沒有按下功能鍵C
keyedown=0;//表示按下功能鍵E
d=0;//給定的脈寬值為0
keysave=keyin;
keydatanum++;
realkey[keydatanum-1]=keyin;
disled[keydatanum-1]=led[keysave];
disled[2]=led[0];
disled[3]=led[0];
disled[4]=0x00;
}
}
}
while(!(keyin==0x0f)); //'f'命令,退出程序
d=0;
PortWriteByte(0x290,0x80); /*D/A 輸出*/
PortWriteByte(ioport1,0xd1); //清顯示
DisableIntr(); /*關中斷*/
Cleanup(); /*關閉設備*/
}
void key()
{
PortWriteByte(ioport1,0xd1); //清顯示
PortWriteByte(0x290,0x80); /*D/A 輸出*/
Sleep(100);
do{
disp(); //調顯示子程序
if(keycdown==1)//C鍵
{
motorstart();//電機開始轉動
if(keyedown==1)//如果進入調速函數
{
pidadapt();
}
}
PortReadByte(ioport1,&data);
}
while(!(data&0x07));
PortReadByte(ioport,&data); //讀狀態
keyin = data & 0x07;
data = data & 0x3f;
for(k=0;k<16;k++)
{
if(data==table[k])
keyin=k;
}
}
//數碼管顯示,最高位(最左)顯示當前功能鍵,最右兩位顯示給定值,第三、四位顯示測速值
//由void key()函數調用
void disp()
{
PortWriteByte(ioport1,0x90);
Sleep(100);
PortWriteByte(ioport,disled[0]);
PortWriteByte(ioport,disled[1]);
PortWriteByte(ioport,disled[2]);
PortWriteByte(ioport,disled[3]);
PortWriteByte(ioport,disled[4]);
PortWriteByte(ioport,disled[5]);
}
//中斷處理程序,定時1s,由void measurespeed()進入
void int_proc()
{
getspeed=0;
data1=0x00;//存計數的低8位
data2=0x00;//存計數的高8位
count=0;//得到定時器2的當前計數值
count1=0;//測到的轉速值
PortReadByte(0x282,&data1); //讀入計數器的低8位
PortReadByte(0x282,&data2); //讀入計數器的高8位
count=data2*256+data1;
count1=(65535-count)*2/6; //得到轉速
getspeed=count1;
printf("getspeed=%d\n",getspeed);
mspeed[0]=getspeed%10;//得到測到的轉速的低位
mspeed[1]=getspeed/10;//得到測到的轉速的高位
disled[2]=led[mspeed[0]];//顯示測速值的低位
disled[3]=led[mspeed[1]];//顯示測速值的高位
PortWriteByte(0x283,0x50); //設置8253工作方式,定時器1工作方式0
PortWriteByte(0x281,0x0a); //設置定時器1的初始計數值200,低位為c8,定時1s
PortWriteByte(0x283,0xb0); //設置8253工作方式,定時器2工作方式0,(計脈沖的個數)
PortWriteByte(0x282,0xff); //設置定時器2的初始計數值ffff,低位為ff
PortWriteByte(0x282,0xff); //設置定時器2的初始計數值ffff,高位為ff
PortWriteByte(0x28b,0x0f); //初始狀態時,PC7,393清零端置1,
PortWriteByte(0x28b,0x0c); //初始狀態時,PC6,393計數端置0,
}
//電機轉動函數模塊,由void key()調用
void motorstart()
{
int pulse=0;
pulse=d*128/48;
if(pulse>128)
{
PortWriteByte(0x290,0xff); /*D/A 輸出*/
}
else
{
pulse=0x80+pulse;
PortWriteByte(0x290,pulse); /*D/A 輸出*/
}
}
//測量電機的轉速,由void key()調用
void measurespeed()
{
}
//pid調速算法
void pidadapt()
{
int R=0;int es=0;int es1=0;int es2=0;
int es3=0;int es4=0;int es5=0;int es6=0;int es7=0;
int es8=0;int es9=0;int es10=0;int ies=0;int des=0;
int M=0;
int e1=0; int S=0;
es10=es9; //(以下是PID控制算法)
es9=es8;
es8=es7;
es7=es6;
es6=es5;
es5=es4;
es4=es3;
es3=es2;
es2=es1;
es1=es;
es=R-getspeed;
ies=1*(es+es1+es2+es3+es4+es5+es6+es7+es8+es9+es10);
des=es1-es2;
M=int (es+0.1*des+0.0001*ies);
motorstart();//電機開始轉動
e1=e1+M;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -