51單片機(jī)電機(jī)pid控制系統(tǒng)程序
掃描二維碼
隨時(shí)隨地手機(jī)看文章
51單片機(jī)電機(jī)pid控制系統(tǒng)程序
本程序來(lái)源網(wǎng)上,小編進(jìn)行了簡(jiǎn)單修改,還未驗(yàn)證。
/*************************
應(yīng)用背景:直流電機(jī)的額定功率12V,額定轉(zhuǎn)速3000rpm,光碼盤12孔,
晶振為12MHz,定時(shí)/計(jì)數(shù)器T0檢測(cè)轉(zhuǎn)速,用定時(shí)器T1進(jìn)行定時(shí),
P1.0控制直流電機(jī)的正反轉(zhuǎn),用P1.1控制電機(jī)的轉(zhuǎn)速.
************************/
#include
#include
#define uchar unsigned char
uchar timcount,PWMH,SpeedSet,SpeedDet;
uchar KP,KI,KD;
int e1,e2,e3,uk,duk;
sbit Dir = P1^0;
sbit PWM = P1^1;
//延時(shí)函數(shù)
void delay(uchar i)
{
uchar j;
for(;i>0;i--)
{
for(j=29;j;j--)
_nop_();
_nop_();
}
}
//延時(shí)函數(shù),產(chǎn)生PWM波
void PWMout(uchar q)
{
PWM = 1;
delay(q);
PWM = 0;
delay(100-q);
}
void timer1() interrupt 3
{
TH1 = 0x3c; //(65536-50000)=15536= ox3c oxb0 即定時(shí)50ms
TL1 = 0xb0; //(65536-50000)=15536= ox3c oxb0 即定時(shí)50ms
if(--timcount==0)
{
timcount = 4;
TR0 = 0;
SpeedDet = TL0;
TL0 = 0;
TR0 = 1;
e1 = SpeedSet-SpeedDet;
duk = (KP*(e1-e2)+KI*e1+KD*(e1-2*e2+e3))/10; //誤差的微分:(e1-2*e2+e3)=((e1-e2)-(e2-e3))/1
uk = uk+duk;
if(uk>100)
uk=100;
else if(uk<-100)
uk = -100;
if(uk<0)
{
PWMH = -uk;
Dir = 0;
}
else
{
PWMH =uk;
Dir = 1;
}
e3 = e2;
e2 = e1;
}
}
void main(void)
{
TMOD = 0x16; //T1工作于定時(shí)模式的方式一16位定時(shí)器;T0工作于計(jì)數(shù)模式的方式2八位自動(dòng)重裝模式。
TH0 = 0;//裝載計(jì)數(shù)初始值為0
TL0 = 0;//裝載計(jì)數(shù)初始值為0
TH1 = 0x3c;//(65536-50000)=15536= ox3c oxb0 即定時(shí)50ms
TL1 = 0xb0;//(65536-50000)=15536= ox3c oxb0 即定時(shí)50ms
timcount = 4; //
PWMH = 0; //PWM高電平時(shí)間初始為0
SpeedSet = 80;//設(shè)定期望值速度80
SpeedDet = 0; //速度偏移量
e1 = 0;//當(dāng)前誤差
e2 = 0;//上一次誤差
e3 = 0;//上上次誤差
KP =10; //比例系數(shù)
KI = 1;//積分系數(shù)
KD = 2;//微分系數(shù)
TR0 = 1; //打開定時(shí)器T0
TR1 = 1;//打開計(jì)數(shù)器T1
ET1 = 1;//允許中斷T1
ET0 = 1;//允許中斷T0
EA = 1;//打開總中斷
while(1)
{
PWMout(PWMH); //電機(jī)運(yùn)行速度
}
}