大神来看看我写的这个直流有刷电机双闭环控制代码对不对

2019-03-24 09:13发布

本帖最后由 张锋 于 2016-7-4 09:11 编辑
  1. #include "DSP28x_Project.h"
  2. #include "IQmathLib.h"                                //IQmath头文件
  3. #include "pid_reg3.h"                                  //PID运算头文件
  4. #include "Example_posspeed.h"                //速度检测头文件

  5. /*函数声明*/
  6. void InitPwm1(void);
  7. __interrupt void Epwm1Int_isr(void);
  8. __interrupt void CPU_Timer0_isr();
  9. void Adc_Config(void);

  10. #define EPWM1_DB 180                                        //死区时间 2us,180/90M

  11. PIDREG3 pid_i = PIDREG3_DEFAULTS;                //电流环PI
  12. PIDREG3 pid_spd = PIDREG3_DEFAULTS;                //速度环PI

  13. POSSPEED qep_posspeed=POSSPEED_DEFAULTS;        //测速模块,初始化一些参数

  14. _iq spd = _IQ(0.0);

  15. _iq Ifb = _IQ(0.0);                                                //电流反馈值
  16. _iq Iref;                                                                //电流给定值

  17. _iq Spdfb = _IQ(0.0);                                        //速度反馈值
  18. _iq Spdref;                                                                //速度给定值
  19. _iq Duty = _IQ(0.0);                                        //占空比

  20. Uint32 IsrCount = 0;                                        //中断计数

  21. int main(void)
  22. {
  23.         InitSysCtrl();                                                //初始化系统系统时钟,包括:PLL(90M), 看门狗时钟, 外设时钟的控制;
  24.         DINT;                                                                //关总中断
  25.         InitEPwm1Gpio();                                        //初始化PWM-Gpio
  26.         InitEQep1Gpio();                                        //初始化EQEP-Gpio
  27.         InitCpuTimers();                                        //初始化Timer,用于速度环

  28.         InitPieCtrl();                                                //初始化PIE模块
  29.         IER = 0X0000;                                                //关闭CPU中断
  30.         IFR = 0X0000;                                                //清除全部的CPU中断标志
  31.         InitPieVectTable();                                        //初始化中断向量表
  32. //中断入口选择
  33.         EALLOW;
  34.         PieVectTable.EPWM1_INT = &Epwm1Int_isr;
  35.         PieVectTable.TINT0 = &CPU_Timer0_isr;
  36.         EDIS;
  37. //关闭PWM时钟
  38.         EALLOW;
  39.         SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 0;
  40.         EDIS;

  41.         InitPwm1();                                                        //初始化Pwm1,电流环20k,50us
  42.         InitAdc();                                                        //初始化ADC,20k,由PWM触发
  43.         ConfigCpuTimer(&CpuTimer0, 90, 2000);    //速度环 2ms
  44.         StopCpuTimer0();                                        //关闭Timer0
  45. //开启PWM时钟
  46.         EALLOW;
  47.         SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1;
  48.         EDIS;

  49.         IER |= M_INT1;
  50.         IER |= M_INT3;

  51.         PieCtrlRegs.PIEIER1.bit.INTx7 = 1;                //使能PIE级TIMER0中断
  52.         PieCtrlRegs.PIEIER3.bit.INTx1 = 1;                //使能PIE级PWM1中断

  53.         Adc_Config();                                                        //配置ADC

  54.         qep_posspeed.init(&qep_posspeed);                //Eqep初始化

  55. //PID参数设定
  56. //初始化电流环PI参数
  57.         pid_i.Kp = _IQ(0.3);
  58.         pid_i.Ki = _IQ(0.0001);
  59.         pid_i.Kd = _IQ(0.0);
  60.         pid_i.Kc = _IQ(0);
  61.         pid_i.OutMax = _IQ(0.499);
  62.         pid_i.OutMin = _IQ(-0.499);
  63.         Iref = _IQ(0.2);
  64. //初始化速度环PI参数
  65.         pid_spd.Kp = _IQ(0.1);
  66.         pid_spd.Ki = _IQ(0.001);
  67.         pid_spd.Kd = _IQ(0.0);
  68.         pid_spd.Kc = _IQ(0);
  69.         pid_spd.OutMax = _IQ(0.99);
  70.         pid_spd.OutMin = _IQ(-0.99);
  71.         Spdref = _IQ(0.5);

  72.         StartCpuTimer0();                                //开启Timer0

  73.         EINT;                                                        //使能总中断
  74.         ERTM;                                                        //使能全局实时中断
  75.         while (1)
  76.         {
  77.                 ;
  78.         }
  79. }
  80. //================================================
  81. //函 数 名:                CPU_Timer0_isr
  82. //函数功能说明:                速度环的运算
  83. //调用函数:                        qep_posspeed.calc();   M法测速
  84. //                                        PID_MACRO();        PID运算
  85. //访问的表:                        无
  86. //输入参数:                         无
  87. //返 回 值:                        无
  88. //涉及的全局变量:        CpuTimer0.InterruptCount  TImer0中断计数
  89. //                                        Iref 速度环输出传送给电流环给定,范围-1~+1,Q24
  90. //修改记录:
  91. //================================================
  92. __interrupt void CPU_Timer0_isr()
  93. {
  94.         CpuTimer0.InterruptCount++;                                        //中断计数

  95. /*速度环*/
  96.         qep_posspeed.calc(&qep_posspeed);//M法测速,最终速度为  qep_posspeed.SpeedRpm_fr globalQ

  97.         spd = qep_posspeed.Speed_fr;    //速度,globalQ,标幺值

  98.         pid_spd.Fdb = spd;                                //速度反馈
  99.         pid_spd.Ref = Spdref;                        //速度给定
  100.         PID_MACRO(pid_spd);

  101.         Iref = pid_spd.Out;

  102.         PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;                        //PIE中断回应
  103. }
  104. //================================================
  105. //函 数 名:                Epwm1Int_isr
  106. //函数功能说明:                电流环运算
  107. //调用函数:                        PID_MACRO();  PID运算
  108. //访问的表:                        无
  109. //输入参数:                         无
  110. //返 回 值:                        无
  111. //涉及的全局变量:        IsrCount  PWM1中断计数
  112. //                                        Ifb        电流采样值,范围-1~1,Q24
  113. //修改记录:
  114. //================================================
  115. __interrupt void Epwm1Int_isr()
  116. {
  117.         Uint32 temp;
  118.         IsrCount++;                                                //中断计数

  119. /*电流环*/
  120.         temp = AdcResult.ADCRESULT1;        //电流值
  121. //        Ifb = ((AdcResult.ADCRESULT1<<12) - _IQ(0.5))<<1;                //电流采样值为 (-0.5~0.5)*2 变为 -1~+1
  122. //        Ifb = _IQdiv(_IQmpy(_IQ(3.3),_IQdiv(temp,4096)),_IQ(2));//
  123.         Ifb = ((temp<<12) - _IQ(0.5))<<1;                //电流采样值为 (-0.5~0.5)*2 变为 -1~+1

  124.         pid_i.Fdb = Ifb;
  125.         pid_i.Ref = Iref;
  126.         PID_MACRO(pid_i);
  127.         Duty = pid_i.Out;

  128.         EPwm1Regs.CMPA.half.CMPA = (4500*(Duty+_IQ(0.5)))>>24;

  129.         EPwm1Regs.ETCLR.bit.INT = 1;                                //清除中断标志
  130.         PieCtrlRegs.PIEACK.all = PIEACK_GROUP3;                //PIE中断回应
  131. }

  132. //================================================
  133. //函 数 名:                InitPwm1
  134. //函数功能说明:                PWM1模块初始化,设定周期为TBPRD=4500,对应20kHz,
  135. //                                        以及死区设置,死区时间EPWM1_DB=2us
  136. //                                        PWM1中断设置,中断频率=PWM频率
  137. //调用函数:                        无
  138. //访问的表:                        无
  139. //输入参数:                         无
  140. //返 回 值:                        无
  141. //涉及的全局变量:        无
  142. //修改记录:
  143. //================================================
  144. void InitPwm1(void)
  145. {
  146.         EPwm1Regs.TBPRD = 4500;                        //周期,频率20k = 90000/4500
  147.         EPwm1Regs.TBPHS.half.TBPHS = 0x0000;
  148.         EPwm1Regs.TBCTR = 0x0000;

  149.         EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP; //增计数
  150.         EPwm1Regs.TBCTL.bit.PHSEN = TB_DISABLE;
  151.         EPwm1Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1;       //不分频,
  152.         EPwm1Regs.TBCTL.bit.CLKDIV = TB_DIV1;

  153.         EPwm1Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;
  154.         EPwm1Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
  155.         EPwm1Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;
  156.         EPwm1Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;

  157.         EPwm1Regs.CMPA.half.CMPA = 2250;                                //50%

  158.         //动作设置
  159.         EPwm1Regs.AQCTLA.bit.CAU = AQ_CLEAR;                                //复位
  160.         EPwm1Regs.AQCTLA.bit.ZRO = AQ_SET;                                        //置位

  161.         EPwm1Regs.AQCTLB.bit.CAD = AQ_SET;                                //置位
  162.         EPwm1Regs.AQCTLB.bit.CAU = AQ_CLEAR;                        //复位

  163.         //死区设置
  164.         EPwm1Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE;
  165.         EPwm1Regs.DBCTL.bit.POLSEL = DB_ACTV_HIC;
  166.         EPwm1Regs.DBCTL.bit.IN_MODE = DBA_ALL;
  167.         EPwm1Regs.DBRED = EPWM1_DB;
  168.         EPwm1Regs.DBFED = EPWM1_DB;

  169.         //Pwm中断设置
  170.         EPwm1Regs.ETSEL.bit.INTSEL = ET_CTR_ZERO;     //计数器 = 0 时触发中断
  171.         EPwm1Regs.ETSEL.bit.INTEN = 1;                //使能中断
  172.         EPwm1Regs.ETPS.bit.INTPRD = ET_1ST;           //每次都触发中断
  173. }
  174. //================================================
  175. //函 数 名:                Adc_Config
  176. //函数功能说明:                ADC模块设置
  177. //                                        ADCSOC0   对应通道   ADCINA0
  178. //                                        ADCSOC1   对应通道   ADCINA0
  179. //                                PWM1触发ADC,即ADC采样频率20k
  180. //调用函数:                        无
  181. //访问的表:                        无
  182. //输入参数:                         无
  183. //返 回 值:                        无
  184. //涉及的全局变量:        无
  185. //修改记录:
  186. //================================================
  187. //pwm触发ADC
  188. void Adc_Config(void)
  189. {
  190.         EALLOW;

  191.         AdcRegs.ADCSOC0CTL.bit.CHSEL         = 0;        //ADCSOC0   对应通道   ADCINA0
  192.         AdcRegs.ADCSOC1CTL.bit.CHSEL         = 0;        //ADCSOC1   对应通道   ADCINA0

  193.         AdcRegs.ADCSOC0CTL.bit.TRIGSEL         = 5;        //PWM1触发SOC0
  194.         AdcRegs.ADCSOC1CTL.bit.TRIGSEL         = 5;        //PWM1触发SOC1

  195.         AdcRegs.ADCSOC0CTL.bit.ACQPS         = 6;        //采样保持7个周期
  196.         AdcRegs.ADCSOC1CTL.bit.ACQPS         = 6;        //采样保持7个周期

  197.         EDIS;

  198.         // 触发adc采样
  199.     /* Set up Event Trigger with CNT_zero enable for Time-base of EPWM1 */
  200.     EPwm1Regs.ETSEL.bit.SOCAEN = 1;     /* Enable SOCA */
  201.     EPwm1Regs.ETSEL.bit.SOCASEL = 1;    /* Enable CNT_zero event for SOCA */
  202.     EPwm1Regs.ETPS.bit.SOCAPRD = 1;     /* Generate SOCA on the 1st event */
  203.         EPwm1Regs.ETCLR.bit.SOCA = 1;       /* Clear SOCA flag */
  204. }

复制代码
请大家看看这个程序对不对 此帖出自小平头技术问答
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
1条回答
bkn1860
1楼-- · 2019-03-24 13:08
 精彩回答 2  元偷偷看……

一周热门 更多>

相关问题

    相关文章