微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > 增量式PID的stm32实现,整定过程

增量式PID的stm32实现,整定过程

时间:11-28 来源:互联网 点击:

  1. RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5, ENABLE);//Open TIM4 clock
  2. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);//open gpioB clock
  3. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;//GPIO 1
  4. GPIO_InitStructure.GPIO_Mode =GPIO_Mode_IPU;//浮空输入 上拉输入
  5. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  6. GPIO_Init(GPIOA, &GPIO_InitStructure);
  7. TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值
  8. TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值
  9. TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim
  10. TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;//TIM向上计数模式
  11. TIM_TimeBaseInit(TIM5, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位
  12. NVIC_InitStructure.NVIC_IRQChannel = TIM5_IRQn;
  13. NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
  14. NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
  15. NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  16. NVIC_Init(&NVIC_InitStructure);
  17. TIM5_ICInitStructure.TIM_Channel = TIM_Channel_2;
  18. TIM5_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;
  19. TIM5_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
  20. TIM5_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_div1;
  21. TIM5_ICInitStructure.TIM_ICFilter = 0x3;//Filter:过滤
  22. TIM_PWMIConfig(TIM5, &TIM5_ICInitStructure);//PWM输入配置
  23. TIM_SelectInputTrigger(TIM5, TIM_TS_TI2FP2);//选择有效输入端
  24. TIM_SelectSlaveMode(TIM5, TIM_SlaveMode_Reset);//配置为主从复位模式
  25. TIM_SelectMasterSlaveMode(TIM5, TIM_MasterSlaveMode_Enable);//启动定时器的被动触发
  26. TIM_ITConfig(TIM5, TIM_IT_CC2|TIM_IT_Update, ENABLE);//中断配置
  27. TIM_ClearITPendingBit(TIM5, TIM_IT_CC2|TIM_IT_Update); //清除中断标志位
  28. TIM_Cmd(TIM5, ENABLE);
  29. }
  30. void TIM5_IRQHandler(void)
  31. {
  32. {
  33. if (TIM_GetITStatus(TIM5, TIM_IT_CC2) != RESET)//捕获1发生捕获事件
  34. {
  35. duty_TIM5=TIM_GetCapture1(TIM5); //采集占空比
  36. if(TIM_GetCapture2(TIM5)>600)period_TIM5=TIM_GetCapture2(TIM5);
  37. CollectFlag_TIM5 = 0;
  38. }
  39. }
  40. TIM_ClearITPendingBit(TIM5, TIM_IT_CC2|TIM_IT_Update); //清除中断标志位
  41. }

复制代码



PID部分:
准备部分:先定义PID结构体:

  1. typedef struct
  2. {
  3. int setpoint;//设定目标
  4. int sum_error;//误差累计
  5. float proportion ;//比例常数
  6. float integral ;//积分常数
  7. float derivative;//微分常数
  8. int last_error;//e[-1]
  9. int prev_error;//e[-2]
  10. }PIDtypedef;

复制代码


这里注意一下成员的数据类型,依据实际需要来定的。
在文件中定义几个关键变量:

  1. floatKp =0.32; //比例常数
  2. floatTi =0.09 ; //积分时间常数
  3. float Td =0.0028 ;//微分时间常数
  4. #define T0.02 //采样周期
  5. #define KiKp*(T/Ti)// Kp Ki Kd 三个主要参数
  6. #define KdKp*(Td/T)

复制代码


C语言好像用#define 什么什么对程序不太好,各位帮忙写个优化办法看看呢? 用const?

PID.H里面主要的几个函数:

  1. void PIDperiodinit(u16 arr,u16 psc);//PID 采样定时器设定
  2. void incPIDinit(void);//初始化,参数清零清零
  3. int incPIDcalc(PIDtypedef*PIDx,u16 nextpoint);//PID计算
  4. void PID_setpoint(PIDtypedef*PIDx,u16 setvalue);//设定 PID预期值
  5. void PID_set(float pp,float ii,float dd);//设定PIDkp ki kd三个参数
  6. void set_speed(float W1,float W2,float W3,float W4);//设定四个电机的目标转速

复制代码



PID处理过程:
岔开一下:这里我控制的是电机的转速w,实际上电机的反馈波形的频率f、电机转速w、控制信号PWM的占空比a三者是大致线性的正比的关系,这里强调这个的目的是
因为楼主在前期一直搞不懂我控制的转速怎么和TIM4输出的PWM的占空比联系起来,后来想清楚里面的联系之后通过公式把各个系数算出来了。

正题:控制流程是这样的,首先我设定我需要的车速(对应四个轮子的转速),然后PID就是开始响应了,它先采样电机转速,得到偏差值E,带入PID计算公式,得到调整量也就是最终更改了PWM的占空比,不断调节,直到转速在稳态的一个小范围上下浮动。
上面讲到的“得到调整量”就是增量PID的公式:

  1. int incPIDcalc(PIDtypedef *PIDx,u16 nextpoint)
  2. {

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top