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

2025-10-27 22:20:10

1、头文件、宏定义

//###########################################################################

#include "DSP28x_Project.h"     // Device Headerfile and Examples Include File

#include "Example_posspeed.h"   // Example specific Include file

#include <stdio.h>

#include <math.h>

 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 SCI

void 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 FIFO

void 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;

}

声明:本网站引用、摘录或转载内容仅供网站访问者交流或参考,不代表本站立场,如存在版权或非法内容,请联系站长删除,联系邮箱:site.kefu@qq.com。
猜你喜欢