80 likes | 318 Views
馬達控制 (QEI). 上次的圖 ( 使用 A/D). 這次的圖 ( 用 QEI 大約是這樣 ). // 馬達正反轉 1 圈 //#include <stdio.h> // 呼叫 stdio( 標準輸入輸出 ) 指令巨集 //#define FCY 2000000 #include <p30F4011.h> // 呼叫 p30F3011(IC) 指令巨集 #include <qei.h> long icount=0,v2_new=0,v2_old=0,pi=0,j=0;
E N D
//馬達正反轉1圈 • //#include <stdio.h> //呼叫stdio(標準輸入輸出)指令巨集 • //#define FCY 2000000 • #include <p30F4011.h> //呼叫p30F3011(IC)指令巨集 • #include <qei.h> • long icount=0,v2_new=0,v2_old=0,pi=0,j=0; • double v1=1600.0,v3=0.0,e_new=0.0,e_old=0.0,d_new=0.0,d_old=0.0,kp=20.0,ki=0.0; • int pot[4]={0x0100,0x0200,1,-1}; • int dd; • unsigned int s=0; • _FWDT(WDT_OFF); • void PWM_Initial(void) • { • PTPER = 125; //PWM = (20MHz / 16/ 125) = 10 KHz • IEC2bits.PWMIE = 0; //Disable PWM Interrupt • PTCON = 0xA008; // 0b 1010 0000 0000 0000 • PWMCON1 = 0x0777; // 0b 0000 0111 0111 0111 • PDC1=0; • OVDCON= pot[pi]; //設定輸出腳位 • IPC9bits.PWMIP = 6; • }
void Qei_Initial(void) • { • QEICON=0x0700; //0000 0111 0000 0000 x4與MAX比較 • DFLTCON=0x0; //0000 0000 0000 0000 • POSCNT=0; • MAXCNT=0xffff; • QEICONbits.CNTERR=1; • } • void Init_Timer1( void ) • { • T1CON = 0; • IFS0bits.T1IF = 0; • IPC0bits.T1IP = 7; • IEC0bits.T1IE = 1; • PR1 = 5000; // 20MHz/8/5000=500 Hz 中斷為2ms • T1CONbits.TCS = 0; • T1CONbits.TCKPS=1; //TCKPS<1:0>: Timer Input Clock Prescale Select bits • //11 = 1:256 prescale value • //10 = 1:64 prescale value • //01 = 1:8 prescale value • //00 = 1:1 prescale value • T1CONbits.TON=1; • }
void _ISR _T1Interrupt(void) • { • v2_old=v2_new; • v2_new=POSCNT; • if(((v2_old-v2_new)<30000)&&((v2_new-v2_old)<30000)) • v2_new=v2_new; • else if((v2_old-v2_new)>30000) • v2_new=65536+v2_new; • else if(((v2_new-v2_old)>30000)&&(v2_old>=65536)) • v2_new=v2_new; • else • v2_new=v2_new-65536; • e_new=v1-v2_new*1.0; • d_new=kp*e_new; • if(d_new>0.0) • { • pi=0; • if(d_new>220.0) • d_new=220.0; • } • else if(d_new<0.0) • { • if(d_new<-220.0) • d_new=-220.0; • pi=1; • } • dd=d_new*pot[pi+2]; • PDC1=dd; OVDCON= pot[pi]; • s++; • IFS0bits.T1IF = 0; • }
int main(void) • { • ADPCFG=0xffff; • TRISB = 0x01f2; • TRISF = 0x0000; • PORTF=0x0002; • PWM_Initial(); • Qei_Initial(); • Init_Timer1(); • while(1) • { • if (s>4000) • { • v1=1600.0; • s=0; • PORTF=0x2; • } • else if (s>2000) • { • v1=0.0; • PORTF=0x1; • } • } • }
練習 • 1.自行定義馬達圈數,並且要正反轉!