內(nèi)含PID控制、AD轉(zhuǎn)換、12864顯示、電機(jī)測(cè)速、控制邏輯程序
仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)
51hei.png (26.53 KB, 下載次數(shù): 67)
下載附件
2021-4-20 21:30 上傳
51hei.png (11.16 KB, 下載次數(shù): 65)
下載附件
2021-4-20 21:30 上傳
仿真.png (44.34 KB, 下載次數(shù): 67)
下載附件
2021-4-20 20:53 上傳
單片機(jī)源程序如下:
- #include <MOTOR.h>
- #include <ADC.h>
- unsigned int PWM=0; //pwm占空比為50%,可調(diào)占空比
- unsigned int D;
- unsigned char time = 0;
- uchar targetM=0,factM=0;
- //PID定義
- int out = 0;
- int e, e1, e2;//pid 偏差
- float uk=0, uk1=0, duk=0;//pid輸出值
- float Kp = 0.1, Ki = 0.05, Kd = 0.016;//pid控制系數(shù) 10,12,1.5
- uint Inpluse = 0, num1 = 0;
- unsigned int time1 = 0;
- //-------------------------------
- //外部中斷0程序-測(cè)速用的
- //-------------------------------
- void int0() interrupt 0
- {
- Inpluse++;
- }
- //-------------------------------
- // PID
- //-------------------------------
- void PIDControl() //pid偏差計(jì)算
- {
- e = targetM - factM;
- duk = (Kp*(e - e1) + Ki * e + Kd * (e - 2 * e1 + e2));
- uk = uk1 + duk;
- out = (int)uk;
- if (out > 100)
- {
- out = 100;
- }
- else if (out < 0)
- {
- out = 0;
- }
- uk1 = uk;
- e2 = e1;
- e1 = e;
- D = out;
- }
- //-------------------------------
- // 定時(shí)器、中斷初始化
- //-------------------------------
- void TimeInit()
- {
- TMOD = 0X01; //定時(shí)器工作在方式1(16位定時(shí)器)
- TH0 = 0XFF; //12M晶振下定時(shí)0.1ms 65536-65436
- // TL0 = 0X9c;
- TL0 = 0Xc6; //實(shí)驗(yàn)
- ET0 = 1;
- TR0 = 1; //開(kāi)啟定時(shí)器
- EX0 = 1; //中斷0允許
- IT0 = 1; //邊沿觸發(fā)
- EA = 1;
- INT = 1;
- e = 0;
- e1 = 0;
- e2 = 0;
- IN01=0;
- }
復(fù)制代碼
- #include <reg52.h>
- #include <intrins.h>
- #include <LCD12864.h>
- #include <ADC.h>
- #include <WORDMODEL.h>
- #include <MOTOR.h>
- #define uint unsigned int
- #define uchar unsigned char
- #include <string.h>
- uchar SOC = 0, V = 0, VOLT = 0;
- //SOC
- void display0()
- {
- SOC = vol*100/255;
- temp0 = SOC / 100;
- temp1 = (SOC % 100) / 10;
- temp2 = SOC % 10;
- show_ch1(1, 0, 4 * 6, ch1 + (12 * (temp0 + 4)));
- show_ch1(1, 0, 5 * 6, ch1 + (12 * (temp1 + 4)));
- show_ch1(1, 0, 6 * 6, ch1 + (12 * (temp2 + 4)));
- }
- //車速
- void display1()
- {
- V = vol * 192 / 255;
- temp0 = V / 100;
- temp1 = (V % 100) / 10;
- temp2 = V % 10;
- show_ch1(2, 0, 3 * 6, ch1 + (12 * (temp0 + 4)));
- show_ch1(2, 0, 4 * 6, ch1 + (12 * (temp1 + 4)));
- show_ch1(2, 0, 5 * 6, ch1 + (12 * (temp2 + 4)));
- }
- //電池電壓
- void display2()
- {
- VOLT = vol * 400 / 255;
- temp0 = VOLT / 100;
- temp1 = (VOLT % 100) / 10;
- temp2 = VOLT % 10;
- show_ch1(2, 2, 0 * 6, ch1 + (12 * (temp0 + 4)));
- show_ch1(2, 2, 1 * 6, ch1 + (12 * (temp1 + 4)));
- show_ch1(2, 2, 2 * 6, ch1 + (12 * (temp2 + 4)));
- }
- //目標(biāo)制動(dòng)力矩
- void display3()
- {
- targetM = vol * 200 / 255;
- D= vol * 100 / 255;
- temp0 = targetM / 100;
- temp1 = (targetM % 100) / 10;
- temp2 = targetM % 10;
- show_ch1(2, 4, 3 * 6, ch1 + (12 * (temp0 + 4)));
- show_ch1(2, 4, 4 * 6, ch1 + (12 * (temp1 + 4)));
- show_ch1(2, 4, 5 * 6, ch1 + (12 * (temp2 + 4)));
- }
- //實(shí)際制動(dòng)力矩
- void display4()
- {
- // val=100;
- factM=num1/5 ;
- // val = vol * 192 / 255;
- temp0 = factM / 100;
- temp1 = (factM % 100) / 10;
- temp2 = factM % 10;
- show_ch1(2, 6, 3 * 6, ch1 + (12 * (temp0 + 4)));
- show_ch1(2, 6, 4 * 6, ch1 + (12 * (temp1 + 4)));
- show_ch1(2, 6, 5 * 6, ch1 + (12 * (temp2 + 4)));
- }
- void main()
- {
- InitLCD();
- TimeInit();
- ClearScreen(0);
- Set_line(0);
- //SOC顯示
- show_ch1(1,0,0*6,ch1+12*1);
- show_ch1(1,0,1*6,ch1+12*2);
- show_ch1(1,0,2*6,ch1+12*3);
- show_ch1(1, 0, 3 * 6, ch1 + 12 * 0);
- show_ch1(1, 0, 7 * 6, ch1 + 12 * 14);
- //車速顯示
- show_ch2(1, 0, 52, ch2 + 24 * 6);
- show_ch2(2, 0, 0 * 12, ch2 + 24 * 7);
- show_ch1(2, 0, 1 * 12, ch1 + 12 * 0);
- show_ch1(2, 0, 6*6, ch1 + 12 * 15);
- show_ch1(2, 0, 6 * 7, ch1 + 12 * 16);
- show_ch1(2, 0, 6 * 8, ch1 + 12 * 17);
- show_ch1(2, 0, 6 * 9, ch1 + 12 * 18);
- //電池電壓顯示
- show_ch2(1, 2, 0 * 14, ch2 + 24 * 12);
- show_ch2(1, 2, 1 * 14, ch2 + 24 * 13);
- show_ch2(1, 2, 2 * 14, ch2 + 24 * 14);
- show_ch2(1, 2, 3 * 14, ch2 + 24 * 15);
- show_ch1(1, 2, 4 * 14, ch1 + 12 * 0);
- show_ch1(2, 2, 6 * 3, ch1 + 12 * 21);
- //目標(biāo)制動(dòng)力矩顯示
- show_ch2(1, 4, 0, ch2 + 24 * 0);
- show_ch2(1, 4, 13, ch2 + 24 * 1);
- show_ch2(1, 4, 26, ch2 + 24 * 2);
- show_ch2(1, 4, 39, ch2 + 24 * 3);
- show_ch2(1, 4, 52, ch2 + 24 * 4);
- show_ch2(2, 4, 0 * 12, ch2 + 24 * 5);
- show_ch1(2, 4, 1 * 12, ch1 + 12 * 0);
- show_ch1(2, 4, 6 * 6, ch1 + 12 * 19);
- show_ch1(2, 4, 7 * 6, ch1 + 12 * 20);
- //實(shí)際制動(dòng)力矩顯示
- show_ch2(1, 6, 0 , ch2 + 24 * 16);
- show_ch2(1, 6, 13, ch2 + 24 * 17);
- show_ch2(1, 6, 26, ch2 + 24 * 2);
- show_ch2(1, 6, 39, ch2 + 24 * 3);
- show_ch2(1, 6, 52, ch2 + 24 * 4);
- show_ch2(2, 6, 0 * 12, ch2 + 24 * 5);
- show_ch1(2, 6, 1 * 12, ch1 + 12 * 0);
- show_ch1(2, 6, 6 * 6, ch1 + 12 * 19);
- show_ch1(2, 6, 7 * 6, ch1 + 12 * 20);
-
- while(1)
- {
- ADDA=0;
- ADDB=0;
- ADDC=0;
- adc();
- display0();
-
- ADDA=1;
- adc();
- display1();
-
- ADDA=0;
- ADDB=1;
- adc();
- display2();
-
- ADDA=1;
- adc();
- display3();
- if (SOC>95)
- {
- targetM = 0;
- }
- if (V <20)
- {
- targetM = 0;
- }
- if (VOLT > 390)
- {
- targetM = 0;
- }
- if (targetM > 150)
- {
- targetM = 0;
- }
- else if(targetM > 100)
- {
- targetM = targetM*0.5;
- }
-
- if (time1 > 100)
- {
- time1 = 0;
- num1 = Inpluse*103/27 ;
- Inpluse = 0;
- PIDControl();
- PWM =D;
- }
- display4();
-
- }
- }
- //-------------------------------
- //定時(shí)器0
- //-------------------------------
- void Timer0(void) interrupt 1
- {
-
- // TH0 = 0XFF; //重裝初值
- // TL0 = 0X9c; //標(biāo)準(zhǔn)值
- // TL0 = 0Xb8; //包含誤差
- TH0=0XFF;
- TL0=0X37;
- time++;
- if (time >= 100) //PWM周期為100*0.1ms
- time = 0;
- if (time < PWM)
- IN01 = 1;
- else
- IN01 = 0;
- time1++; //轉(zhuǎn)速測(cè)量周期
- }
復(fù)制代碼
51hei.png (16.25 KB, 下載次數(shù): 68)
下載附件
2021-4-20 21:33 上傳
所有資料51hei提供下載(Proteus請(qǐng)使用7.5版本):
仿真、主程序.zip
(115.49 KB, 下載次數(shù): 26)
2021-4-20 20:43 上傳
點(diǎn)擊文件名下載附件
下載積分: 黑幣 -5
|