多语言展示
当前在线:1789今日阅读:84今日分享:32

DSPf28335 直流电机测速、PID调速以及串口显示

基于DSPf28335的QEP测速程序、增量式PID调速、16进制串口显示详细代码
方法/步骤
1

头文件、宏定义 //########################################################################### #include 'DSP28x_Project.h'     // Device Headerfile and Examples Include File#include 'Example_posspeed.h'   // Example specific Include file#include #include  Uint16       *ExRamStart = (Uint16 *)0x100000; #define   LED1  GpioDataRegs.GPBDAT.bit.GPIO54 #define   LED2  GpioDataRegs.GPBDAT.bit.GPIO55 #define   LED3  GpioDataRegs.GPBDAT.bit.GPIO56 #define   LED4  GpioDataRegs.GPBDAT.bit.GPIO57 int V;//声明 float N; int M;void EPwmSetup();interrupt void prdTick(void); POSSPEED qep_posspeed=POSSPEED_DEFAULTS;//默认值Uint16 Interrupt_Count = 0; void scib_echoback_init(void);void scib_fifo_init(void);void scib_xmit(int a);void scib_msg(char *msg);

2

增量式PID函数 struct _pid{    float setspeed;    float actualspeed;    float err;    float err_last;    float err_last2;    float kp,ki,kd;              }pid;  void pid_init(){    pid.setspeed=0;    pid.actualspeed=0;    pid.err=0.0;    pid.err_last=0.0;    pid.err_last2=0.0;    pid.kp=0.5;    pid.ki=0.3;    pid.kd=0.15;         }  void pid_realize()//增量式    {    pid.setspeed=150;    pid.actualspeed=V;    pid.err=pid.setspeed-pid.actualspeed;    float incrementspeed=pid.kp*(pid.err-pid.err_last)+pid.ki*pid.err+pid.kd*(pid.err-2*pid.err_last+pid.err_last2);//增量速度    pid.err_last2=pid.err_last;    pid.err_last=pid.err;    N=N-(incrementspeed/200);//占空比系数(占空比=SP*N)    if(N>0.5)     N=0.5;    else if (N<0)     N=0;    else     N=N;    }          //没有考虑死区,没有设定上下限

3

