當前位置:編程學習大全網 - 編程語言 - 單片機pid算法控制步進電機的電路和程序

單片機pid算法控制步進電機的電路和程序

//P1.1(T0):計算它們的距離

//P0.4:Tx

//P0.5:Rx

# include & ltc 8051f 310 . h & gt;//SFR聲明

# include & ltstdio.h & gt//標準I/O定義文件

# include & ltmath.h & gt//數學庫文件

# include & ltIntrins.h & gt

# include & ltabsacc.h & gt

無符號int j,I;

char a = 0;

無符號整數t = 0;

//sbit led=p0^2;

//P0.0(PWM0):給定左輪速度。

sbit vls=p0^4;//P0.4(GPIO):給左輪方向。

sbit vlf=p0^6;//P0.6(T0):反饋左輪轉速。

sbit dlf=p1^0;//P1.0(GPIO):反饋左輪方向。

//P0.2(PWM0):給定合適的輪速。

sbit vrs=p0^5;//P0.5(GPIO):給出正確的車輪方向。

sbit vrf=p0^7;//P0.7(T0):反饋右輪轉速。

sbit drf=p1^1;//P1.1(GPIO):反饋右輪方向。

int ol//左輪給定值

int len

int len_1,len _ 2;

int lyn_1,Lyn _ 2;

int vl1,vl2//反饋左輪速度值(采樣周期內的方波數)

int lfz//操作後分配給PWM的值

int lyn,lynn

int lun=0,LUN _ 1 = 0;//偏差校正值是校正後的PWM輸出。

國際倫普,魯尼,隆德;//PID校正值

int或;//右輪給定值

int ren

int ren_1,ren _ 2;

int ryn_1,ryn _ 2;

int vr1,vr2//反饋右輪轉速值(采樣周期內的方波數)

int rfz//操作後分配給PWM的值

int ryn,rynn

int run=0,run _ 1 = 0;//偏差校正值是校正後的PWM輸出。

int runp,runi,rund//PID校正值

浮點kp = 2.0//比例系數1.8

float kd = 0.2//微分系數0.4

浮動lki//積分系數

void Pio _ init(void);

void sys _ init(void);

void t 01 _ init(void);

void time 3 _ INT(void);

void PID(void);

void中斷_ init(void);

void delay(無符號int x);

void PWM 1 _ 1(void);

無效總管(無效)

{

PCA0MD & amp= ~ 0x40//關閉

Pio _ init();//P11為測距輸入。

sys _ init();

t 01 _ init();

PWM 1 _ 1();

time 3 _ INT();

中斷_初始化();

vls = 1;VRS = 0;

while(1)

{

ol = 50

or = 50

延時(1000);

ol = 100;

or = 100;

延時(1000);

ol =-50;

or = 50

延時(1000);

}

}

無效PID(無效)

