|
仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)
Snipaste_2020-05-20_15-31-22.png (18.97 KB, 下載次數(shù): 58)
下載附件
2020-5-20 15:33 上傳
單片機(jī)源程序如下:
- #include <reg51.h>
- #include "lcd1602.h"
- #define THC0 0xf9
- #define TLC0 0x0f //
- /***********端口定義**************/
- //按鍵
- sbit StopAndStart =P0^0;
- sbit KeyTurnForward =P0^1;
- sbit KeyTurnBackward=P0^2;
- sbit KeyAddSpeed =P0^3;
- sbit KeySubSpeed =P0^4;
- //電機(jī)
- sbit CONT1=P2^3;
- sbit CONT2=P2^4;
- sbit EN =P2^5;
- //
- sbit LED1 = P2^0;
- sbit LED2 = P2^1;
- sbit LED3 = P2^2;
- /*^^^^^^^^轉(zhuǎn)態(tài)變量^^^^^^^^^^*/
- unsigned char motoEn;
- unsigned char motoDirection;
- /***********變量定義**************/
- unsigned int SpeedSet = 100; //速度設(shè)置
- unsigned int Impluse = 0; //脈沖計(jì)數(shù)
- unsigned int num = 0; //速度顯示
- unsigned int cnt = 0;
- unsigned int PWMTime=500; //脈沖寬度
- int e,e1,e2;
- float uk,uk1,duk; //PID輸出值
- float Kp=15,Ki=12,Kd=1.6;
- int out=0;
- /*^^^^^^^^延時(shí)函數(shù)^^^^^^^^^^*/
- void delay_xms(unsigned char ms)
- {
- unsigned int i,j;
- for(i=0;i<ms;i++)
- {
- for(j=0;j<333;j++);
- }
- }
- /*########系統(tǒng)初始化########*/
- void SystemInit()
- {
- //外部中斷0
- IT0 = 1; //下降沿觸發(fā)
- EX0 = 1; //開(kāi)外部中斷
- EA = 1; //開(kāi)總中斷
- //定時(shí)器0 1
- ET0=1; //開(kāi)定時(shí)器中斷
- TMOD=0X21;//T0方式2 T1方式2
- TH0 = THC0;
- TL0 = TLC0;
- TR0 = 1; //啟動(dòng)定時(shí)器0
- TH1=0x10;
- TL1=0x10;
- ET1=1;
- TR1=1;
- e = 0;
- e1 = 0;
- e2 = 0;
- motoEn=0;
- motoDirection=1;
- //LCD
- LCD1602_Init();
-
- }
- /*########按鍵掃描##########*/
- void key_scan()
- {
- //啟/停
- if(StopAndStart == 0) //判斷按下
- {
- delay_xms(10);
- if(StopAndStart == 0)
- {
-
- while(StopAndStart == 0 ); //判斷松手
- //執(zhí)行按鍵功能
- motoEn=~motoEn;
- //EN=1;
- }
- }
-
- //正轉(zhuǎn)
- if(KeyTurnForward == 0) //判斷按下
- {
- delay_xms(10);
- if(KeyTurnForward == 0)
- {
-
- while(KeyTurnForward == 0 ); //判斷松手
- //執(zhí)行按鍵功能
- motoDirection=1;
- //CONT1 = 1;
- //CONT2 = 0;
- }
- }
- //反轉(zhuǎn)
- if(KeyTurnBackward == 0) //判斷按下
- {
- delay_xms(10);
- if(KeyTurnBackward == 0)
- {
- while(KeyTurnForward == 0 ); //判斷松手
- //執(zhí)行按鍵功能
- motoDirection=0;
- //CONT1 = 0;
- //CONT2 = 1;
- }
- }
-
- //加速
- if(KeyAddSpeed == 0)
- {
- delay_xms(10);
- if(KeyAddSpeed == 0) //判斷按下
- {
- unsigned char i=0;
- while(KeyAddSpeed == 0 && i<255){delay_xms(1);i++;} //判斷松手
- //執(zhí)行按鍵功能
- SpeedSet += 5;
- if(SpeedSet>300)
- {
- SpeedSet = 300;
- }
- }
- }
- //減速
- if(KeySubSpeed == 0) //判斷按下
- {
- delay_xms(10);
- if(KeySubSpeed == 0)
- {
- unsigned char i=0;
- while(KeySubSpeed == 0 && i<255){delay_xms(1);i++;} //判斷松手
- //執(zhí)行按鍵功能
- SpeedSet -= 5;
- if(SpeedSet<0)
- {
- SpeedSet = 0;
- }
- }
- }
- }
- /*##########電機(jī)狀態(tài)動(dòng)作###########*/
- void MotoControl()
- {
- if(motoEn == 0)
- {
- EN=0;
- CONT1=0;
- CONT2=0;
- LED1 = 1;
- }
- else
- {
- EN=1;
- LED1 = 0;
- if(motoDirection == 1)
- {
- CONT1=1;
- CONT2=0;
- LED2 = 0;
- LED3 = 1;
- }
- else
- {
- CONT1=0;
- CONT2=1;
- LED2 = 1;
- LED3 = 0;
- }
- }
- }
- /*########LCD顯示###########*/
- void LCDDis()
- {
- LCD1602_4num(0,8,num);
- LCD1602_4num(1,8,SpeedSet);
- }
- /*^^^^^^^^PWM 輸出^^^^^^^^^*/
- void PWMOUT()
- {
- if(motoDirection == 1)
- {
- if(cnt<PWMTime)
- {
- CONT1=1;
- }
- else
- {
- CONT1=0;
- }
- }
- else
- {
- if(cnt<PWMTime)
- {
- CONT2=1;
- }
- else
- {
- CONT2=0;
- }
- }
- if(cnt>1000) cnt = 0;
- }
- /*########PID調(diào)速############*/
- void PIDControl() //pid偏差計(jì)算
- {
- e=SpeedSet-num;
- duk=(Kp*(e-e1)+Ki*e+Kd*(e-2*e1+e2))/50;
- uk=uk1+duk;
- out=(int)uk;
- if(out>1000)
- {
- out=1000;
- }
- else
- if(out<0)
- {
- out=0;
- }
- uk1=uk; //變量值偏移位
- e2=e1;
- e1=e;
- PWMTime=out;
- }
- /********************/
- void main()
- {
- SystemInit();
- while(1)
- {
- key_scan();//按鍵掃描
- LCDDis();//LCD顯示
- MotoControl();//根據(jù)按鍵掃描出的結(jié)果做出響應(yīng)
- PWMOUT();
-
- }
- }
- /*@@@@@@@@@@外部中斷0@@@@@@@@@@@@@@*/
- void inter0() interrupt 0
- {
- Impluse++; //采集外部脈沖數(shù)據(jù)
- }
- /*@@@@@@@@@@定時(shí)器中斷0@@@@@@@@@@@@@@*/
- void inter1() interrupt 1
- {
- static unsigned int time=0;
- TH0=THC0;
- TL0=TLC0;
- time++; //轉(zhuǎn)速測(cè)量周期
- if(time>100)
- {
- time=0;
- num=Impluse*5;
- Impluse=0;
- PIDControl();
- }
- }
- void inter3() interrupt 3
- {
- cnt++;
- if(motoDirection == 1)
- {
- if(cnt<PWMTime)
- {
- CONT1=1;
- }
- else
- {
- CONT1=0;
- }
- }
- else
- {
- if(cnt<PWMTime)
- {
- CONT2=1;
- }
- else
- {
- CONT2=0;
- }
- }
- if(cnt>1000) cnt = 0;
- }
復(fù)制代碼
全部資料51hei下載地址:
直流調(diào)速.zip
(94.76 KB, 下載次數(shù): 149)
2020-5-20 15:34 上傳
點(diǎn)擊文件名下載附件
下載積分: 黑幣 -5
|
|