仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)
單片機源程序如下:
- #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;
- //電機
- sbit CONT1=P2^3;
- sbit CONT2=P2^4;
- sbit EN =P2^5;
- //
- sbit LED1 = P2^0;
- sbit LED2 = P2^1;
- sbit LED3 = P2^2;
- /*^^^^^^^^轉態變量^^^^^^^^^^*/
- unsigned char motoEn;
- unsigned char motoDirection;
- /***********變量定義**************/
- unsigned int SpeedSet = 100; //速度設置
- unsigned int Impluse = 0; //脈沖計數
- 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;
- /*^^^^^^^^延時函數^^^^^^^^^^*/
- void delay_xms(unsigned char ms)
- {
- unsigned int i,j;
- for(i=0;i<ms;i++)
- {
- for(j=0;j<333;j++);
- }
- }
- /*########系統初始化########*/
- void SystemInit()
- {
- //外部中斷0
- IT0 = 1; //下降沿觸發
- EX0 = 1; //開外部中斷
- EA = 1; //開總中斷
- //定時器0 1
- ET0=1; //開定時器中斷
- TMOD=0X21;//T0方式2 T1方式2
- TH0 = THC0;
- TL0 = TLC0;
- TR0 = 1; //啟動定時器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 ); //判斷松手
- //執行按鍵功能
- motoEn=~motoEn;
- //EN=1;
- }
- }
-
- //正轉
- if(KeyTurnForward == 0) //判斷按下
- {
- delay_xms(10);
- if(KeyTurnForward == 0)
- {
-
- while(KeyTurnForward == 0 ); //判斷松手
- //執行按鍵功能
- motoDirection=1;
- //CONT1 = 1;
- //CONT2 = 0;
- }
- }
- //反轉
- if(KeyTurnBackward == 0) //判斷按下
- {
- delay_xms(10);
- if(KeyTurnBackward == 0)
- {
- while(KeyTurnForward == 0 ); //判斷松手
- //執行按鍵功能
- 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++;} //判斷松手
- //執行按鍵功能
- 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++;} //判斷松手
- //執行按鍵功能
- SpeedSet -= 5;
- if(SpeedSet<0)
- {
- SpeedSet = 0;
- }
- }
- }
- }
- /*##########電機狀態動作###########*/
- 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調速############*/
- void PIDControl() //pid偏差計算
- {
- 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();//根據按鍵掃描出的結果做出響應
- PWMOUT();
-
- }
- }
- /*@@@@@@@@@@外部中斷0@@@@@@@@@@@@@@*/
- void inter0() interrupt 0
- {
- Impluse++; //采集外部脈沖數據
- }
- /*@@@@@@@@@@定時器中斷0@@@@@@@@@@@@@@*/
- void inter1() interrupt 1
- {
- static unsigned int time=0;
- TH0=THC0;
- TL0=TLC0;
- time++; //轉速測量周期
- 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;
- }
復制代碼
全部資料51hei下載地址:
直流調速.zip
(94.76 KB, 下載次數: 149)
2020-5-20 15:34 上傳
點擊文件名下載附件
|