{

/* * * * * * * * * * * *左輪PID調節* * * * * * * * * * * * * *

if(dlf==1)

{

Lyn =(vl2 * 256+VL 1);//dlf為左輪反饋方向,0表示前進vl=TL0。

}

其他

{

Lyn =-(vl2 * 256+VL 1);//dlf=1表示向後,速度應該是負的。

}

len = ol-Lyn;//誤差=給定速度-反饋速度(采樣周期內的方波數)

if(ABS(len)& lt;8)//30

{

lki = 1.4;//確定//ki值1.4

}

其他

{

lki = 0.05//積分系數:如果|給定值-反饋值|過大。

}//可以不引入積分,或者引入壹個小0.05。

lunp = KP *(len-len _ 1);//比例校正

魯尼= lki * len//積分校正

Lund = KD *(len-2 * len _ 1+len _ 2);//差分校正

LUN = lunp+魯尼+Lund+LUN _ 1;//總校正

* * * * * * * * * * * *新舊數據更新* * * * * * * * * * * * * * * * * * * *

len _ 2 = len _ 1;

len _ 1 = len;//len:當前采樣周期內的速度偏差;Len_1:上壹個采樣周期的速度偏差。

LUN _ 1 = LUN;//lun:當前采樣周期獲得的PWM校正值;Lun_1:在上壹個采樣周期獲得的PWM校正值。

* * * * * * * * * * * *新舊數據更新* * * * * * * * * * * * * * * * * * * *

if(LUN & gt;255)

{

lun = 255//正速度

}

如果(lun & lt-255)

{

LUN =-255;//負速度

}

如果(lun & lt0)

{

vls = 1;

PCA 0 cph 0 =-LUN;

}

if(LUN & gt;=0)

{

vls = 0;

PCA0CPH0 = lun

}

/* * * * * * * * * * * *右輪PID調節* * * * * * * * * * * * * * * *

if(drf==0)

{

ryn =(vr2 * 256+VR 1);//drf為右輪反饋方向,0表示前進vl=TL0。

}

其他

{

ryn =-(vr2 * 256+VR 1);//dlf=1表示向後,速度應該是負的。

}

ren = or-ryn;//誤差=給定速度-反饋速度(采樣周期內的方波數)

if(ABS(ren)& lt;8)//30

{

lki = 1.4;//確定//ki值1.4

}

其他

{

lki = 0.05//積分系數:如果|給定值-反饋值|過大。

}//可以不引入積分,或者引入壹個小0.05。

runp = KP *(ren-ren _ 1);//比例校正

runi = lki * ren//積分校正

rund = KD *(ren-2 * ren _ 1+ren _ 2);//差分校正

run = runp+runi+rund+run _ 1;//總校正

* * * * * * * * * * * *新舊數據更新* * * * * * * * * * * * * * * * * * * *

ren _ 2 = ren _ 1;

ren _ 1 = ren;//len:當前采樣周期內的速度偏差;Len_1:上壹個采樣周期的速度偏差。

run _ 1 =運行;//lun:當前采樣周期獲得的PWM校正值;Lun_1:在上壹個采樣周期獲得的PWM校正值。

* * * * * * * * * * * *新舊數據更新* * * * * * * * * * * * * * * * * * * *

if(run & gt;255)

{

run = 255//正速度

}

if(運行& lt-255)

{

run =-255;//負速度

}

if(運行& lt0)

{

VRS = 1;

PCA 0 cph 1 =-run;

}

if(run & gt;=0)

{

VRS = 0;

PCA 0 cph 1 =運行;

}

//因為這裏的PCA0CPH0越大,對應的電機轉速越低,所以需要降低255。

}

void pio_init(void)

{

XBR0 = 0x00//0000 0001

xbr 1 = 0x 72;//當0111010時,T0T1可以弱拉起來連接腳踝P06、P07 CEX0、CEX1,連接腳踝P00、P01。

P0MDIN = 0xff//模擬(0);號碼(1)1111011。

P0MDOUT = 0xc3//開漏(0);推拉式(1)111 111

P0SKIP = 0x3c//0011 1100

p 1 mdin = 0x ff;//1111 1111

p 1m dout = 0x fc;//

p 1 skip = 0x 00;//1111 1111

}

void sys _ init(void)//12 MHz

{

OSCICL = 0x43

OSCICN = 0xc2

CLKSEL = 0x00

}

void PWM 1 _ 1(void)//PWM初始化

{

PCA0MD = 0x08//PCA時鐘除以12。

PCA0CPL0 = 200//左輪

PCA 0 CPM 0 = 0x 42;//將左輪設置為8位PWM輸出。

PCA0CPH0 = 200

PCA 0 CPL 1 = 200;//平衡校正

PCA 0 CPM 1 = 0x 42;//設置為8位PWM輸出。

PCA 0 cph 1 = 200;

PCA0CN = 0x40//允許PCA工作

}

void t01_init(void)

{

TCON = 0x 50;//計數器1,2允許

TMOD = 0x 55;//定時器1和2采用16位計數功能。

CKCON = 0x00

th 1 = 0x 00;//用來采集左輪的速度。

TL 1 = 0x 00;

TH0 = 0x00//用於采集右輪的速度。

TL0 = 0x00

}

void TIME3_INT(void)

{

TMR3CN = 0x00//定時器3自動過載16位。

CKCON & amp= ~ 0x40

TMR3RLL = 0xff

TMR3RLH = 0xd7

TMR3L = 0xff

TMR3H = 0xd7

TMR3CN | = 0x04

}

Voidt3 _ ISR()中斷14//定時器3中斷服務程序。

{

//led = ~ led;

EA = 0;

TCON & amp;= ~ 0x50//關閉計數器0,1

VL 1 = TL0;//取左輪速度值

vl2 = TH0

VR 1 = TL 1;//取正確的輪速值。

vr2 = th 1;

th 1 = 0x 00;

TL 1 = 0x 00;

TH0 = 0x00

TL0 = 0x00

PID();//PID處理

TMR3CN & amp= ~ 0x80//清除中斷標誌。

TCON | = 0x 50;//重新啟動計數器0,1。

EA = 1;

}

void中斷_初始化(void)

{ IE = 0x80

IP = 0x00

eie 1 | = 0x 80;

EIP 1 | = 0x 80;

}

Void delay(unsigned int m) //延遲程序

{

for(I = 0;我& lt2000;i++)

{

for(j = 0;j & ltm;j++){ _ nop _();_ nop _();}

}

}

  • 上一篇:learn是什麽意思啊了
  • 下一篇:J2ME相關資料
  • copyright 2024編程學習大全網