本此設(shè)計(jì)選擇STC89C52單片機(jī)作為主控芯片,選取帶有光電編碼器的直流電機(jī)作為被控對(duì)象,利用單片機(jī)的T0定時(shí)器產(chǎn)生PWM信號(hào)并送到直流電機(jī)。在Proteus仿真環(huán)境下搭建了L298N直流電機(jī)驅(qū)動(dòng)電路、矩陣鍵盤掃描電路以及LCD12864顯示電路。實(shí)現(xiàn)了直流電機(jī)的啟動(dòng)、加速、正轉(zhuǎn)、反轉(zhuǎn)、制動(dòng)等功能。同時(shí),采用PID控制算法可實(shí)現(xiàn)電機(jī)速度在特定的場(chǎng)合實(shí)現(xiàn)自動(dòng)切換。具體見(jiàn)附件。
1-1.png (282.89 KB, 下載次數(shù): 96)
下載附件
2020-8-16 09:37 上傳
單片機(jī)源程序如下:
- #include<reg51.h>
- #include<intrins.h>
- #include<math.h>
- #include "lcd.h"
- #include "Key.h"
- #include "Motor.h"
- #include "LCD12864.h"
- #include "KeyBoard.h"
- #include "LCD12864.h"
- #include "LcdShow.h"
- #include "PID.h"
- extern uchar State_Flag;
- extern uchar Fwd_Flag;
- extern uchar Rev_Flag;
- unsigned int KeyValue;
- unsigned int idata pwm_t;//周期
- unsigned int idata Impluse,Time_Count,ImpluseR;
- uchar idata Stop_Flag,Run_Flag,Curve_Flag;
- uint idata Set_Speed; // 設(shè)定轉(zhuǎn)速
- unsigned char idata Sz_Flag,Sr_Flag; // 記錄A相觸發(fā)后 ,B相高低電平的標(biāo)志
- float idata L_Speed,R_Speed,ReaSpeed;
- uint idata PWM_Out,R_Duty,L_Duty,Turn_now;
- sbit LSB_L = P1^0; // LSB_L
- sbit LSB_R = P1^1; // LSB_R
- void TimerInit(void) //@11.0592MHz
- {
-
- TMOD=0x01; //定時(shí)器模式
- TL0 = 0x18; //初值 1ms
- TH0 = 0xFC; //初值
-
- IT0 = 1; //設(shè)置下降沿觸發(fā) 還是低電平觸發(fā) 0低電平
- IT1 = 1; //設(shè)置下降沿觸發(fā) 還是低電平觸發(fā) 0低電平
- EA = 1;
- EX0 = 1;
- EX1 = 1;
-
- ET0 = 1;
- TR0 = 1;
- }
- void main()
- {
- LED = 0;
-
- Stop_Flag = 0;
- Lcd_Initial();
- TimerInit();
- Set_Speed = 0;
- Lcd_Clear();
- while(1)
- {
- KeyValue = Get_Keyvalue(); // 矩陣鍵盤掃描
- if(KeyValue == 14) // 輸入速度
- {
- Set_Speed = SpeedInput();
- KeyValue = 16;
- }
- Key_Process();
- if(Run_Flag)
- {
- Set_Speed = 80;
- Run_Flag = 0;
- }
-
- if(State_Flag && ~Stop_Flag)
- {
- PWM_Out = PID_Calculate(Set_Speed,abs(ReaSpeed));
- R_Duty = PWM_Out + Turn_now;
- L_Duty = PWM_Out - Turn_now;
- }
- else
- PWM_Out = 0; // 停止
- Lcd_Show();
- }
- }
-
- //定時(shí)器0中斷
- void timer0() interrupt 1
- {
- static int i;
- TL0 = 0x18; //初值
- TH0 = 0xFC; //初值
-
-
- pwm_t++;
- Time_Count++;;
- if(pwm_t == 500) //500ms
- {
- pwm_t = 0;
- if(Stop_Flag)
- {
- i++;
- L_Duty = 0;
- R_Duty = 0;
- if(i<31)
- {
- LED = ~LED;
- if(i == 30)
- {
- Stop_Flag = 0;
- i = 0;
- Set_Speed = 30;
- }
- }
- }
- }
- if( pwm_t<L_Duty)
- MotorL_Control();
- else
- MotorL_Stop();
-
- if( pwm_t<R_Duty)
- MotorR_Control();
- else
- MotorR_Stop();
- /*---------M法 測(cè)速------------*/
- if(Time_Count == 100 ) // 100ms
- {
-
- Control();
- Time_Count = 0;
- Impluse = 0;
- ImpluseR = 0;
- }
- }
- void int0() interrupt 0
- {
- Impluse++;
- if(LSB_L == 1)
- Sz_Flag = 1; // 正反轉(zhuǎn)標(biāo)志位 A相下降沿,B相高電平
-
- else Sz_Flag = 0;
- LSB_L = 1;
- }
- void int1() interrupt 2 // 外部中斷1 用于測(cè) 右輪的速度
- {
- ImpluseR++;
- if(LSB_R == 1)
- Sr_Flag = 1; // 正反轉(zhuǎn)標(biāo)志位 A相下降沿,B相高電平
-
- else Sr_Flag = 0;
- LSB_R = 1;
- }
復(fù)制代碼 |