直流电机PID转速闭环调速控制系统
在工業(yè)自動(dòng)控制系統(tǒng)和各種智能產(chǎn)品中常常會(huì)用用電動(dòng)機(jī)進(jìn)行驅(qū)動(dòng)、傳動(dòng)和控制,而現(xiàn)代智能控制系統(tǒng)中,對(duì)電機(jī)的控制要求越來(lái)越精確和迅速,對(duì)環(huán)境的適應(yīng)要求越來(lái)越高。隨著科技的發(fā)展,通過(guò)對(duì)電機(jī)的改造,出現(xiàn)了一些針對(duì)各種應(yīng)用要求的電機(jī),如伺服電機(jī)、步進(jìn)電機(jī)、開(kāi)關(guān)磁阻電機(jī)等非傳統(tǒng)電機(jī)。但是在一些對(duì)位置控制要求不高的電機(jī)控制系統(tǒng)如傳動(dòng)控制系統(tǒng)中,傳統(tǒng)電機(jī)如直流電機(jī)乃有很大的優(yōu)勢(shì),而要對(duì)其進(jìn)行精確而又迅速的控制,就需要復(fù)雜的控制系統(tǒng)。隨著微電子和計(jì)算機(jī)的發(fā)展,數(shù)字控制系統(tǒng)應(yīng)用越來(lái)越廣泛,數(shù)字控制系統(tǒng)有控制精確,硬件實(shí)現(xiàn)簡(jiǎn)單,受環(huán)境影響小,功能復(fù)雜,系統(tǒng)修改簡(jiǎn)單,有很好的人機(jī)交換界面等特點(diǎn)。
在電機(jī)控制系統(tǒng)開(kāi)發(fā)中,常常需要消耗各種硬件資源,系統(tǒng)構(gòu)建時(shí)間長(zhǎng),而在調(diào)試時(shí)很難對(duì)硬件系統(tǒng)進(jìn)行修改,從而延長(zhǎng)開(kāi)發(fā)周期。隨著計(jì)算機(jī)仿真技術(shù)的出現(xiàn)和發(fā)展,可用計(jì)算機(jī)對(duì)電機(jī)控制系統(tǒng)進(jìn)行仿真,從而減小系統(tǒng)開(kāi)發(fā)開(kāi)支和周期。計(jì)算機(jī)仿真可分為整體仿真
和實(shí)時(shí)仿真。整體仿真是對(duì)系統(tǒng)各個(gè)時(shí)間段對(duì)各個(gè)對(duì)象進(jìn)行計(jì)算和分析,從而對(duì)各個(gè)對(duì)象的變化情況有直觀的整體的了解,即能對(duì)系統(tǒng)進(jìn)行精確的預(yù)測(cè),如Matlab就是一個(gè)典型的實(shí)時(shí)仿真軟件。實(shí)時(shí)仿真是對(duì)時(shí)間點(diǎn)的動(dòng)態(tài)仿真,即隨著時(shí)間的推移它能動(dòng)態(tài)仿真出當(dāng)時(shí)系統(tǒng)的狀態(tài)。Proteus是一個(gè)實(shí)時(shí)仿真軟件,用來(lái)仿真各種嵌入式系統(tǒng)。它能對(duì)各種微控制器進(jìn)行仿真,本系統(tǒng)即用Proteus對(duì)直流電機(jī)控制系統(tǒng)進(jìn)行仿真。
在系統(tǒng)軟件開(kāi)發(fā)中開(kāi)發(fā)中可用操作系統(tǒng),也可不用操作系統(tǒng)。如用操作系統(tǒng),程序可實(shí)現(xiàn)模塊化,并能對(duì)系統(tǒng)資源進(jìn)行統(tǒng)籌管理,最主要的是可實(shí)現(xiàn)多任務(wù)運(yùn)行。如果需要多任務(wù)并行運(yùn)行,并且需要一定的時(shí)間間隔,某些任務(wù)對(duì)時(shí)間的要求不高時(shí),如不用操作系統(tǒng)則要占用定時(shí)器資源,并且對(duì)棧空間和硬件資源很難進(jìn)行管理,所以在這種情況下需要操作系統(tǒng)。本系統(tǒng)用操作系統(tǒng)uC/COS.
uC/COS是一個(gè)完整的、可移植、可固化、可剪裁的占先式實(shí)時(shí)多任務(wù)內(nèi)核.uC/COS
已經(jīng)有很多產(chǎn)品成功使用的案例且得到美國(guó)軍方的認(rèn)證,說(shuō)明了該系統(tǒng)的可靠性。uC/COS
源代碼公開(kāi),代碼短,源代碼大部分是使用ANSI C編寫(xiě)的,移植性和裁減性好,功能強(qiáng)大,
能可靠應(yīng)用于各種控制系統(tǒng)中。
系統(tǒng)構(gòu)成
硬件全圖
各子系統(tǒng)
1. 轉(zhuǎn)速控制輸入
如用按鍵輸入則需要復(fù)雜的軟件實(shí)現(xiàn),并且需要足夠的引腳資源,本系統(tǒng)用ADC0832采樣電位器上的電壓信號(hào)來(lái)實(shí)現(xiàn)轉(zhuǎn)速信號(hào)輸入。
2.LPC2106微控制器
LPC2106是Phlip公司推出的核心為ARM的控制器。LPC2106 包含一個(gè)支持仿真的ARM7TDMI-S CPU、與片內(nèi)存儲(chǔ)器控制器接口的ARM7 局部總線、與中斷控制器接口的AMBA 高性能總線(AHB)和連接片內(nèi)外設(shè)功能的VLSI 外設(shè)總線(VPB,ARMAMBA 總線的兼容超集)。片內(nèi)有64K 字節(jié)靜態(tài)RAM和128K的FLASH存儲(chǔ)器。可尋址4GB。
在本仿真中LPC2106沒(méi)加晶振電路,頻率在芯片屬性中設(shè)置。
3.液晶顯示
本系統(tǒng)采用Proteus仿真庫(kù)有的液晶顯示模塊AMPIRE128X64,為8192像素的單色LCD
屏幕分為兩半控制,控制引腳為CS1和CS2。數(shù)據(jù)通過(guò)移位寄存器輸入。
4.電機(jī)驅(qū)動(dòng)電路
本系統(tǒng)仿真的是最大輸入電壓為12伏的微型電機(jī),故用通用電機(jī)驅(qū)動(dòng)電路實(shí)現(xiàn)假設(shè)該電路輸入電阻為無(wú)窮大,輸出電阻為0。
5.仿真電機(jī)的51單片機(jī)
雖然Proteus有電機(jī)模塊,但其電機(jī)模塊沒(méi)有輸出轉(zhuǎn)速接口故用一單片機(jī)代替它,單片機(jī)用ADC0832采樣輸入的電壓,經(jīng)過(guò)處理即輸出和真實(shí)電機(jī)同步的轉(zhuǎn)速(需要大量的浮點(diǎn)運(yùn)算,可考慮用DSP)。通過(guò)兩個(gè)按鍵改變轉(zhuǎn)矩沒(méi)按一次增大或減小0.001,上面的是增大。
6.仿真結(jié)果
仿真1.8秒鐘后得下圖,可看到轉(zhuǎn)速逐漸增大然后穩(wěn)定下來(lái)。
增大轉(zhuǎn)矩后,可看到轉(zhuǎn)速下降后又恢復(fù)
/****************************************************************************** ** 實(shí)時(shí)微型直流電機(jī)PID轉(zhuǎn)速閉環(huán)調(diào)速控制系統(tǒng)程序(基于移植于LPC2106上的uc/cos實(shí)時(shí)操作系統(tǒng)) ** ******************************************************************************/ #include "config.h" #include "LCD.h"#define TASK_STK_SIZE 512 //各任務(wù)棧大小 #define IO_Init() \PINSEL0= 2; \IODIR|= 0x00007FB0; //P0.4\P0.5\P0.7-P1.4為輸出其他的為輸入 #define Umax 1000 //最大調(diào)節(jié)轉(zhuǎn)速 #define Kp 0.7 //比例放大系數(shù) #define Ts 0.03 //采樣周期 #define t0 4 //積分時(shí)間常數(shù) #define td 0.0005 //微分時(shí)間常數(shù) #define q0 Kp*(1+Ts*t0+td/Ts) #define q1 -Kp*(1+2*td/Ts) #define q2 Kp*td/Ts #define ADC_DO 0x00000040 //P0.6 #define ADC_CS 0x00000080 //P0.7 #define ADC_CLK 0x00000100 //P0.8 #define ADC_DI 0x00000200 //P0.9 OS_STK Main_TaskStk[TASK_STK_SIZE]; OS_STK Task1_TaskStk[TASK_STK_SIZE]; OS_STK Task2_TaskStk[TASK_STK_SIZE]; OS_STK Task3_TaskStk[TASK_STK_SIZE]; OS_STK Task4_TaskStk[TASK_STK_SIZE]; //各任務(wù)棧 OS_EVENT *Conbox; //控制信號(hào)郵箱 float n=0; // 輸入轉(zhuǎn)速 float nb=0; // 反饋轉(zhuǎn)速 void Main_Task(void *data); void Task1(void *p_arg); void Task2(void *p_arg); void Task3(void *p_arg); void Task4(void *p_arg); //函數(shù)聲明 void PWMInit(void) {PWMPR = 0x00; // 不分頻,計(jì)數(shù)頻率為FpclkPWMMCR = 0x02; // 設(shè)置PWMMR0匹配時(shí)復(fù)位PWMTCPWMMR0 = 2765; // 設(shè)置PWM周期PWMMR1 = 0; // 設(shè)置PWM占空比PWMLER = 0x03; // PWMMR0、PWMMR1鎖存PWMPCR = 0x0200; // 允許PWM1輸出,單邊PWMPWMTCR = 0x09; // 啟動(dòng)定時(shí)器,PWM使能PWMMR0 = 2765; // 設(shè)置PWM周期PWMMR1 = 0; // 設(shè)置PWM占空比PWMLER = 0x03; // PWMMR0、PWMMR1鎖存} /********************************************************************************************************* ** 函數(shù)名稱: main ** 功能描述: c語(yǔ)言的主函數(shù),由它啟動(dòng)多任務(wù)環(huán)境 ********************************************************************************************************/ int main (void) {OSInit();OSTaskCreate(Main_Task, (void*)0, &Main_TaskStk[TASK_STK_SIZE - 1], 0);OSStart();return 0; }/****************************************************************************** ** 函數(shù)名稱: Main_Task ** 功能描述: 初始化系統(tǒng)及建立任務(wù) ******************************************************************************/void Main_Task(void *p_arg) { p_arg = p_arg; // 避免編譯警告 TargetInit();IO_Init(); Conbox = OSMboxCreate((void*)0); LCD_Main(); OSTaskCreate(Task1, (void *)0, &Task1_TaskStk[TASK_STK_SIZE - 1], 2);OSTaskCreate(Task2, (void *)0, &Task2_TaskStk[TASK_STK_SIZE - 1], 3);OSTaskCreate(Task3, (void *)0, &Task3_TaskStk[TASK_STK_SIZE - 1], 1);OSTaskCreate(Task4, (void *)0, &Task4_TaskStk[TASK_STK_SIZE - 1], 5);OSTaskSuspend(0); }/****************************************************************************** ** 函數(shù)名稱: Task1_Task ** 功能描述: 實(shí)時(shí)任務(wù),負(fù)責(zé)采樣和處理數(shù)據(jù) ******************************************************************************/void Task1(void *p_arg) { float us; //上次輸出控制信號(hào)float es; //上次采樣誤差信號(hào)float es2 = 0; //上次的上次的采樣誤差信號(hào)uint32 nj; //采樣轉(zhuǎn)速信號(hào)float u; //此次輸出控制信號(hào)float e; //此次采樣誤差信號(hào)p_arg = p_arg;PWMInit(); //PWM初始化while(1){ nj=IOPIN>>16;nb=(float)nj/10; //采樣反饋轉(zhuǎn)速e=n-nb;u=us+q0*e+q1*es+q2*es2; //PID處理if(u>=Umax)u=Umax;es2=es;es=e;us=u;OSMboxPost(Conbox,(void*)&u); //發(fā)送處理后的信號(hào)OSTimeDlyHMSM(0,0,0,30);} } /****************************************************************************** ** 函數(shù)名稱: Task2_Task ** 功能描述: 根據(jù)控制信號(hào)輸出PWM波 ******************************************************************************/void Task2(void *p_arg){ uint8 err;float *nh;p_arg = p_arg;while(1){nh=(float*)OSMboxPend(Conbox,0,&err);if(*nh>=Umax-0.5){PWMMR0 = 2765;PWMMR1= 2764;PWMLER = 0x03;}else{PWMMR0 = 2765;PWMMR1=(uint32)(*nh/Umax*2765);PWMLER = 0x03;} }}void Delay(uint8 n) //延時(shí)函數(shù){uint8 i;for(i=1;i<=n;i++);} /****************************************************************************** ** 函數(shù)名稱: Task3_Task ** 功能描述: 定時(shí)采樣輸入的轉(zhuǎn)速要求(0832采樣) ******************************************************************************/void Task3(void *p_arg){ uint8 ch,i,flag=0;p_arg=p_arg;ch=0;IOCLR=ADC_CS;IOCLR=ADC_DI;//片選,DO為高阻態(tài)for(i=0;i<10;i++){;}IOCLR=ADC_CLK;Delay(4);IOSET=ADC_DI; IOSET=ADC_CLK; Delay(4); //第一個(gè)脈沖,起始位 IOCLR=ADC_CLK; Delay(4); IOSET=ADC_DI; IOSET=ADC_CLK;Delay(4); //第二個(gè)脈沖,DI=1表示雙通道單極性輸入IOCLR=ADC_CLK;Delay(4);IOSET=ADC_DI; IOSET=ADC_CLK;Delay(4); //第三個(gè)脈沖,DI=1表示選擇通道1(CH2)IOCLR=ADC_DI; //DI轉(zhuǎn)為高阻態(tài),DO脫離高阻態(tài)為輸出數(shù)據(jù)作準(zhǔn)備IOSET=ADC_CLK;Delay(4);IOCLR=ADC_CLK; Delay(4); //經(jīng)實(shí)驗(yàn),這里加一個(gè)脈沖AD便能正確讀出數(shù)據(jù)for (i=0; i<8; i++){ IOSET=ADC_CLK; Delay(4); IOCLR=ADC_CLK; Delay(4);if((IOPIN & ADC_DO)!=0)ch=(ch<<1)|1;//在每個(gè)脈沖的下降沿DO輸出一位數(shù)據(jù),最終ch為8位二進(jìn)制數(shù)elsech=(ch<<1)|0;}IOSET=ADC_CS;n=(float)ch*1000/256;if(flag==0){flag=1;OSTaskChangePrio(1,4);}OSTimeDlyHMSM(0,0,0,300);} /****************************************************************************** ** 函數(shù)名稱: Task4_Task ** 功能描述: 液晶顯示任務(wù) ******************************************************************************/void Task4(void *p_arg){#if OSCRITICAL_METHOD ==3OS_CPU_SR cpu_sr;#endifuint16 w,q,k;uint8 i;uint8 shu1[6],shu2[6];p_arg=p_arg;for(;;){shu1[4]=10;w=(uint16)(n*10);k=10000;for(i=0;i<4;i++){shu1[i]=(uint8)(w/k);w=w%k;k=k/10;}shu1[5]=(uint8)w;OS_ENTER_CRITICAL();LCD_num(80,2,shu1,6);shu2[4]=10;q=(uint16)(nb*10);k=10000;for(i=0;i<4;i++){shu2[i]=(uint8)(q/k);q=q%k;k=k/10;}shu2[5]=(uint8)q;LCD_num(80,4,shu2,6);OS_EXIT_CRITICAL();OSTimeDlyHMSM(0,0,0,100);}} /****************************************************************************** ** End Of File ******************************************************************************/ 2.自編的LCD驅(qū)動(dòng)程序(1)頭文件LCD.h /****************************************************************************** ** LCD驅(qū)動(dòng)頭文件LCD.h(基于LPC21**) ** 程序編寫(xiě)者: 吳斌 ** 編寫(xiě)日期: 2007年11月12日 ******************************************************************************/ #ifndef _LCD_H_ #define _LCD_H_ #include "config.h" #define SPI_CLK 0x00000010 //P0.4 #define SPI_DATA 0x00000020 //P0.5 #define RW 0x00000800 //RW #define RS 0x00000400 //RS #define CS1 0x00001000 //CS1 #define CS2 0x00002000 //CS2 #define E 0x00004000 //E #define Kai 0x3F #define Guang 0x3E #define Hang 0xC0 #define Ye 0xB8 #define Lie 0x40#define Setlie(a) \IOCLR = RW; \IOCLR = RS; \send(Lie+a);#define Setye(a) \IOCLR = RW; \IOCLR = RS; \send(Ye+a);#define Setweizi(a,b) \IOCLR = RW; \IOCLR = RS; \send(Lie+a); \send(Ye+b);#define Write(a) \IOCLR = RW; \IOSET = RS; \send(a); void send(uint8 dat); void LCD_disp(uint8 a,uint8 b,uint8 c,uint8 d,uint8 m,uint8 *shuju) ; void SetCS(uint8 a); void LCD(uint8 a,uint8 b,uint8 c,uint8 d, uint8 *shuju); void LCD_num(uint8 a,uint8 b,uint8 *shuju,uint8 n); void LCD_str(uint8 a,uint8 b,uint8 *strtab,uint8 n); void LCD_hanzi(uint8 a,uint8 b,uint8 *hanzitab,uint8 n); void LCD_xian(uint8 a,uint8 b,uint8 *strtab,uint8 n); void LCD_Main(void); #endif /****************************************************************************** ** End Of File ******************************************************************************/(2)LCD驅(qū)動(dòng)程序LCD.c /****************************************************************************** ** LCD驅(qū)動(dòng)程序(基于LPC21**) ** 程序編寫(xiě)者: 吳斌 ** 編寫(xiě)日期: 2007年11月12日 ******************************************************************************/ #include"LCD.h" void send(uint8 dat) //用移位寄存器輸出一字節(jié)數(shù)據(jù) { uint8 i;IOSET = E; // E = 1for(i=0; i<8; i++) // 發(fā)送8位數(shù)據(jù){ IOCLR = SPI_CLK; // SPI_CLK = 0if( (dat&0x80)!=0 ) IOSET = SPI_DATA;else IOCLR = SPI_DATA;dat <<= 1;IOSET = SPI_CLK; // SPI_CLK = 1}IOCLR = E; // E = 0 } void LCD_disp(uint8 a,uint8 b,uint8 c,uint8 d,uint8 m,uint8 *shuju) /*LCD顯示函數(shù),在第a列b頁(yè)輸出大小為c*d的圖像(只能選擇在左或右屏幕顯示) */ {uint8 i,j,f;SetCS(m);for(j=0;j<d;j++){Setweizi(a,j+b);for(i=0;i<c;i++){Write(*(shuju+i));for(f=0;f<0xFF;f++);}} }void SetCS(uint8 a){if(a==0){IOSET =CS2;IOCLR =CS1;}else{IOSET =CS1;IOCLR =CS2;}} void LCD(uint8 a,uint8 b,uint8 c,uint8 d, uint8 *shuju) /*LCD主顯示函數(shù),在第a列b頁(yè)輸出大小為c*d的圖像*/ {uint8 i,j,m,f,n;uint8 *p=shuju;if(a+c<=64){SetCS(0);for(j=0;j<d;j++){Setweizi(a,j+b);for(i=0;i<c;i++){Write(*p);p++;for(f=0;f<0xFF;f++);}}}else if(a<64&&(a+c)>64){m=64-a;n=c-m;for(j=0;j<d;j++){SetCS(0);Setweizi(a,j+b);for(i=0;i<m;i++){Write(*p);p++;for(f=0;f<0xFF;f++);}SetCS(1);Setweizi(0,j+b);for(i=0;i<n;i++){Write(*p);p++;for(f=0;f<0xFF;f++);}}}else{SetCS(1);for(j=0;j<d;j++){Setweizi(a-64,j+b);for(i=0;i<c;i++){Write(*p);p++;for(f=0;f<0xFF;f++);}}} } void LCD_num(uint8 a,uint8 b,uint8 *shuju,uint8 n) /*在第a列b頁(yè)顯示shuju數(shù)組的數(shù)字或小數(shù)點(diǎn)和空格*/ {uint8 numzimo[192]={0xFF,0x1F,0xEF,0xF7,0xF7,0xEF,0x1F,0xFF,0xFF,0xF0,0xEF,0xDF,0xDF, 0xEF,0xF0,0xFF, /*"0",0*/ 0xFF,0xEF,0xEF,0x07,0xFF,0xFF,0xFF,0xFF,0xFF,0xDF,0xDF,0xC0,0xDF,0xDF,0xFF,0xFF, /*"1",1*/ 0xFF,0x8F,0xF7,0xF7,0xF7,0x77,0x8F,0xFF,0xFF,0xCF,0xD7,0xDB,0xDD,0xDE,0xCF,0xFF, /*"2",2*/ 0xFF,0xCF,0xF7,0x77,0x77,0xB7,0xCF,0xFF,0xFF,0xE7,0xDF,0xDF,0xDF,0xEE,0xF1,0xFF, /*"3",3*/ 0xFF,0xFF,0x3F,0xDF,0xEF,0x07,0xFF,0xFF,0xFF,0xF8,0xFB,0xDB,0xDB,0xC0,0xDB,0xFF, /*"4",4*/ 0xFF,0x07,0xF7,0x77,0x77,0xF7,0xF7,0xFF,0xFF,0xE6,0xDE,0xDF,0xDF,0xEE,0xF1,0xFF, /*"5",5*/ 0xFF,0x1F,0xEF,0x77,0x77,0xE7,0xFF,0xFF,0xFF,0xF0,0xEE,0xDF,0xDF,0xEE,0xF1,0xFF, /*"6",6*/0xFF,0xC7,0xF7,0xF7,0x37,0xC7,0xF7,0xFF,0xFF,0xFF,0xFF,0xC0,0xFF,0xFF,0xFF,0xFF, /*"7",7*/ 0xFF,0x8F,0x77,0xF7,0xF7,0x77,0x8F,0xFF,0xFF,0xE3,0xDD,0xDE,0xDE,0xDD,0xE3,0xFF, /*"8",8*/ 0xFF,0x1F,0xEF,0xF7,0xF7,0xEF,0x1F,0xFF,0xFF,0xFF,0xCE,0xDD,0xDD,0xEE,0xF0,0xFF, /*"9",9*/ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xCF,0xCF,0xFF,0xFF,0xFF,0xFF,0xFF, /*".",10*/ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}; /*" ",11*/uint8 i,f;uint8 *p;for(i=0;i<n;i++){f=*(shuju++);p=numzimo+f*16;LCD(a,b,8,2,p);a=a+8;} } void LCD_str(uint8 a,uint8 b,uint8 *strtab,uint8 n) /*在第a列b頁(yè)顯示ASCII字符串(要點(diǎn)陣數(shù)據(jù))*/ {uint8 i;for(i=0;i<n;i++){LCD(a,b,8,2,strtab);a=a+8;strtab=strtab+16;} } void LCD_hanzi(uint8 a,uint8 b,uint8 *hanzitab,uint8 n) /*在第a列b頁(yè)顯示漢字串(要點(diǎn)陣數(shù)據(jù))*/ {uint8 i;for(i=0;i<n;i++){LCD(a,b,16,2,hanzitab);a=a+16;hanzitab=hanzitab+32;} } void LCD_xian(uint8 a,uint8 b,uint8 *strtab,uint8 n) //顯示ASCII字符串到頂時(shí)換行 {uint8 m;if(a+(n-1)*8<=120)LCD_str(a,b,strtab,n);else{if(a%8>0)m=a/8+1+n-16;elsem=a/8+n-16;LCD_str(a,b,strtab,n-m);LCD_str(0,b+2,strtab+16*(n-m),m);} } void LCD_Main(void) //本系統(tǒng)顯示主界面 {uint8 i; uint8 zifu[80]={0xF7,0x07,0xF7,0xFF,0xFF,0xF7,0x07,0xF7,0xFF,0xE0,0xDF,0xDF,0xDF,0xDF, 0xE0,0xFF,/*"U",0*/ 0xFF,0xFF,0xFF,0xFF,0x7F,0x9F,0xE7,0xFB,0xFF,0x9F,0xE7,0xF9,0xFE,0xFF,0xFF,0xFF, /*"/",1*/ 0xFF,0xFF,0xFF,0x7F,0x7F,0x7F,0xFF,0xFF,0xFF,0xF1,0xEE,0xDF,0xDF,0xDF,0xEE,0xFF, /*"c",2*/ 0xFF,0xFF,0x7F,0x7F,0x7F,0x7F,0xFF,0xFF,0xFF,0xE0,0xDF,0xDF,0xDF,0xDF,0xE0,0xFF, /*"o",3*/ 0xFF,0xFF,0x7F,0x7F,0x7F,0x7F,0x7F,0xFF,0xFF,0xCC,0xDB,0xDB,0xDB,0xDB,0xE6,0xFF};/*"s",4*/ uint8 inputn[160]= {0xBB,0x0B,0xB0,0x1B,0xBB,0x9B,0x6F,0x67,0x6B,0x6C,0xEB,0x67,0xF7,0x2F,0xEF,0xFF, 0xFB,0xFB,0xFB,0x00,0xFD,0xFD,0x00,0xB5,0x75,0x80,0xFF,0xC0,0x7F,0x00,0xFF,0xFF, /*"輸",0*/ 0xFF,0xFF,0xFF,0xFF,0xFE,0x7C,0x89,0xE7,0x9F,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xBF,0xDF,0xEF,0xF7,0xF9,0xFE,0xFF,0xFF,0xFF,0xFF,0xFC,0xFB,0xE7,0xCF,0xEF,0xFF, /*"入",1*/ 0x37,0x57,0x63,0x14,0x77,0x77,0x77,0xBF,0xB7,0x07,0xB0,0xB7,0xB7,0xB7,0xBF,0xFF, 0xF7,0xF7,0xFB,0x00,0xFB,0xFB,0xFF,0xFD,0xF4,0xED,0xDD,0x2D,0xF1,0xFD,0xFF,0xFF,/*"轉(zhuǎn)",2*/ 0xBF,0xBD,0x33,0xFF,0xFB,0x1B,0xDB,0xDB,0x0,0xDB,0xDB,0xDB,0x1B,0xFB,0xFF,0xFF, 0xBF,0xDF,0xE0,0xDF,0xB7,0xB6,0xBA,0xBC,0x80,0xBE,0xBC,0xBA,0xB2,0xBF,0xBF, 0xFF,/*"速",3*/0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xC9,0xC9,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}; /*":",4*/ uint8 outputn[160]={0xBB,0x0B,0xB0,0x1B,0xBB,0x9B,0x6F,0x67,0x6B,0x6C,0xEB,0x67,0xF7, 0x2F,0xEF,0xFF, 0xFB,0xFB,0xFB,0x00,0xFD,0xFD,0x00,0xB5,0x75,0x80,0xFF,0xC0,0x7F,0x00,0xFF,0xFF, /*"輸",0*/ 0xFF,0xFF,0x03,0xBF,0xBF,0xBF,0xBF,0x00,0xBF,0xBF,0xBF,0xBF,0xBF,0x03,0xFF,0xFF, 0xFF,0xFF,0x81,0xDF,0xDF,0xDF,0xDF,0xC0,0xDF,0xDF,0xDF,0xDF,0xDF,0x81,0xFF,0xFF, /*"出",1*/ 0x37,0x57,0x63,0x14,0x77,0x77,0x77,0xBF,0xB7,0x07,0xB0,0xB7,0xB7,0xB7,0xBF,0xFF, 0xF7,0xF7,0xFB,0x00,0xFB,0xFB,0xFF,0xFD,0xF4,0xED,0xDD,0x2D,0xF1,0xFD,0xFF,0xFF,/*"轉(zhuǎn)",2*/ 0xBF,0xBD,0x33,0xFF,0xFB,0x1B,0xDB,0xDB,0x0,0xDB,0xDB,0xDB,0x1B,0xFB,0xFF,0xFF, 0xBF,0xDF,0xE0,0xDF,0xB7,0xB6,0xBA,0xBC,0x80,0xBE,0xBC,0xBA,0xB2,0xBF,0xBF, 0xFF,/*"速",3*/ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xC9,0xC9,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}; /*":",4*/uint8 xinhao[16]={0xBF,0xBF,0x7F,0x0F,0x7F,0xBF,0xBF,0xFF,0xFD,0xFD,0xFE,0xF0,0xFE, 0xFD,0xFD,0xFF};/*"*",0*/LCD_str(44,0,zifu,5);LCD_hanzi(0,2,inputn,5);LCD_hanzi(0,4,outputn,5);for(i=0;i<16;i++){ LCD_str(i*8,6,xinhao,1);} } /****************************************************************************** ** End Of File ******************************************************************************/ 3. 用AT89S52單片機(jī)仿真直流電動(dòng)機(jī)程序 /****************************************************************************** ** 用AT89S52單片機(jī)仿真直流電動(dòng)機(jī)程序 ** 程序編寫(xiě)者: 吳斌 ** 編寫(xiě)日期: 2007年11月11日 ******************************************************************************/ #include <reg52.h>#include <INTRINS.H> #include <STDIO.H>#define La 0.1 //電樞電感#define CeQ 0.005#define CmQ 0.2 //#define Ja 0.0000018 //轉(zhuǎn)動(dòng)慣量#define Ra 10#define Ra-La 11.9sbit ADC_CS =P3^4;sbit ADC_CLK=P3^5;sbit ADC_DI =P3^6;unsigned int nc; float TL=0.1;float Te;float Tz=0;float Ts=0;float U=0.68;float Uz=0;float ia=0;float iaz=0;float ias=0;float ea=0;float eaz=0;float eas=0;float n=0;bit f=0;bit e=0;void Delay(unsigned char x){ unsigned char i; for(i=0;i<x;i++); }void INTf0(void)interrupt 0{TL=TL+0.001;}void INTf1(void)interrupt 2{TL=TL-0.001;} void timer0(void)interrupt 1{unsigned int i,ch;ch=0;ADC_CS=0;ADC_DI=0;for(i=0;i<10;i++){;}ADC_CLK=0;Delay(2);ADC_DI=1; ADC_CLK=1; Delay(2); ADC_CLK=0; Delay(2); ADC_DI=0; ADC_CLK=1;Delay(2);ADC_CLK=0;Delay(2);ADC_DI=0; ADC_CLK=1;Delay(2); ADC_DI=0; ADC_DI=1;ADC_CLK=1;Delay(2);ADC_CLK=0; Delay(2);for (i=0; i<8; i++){ ADC_CLK=1; Delay(2); ADC_CLK=0; Delay(2);ch=(ch<<1)|ADC_DI;}ADC_CS=1;U=0.1*(float)ch/256;Uz=Uz+U;ia=(Uz-iaz*Ra-eaz)/(Ra*0.01+La);Te=CmQ *ia;if(f==0);{f=1;ias=ia;Ts=Te-TL;}if(n<=0&&Te<TL&&e==0)n=0;else{e=1;Tz=Tz+(1.5*(Te-TL)-0.5*Ts)*0.01;Ts=Te-TL;n=Tz/Ja;}ea=CeQ *n;eaz=eaz+(1.5*ea-0.5*eas)*0.01-U*0.9727;eas=ea;Uz=Uz-U;iaz=iaz+(1.5*ia-0.5*ias)*0.01-U*0.0273/Ra;ias=ia;nc= (unsigned int)(n*10);P2=nc/256;P0=nc%256; printf("n=%f,i=%f\n",n,ia);TH0 =-(9216/256);TL0 =-(9216%256);}main(){int i;TCON = 0x0F;SCON = 0xDA; TMOD |= 0x20; TH1 = 0xFD; TR1 = 1; TI = 1; TH0 = -(9216/256);TL0 = -(9216%256);EX0=1;EX1=1;PX1=1;EA =1;ET0 =1;TR0= 1;while(1){;}} /****************************************************************************** ** End Of File ******************************************************************************/總結(jié)
以上是生活随笔為你收集整理的直流电机PID转速闭环调速控制系统的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: linux用户层通过spi读写cpld
- 下一篇: 3.7 广域网(ppp协议、HDLC协议