GPIO配置函数void configtestled(void){   EALLOW;   GpioCtrlRegs.GPBMUX2.bit.GPIO54 = 0; // GPIO6复用为GPIO功能   GpioCtrlRegs.GPBDIR.bit.GPIO54 = 1;   // GPIO6设置为输出   GpioCtrlRegs.GPBMUX2.bit.GPIO55 = 0; //   GpioCtrlRegs.GPBDIR.bit.GPIO55 = 1;    GpioCtrlRegs.GPBMUX2.bit.GPIO56 = 0; // GPIO6复用为GPIO功能   GpioCtrlRegs.GPBDIR.bit.GPIO56 = 1;   // GPIO6设置为输出   GpioCtrlRegs.GPBMUX2.bit.GPIO57 = 0; //   GpioCtrlRegs.GPBDIR.bit.GPIO57 = 1;    EDIS;}

4

主函数void main(void){// char *msg;   N=1.0;   V=0;// Uint16 ReceivedChar;// Step 1. Initialize System Control:// PLL, WatchDog, enable Peripheral Clocks// This example function is found in the DSP2833x_SysCtrl.c file.   InitSysCtrl();// Step 2. Initalize GPIO:// This example function is found in the DSP2833x_Gpio.c file and// illustrates how to set the GPIO to it's default state.// InitGpio();  // Skipped for this example    InitEQep1Gpio();   InitEPwm2Gpio();   InitEPwm4Gpio();   InitScibGpio();    EALLOW;   GpioCtrlRegs.GPADIR.bit.GPIO4 = 1;    // GPIO4 as output simulates Index signal   GpioDataRegs.GPACLEAR.bit.GPIO4 = 1;  // Normally low   EDIS;// Step 3. Clear all interrupts and initialize PIE vector table:// Disable CPU interrupts   DINT; // Initialize the PIE control registers to their default state.// The default state is all PIE interrupts disabled and flags// are cleared.// This function is found in the DSP2833x_PieCtrl.c file.   InitPieCtrl(); // Disable CPU interrupts and clear all CPU interrupt flags:   IER = 0x0000;   IFR = 0x0000; // Initialize the PIE vector table with pointers to the shell Interrupt// Service Routines (ISR).// This will populate the entire table, even if the interrupt// is not used in this example.  This is useful for debug purposes.// The shell ISR routines are found in DSP2833x_DefaultIsr.c.// This function is found in DSP2833x_PieVect.c.   InitPieVectTable();  // Interrupts that are used in this example are re-mapped to// ISR functions found within this file.   EALLOW;  // This is needed to write to EALLOW protected registers   PieVectTable.EPWM1_INT= &prdTick;//确定中断服务程序的入口地址   EDIS;    // This is needed to disable write to EALLOW protected registers   pid_init();   EPwmSetup();  // This function exists in Example_EPwmSetup.c// Step 5. User specific code, enable interrupts:// Enable CPU INT1 which is connected to CPU-Timer 0:   IER |= M_INT3; // Enable TINT0 in the PIE: Group 3 interrupt 1   PieCtrlRegs.PIEIER3.bit.INTx1 = 1;//使能第三组中断的第一个小中断 // Enable global Interrupts and higher priority real-time debug events:   EINT;   // Enable Global interrupt INTM   ERTM;   // Enable Global realtime interrupt DBGM    //LoopCount=0;   //ErrorCount=0;   scib_fifo_init();    // Initialize the SCI FIFO   scib_echoback_init();  // Initalize SCI for echoback //   msg='\r\n\n\nStart the velocity measurement!\n\0';//   scib_msg(msg);    configtestled(); //         LED1=1; //      DELAY_US(50000); //      LED2=0; //      DELAY_US(50000000); //      LED1=0; //      DELAY_US(50000); //     LED2=1; //     DELAY_US(5000000); //     LED1=0; //     LED2=0; //     DELAY_US(50000);                LED3=1;                DELAY_US(50000);                LED4=0;                DELAY_US(50000); //                 LED3=0; //             DELAY_US(50000); //             LED4=1; //             DELAY_US(50000000); //             LED3=0; //             LED4=0;   qep_posspeed.init(&qep_posspeed);   while (1)    {       //int32 i=0;      // while(i<320000)      // {         pid_realize();      //PID调节         M=7500*N;         EPwm2Regs.CMPA.half.CMPA=M;   //占空比更新         EQep1Regs.QFLG.bit.UTO==1;    //高速测量中断产生         qep_posspeed.calc(&qep_posspeed);      //   i++;      // }         scib_xmit(V);                      //串口显示     } }

5

测速中断函数  interrupt void prdTick(void)                  // EPWM1 Interrupts once every 4 QCLK counts (one period){  Uint16 i;   // Position and Speed measurement   qep_posspeed.calc(&qep_posspeed);    // Control loop code for position control & Speed contol   Interrupt_Count++;   if (Interrupt_Count==2500)                 // Every 1000 interrupts(4000 QCLK counts or 1 rev.)   {       EALLOW;       GpioDataRegs.GPASET.bit.GPIO4 = 1;     // Pulse Index signal  (1 pulse/rev.)       for (i=0; i<700; i++){       }       GpioDataRegs.GPACLEAR.bit.GPIO4 = 1;       Interrupt_Count = 0;                   // Reset count       EDIS;   }    // Acknowledge this interrupt to receive more interrupts from group 1   PieCtrlRegs.PIEACK.all = PIEACK_GROUP3;   EPwm1Regs.ETCLR.bit.INT=1;  }

6

串口发送函数、引脚配置函数void scib_echoback_init(){    // Note: Clocks were turned on to the SCIA peripheral    // in the InitSysCtrl() function     ScibRegs.SCICCR.all =0x0007;   // 1 stop bit,  No loopback                                   // No parity,8 char bits,                                   // async mode, idle-line protocol    ScibRegs.SCICTL1.all =0x0003;  // enable TX, RX, internal SCICLK,                                   // Disable RX ERR, SLEEP, TXWAKE    ScibRegs.SCICTL2.all =0x0003;    ScibRegs.SCICTL2.bit.TXINTENA = 1;    ScibRegs.SCICTL2.bit.RXBKINTENA =1;     ScibRegs.SCIHBAUD    =0x0001;  // 9600 baud @LSPCLK = 37.5MHz.    ScibRegs.SCILBAUD    =0x00E7;     ScibRegs.SCICTL1.all =0x0023;  // Relinquish SCI from Reset} // Transmit a character from the SCIvoid scib_xmit(int a){    while (ScibRegs.SCICTL2.bit.TXRDY == 0) {}    ScibRegs.SCITXBUF=a; } void scib_msg(char * msg){    int i;    i = 0;    while(msg[i] != '\0')    {        scib_xmit(msg[i]);        i++;    }} // Initalize the SCI FIFOvoid scib_fifo_init(){    ScibRegs.SCIFFTX.all=0x8000; }void InitScibGpio(){    EALLOW;    GpioCtrlRegs.GPAPUD.bit.GPIO18 = 0;    // Enable pull-up for GPIO18 (SCITXDB)    GpioCtrlRegs.GPAPUD.bit.GPIO19 = 0;     // Enable pull-up for GPIO19 (SCIRXDB)    GpioCtrlRegs.GPAQSEL2.bit.GPIO18 = 3;    GpioCtrlRegs.GPAQSEL2.bit.GPIO19 = 3;  // Asynch input GPIO19 (SCIRXDB)    GpioCtrlRegs.GPAMUX2.bit.GPIO18 = 2;   // Configure GPIO18 for SCITXDB operation    GpioCtrlRegs.GPAMUX2.bit.GPIO19 = 2;   // Configure GPIO19 for SCIRXDB operation    EDIS;}

注意事项

要结合官方例程看,或结合书籍《手把手教你学DSP---基于TMS320F28335》

推荐信息