DSP28335实现PID闭环

Simulink下的模型及结果

给定参考是0.5,经过PID,然后执行机构,最后输出,Simulink的仿真结果如下:
KP=10;KI=5;KD=0.5KP=10;KI=5;KD=0.5
在这里插入图片描述

DSP实现

包括两块:定时器0中断,PID函数。主要就是在中断函数中实现PID。

采用增量式PID算法:
在这里插入图片描述

定时器0中断函数及PID初始化,运算

  1. void TIM0_Init(float Freq,float Period)  
    
  2. {
  3.  EALLOW;  
    
  4.  SysCtrlRegs.PCLKCR3.bit.CPUTIMER0ENCLK=1;  
    
  5.  EDIS;  
    
  6.  EALLOW;  
    
  7.  PieVectTable.TINT0=&TIM0_IRQn;  
    
  8.  EDIS;  
    
  9.  //指向定时器0的寄存器地址  
    
  10.     CpuTimer0.RegsAddr = &CpuTimer0Regs;  
    
  11.     //设置定时器0的周期寄存器值  
    
  12.     CpuTimer0Regs.PRD.all  = 0xFFFFFFFF;  
    
  13.     //设置定时器预定标计数器值为0  
    
  14.     CpuTimer0Regs.TPR.all  = 0;  
    
  15.     CpuTimer0Regs.TPRH.all = 0;  
    
  16.     //确保定时器0为停止状态  
    
  17.     CpuTimer0Regs.TCR.bit.TSS = 1;  
    
  18.     //重载使能  
    
  19.     CpuTimer0Regs.TCR.bit.TRB = 1;  
    
  20.     // Reset interrupt counters:  
    
  21.     CpuTimer0.InterruptCount = 0;  
    
  22.     ConfigCpuTimer(&CpuTimer0, Freq, Period);  
    
  23.     //开始定时器功能  
    
  24.         CpuTimer0Regs.TCR.bit.TSS=0;  
    
  25.         //开启CPU第一组中断并使能第一组中断的第7个小中断,即定时器0  
    
  26.         IER |= M_INT1;  
    
  27.         PieCtrlRegs.PIEIER1.bit.INTx7 = 1;  
    
  28.         //使能总中断  
    
  29.         EINT;  
    
  30.         ERTM;  
    
  31. }
  32. void PID_initial(void)
  33. {
  34. pidStr.KP=10;  
    
  35. pidStr.KI=5;  
    
  36. pidStr.KD=0.5;  
    
  37. }
  38. float PID_control(float adcvalue,float ref)
  39. {
  40. float Inck=0.0;  
    
  41. pidStr.Ek=ref-adcvalue;  
    
  42.    Inck = pidStr.KP*(pidStr.Ek - pidStr.Ek_1) + pidStr.KI*pidStr.Ek  
    
  43.     + pidStr.KD*(pidStr.Ek - 2*pidStr.Ek_1 + pidStr.Ek_2);  
    
  44.     pidStr.Ek_2 = pidStr.Ek_1;  
    
  45.     pidStr.Ek_1 = pidStr.Ek;  
    
  46.     pidStr.dacOut = pidStr.dacOut + Inck*1.000/60;  
    
  47.     if(pidStr.dacOut < 0.0000)  
    
  48.         pidStr.dacOut = 0.0000;  
    
  49.     if(pidStr.dacOut > 0.7)  
    
  50.         pidStr.dacOut = 0.7;  
    
  51.     return pidStr.dacOut;  
    
  52. }
  53. interrupt void TIM0_IRQn(void)
  54. {
  55. EALLOW;  
    
  56. LED2_TOGGLE;  
    
  57. PID_control(a,0.5);  
    
  58. DELAY_US(1);  
    
  59. a=1.5*pidStr.dacOut;  
    
  60. aa[ai]=a;  
    
  61. ai++;  
    
  62. PieCtrlRegs.PIEACK.bit.ACK1=1;  
    
  63. EDIS;  
    
  64. }

主函数:

  1. void main()  
    
  2. {
  3.  InitSysCtrl();  
    
  4.  p=0;  
    
  5.  a=0.0;  
    
  6.  ai=0;  
    
  7.  LED_Init();  
    
  8.  int i;  
    
  9.  for(i=0;i<500;i++)  
    
  10. {  
    
  11.     aa[i]=0;  
    
  12. }  
    
  13. InitPieCtrl();  
    
  14. IER = 0x0000;  
    
  15. IFR = 0x0000;  
    
  16. InitPieVectTable();  
    
  17. PID_initial();  
    
  18. TIM0_Init(150,1000);  
    
  19. while(1)  
    
  20. {  
    
  21.     p++;  
    
  22.     if((p%2)==0)  
    
  23.      {  
    
  24.         LED1_TOGGLE;  
    
  25.      }  
    
  26. }  
    
  27. }

全局变量的定义:

C文件:

  1. #include “canshu.h”
  2. PID_ValueStr pidStr;
  3. float32 a;
  4. float32 aa[500];
  5. Uint16 ai;

H文件

  1. extern float32 m[100];  
    
  2. extern float32 aa[500];
  3. extern float32 a;
  4. extern Uint16 ai;
  5. typedef struct PID_Value
  6. {
  7.  float KP;  
    
  8.  float KI;  
    
  9. float KD;  
    
  10. float Ek;  
    
  11. float Ek_1;  
    
  12. float Ek_2;  
    
  13. float dacOut;  
    
  14. }PID_ValueStr;
  15. extern PID_ValueStr pidStr;
    最终效果:
    在这里插入图片描述
    欢迎批评指正
  • 17
    点赞
  • 141
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值