一.编码器测速
采用m法测速,四倍频计数
要能测速需要打开两个定时器,一个用于脉冲计数(encoder mode),一个用于产生10ms的中断,encoder mode只需要打开这个模式,然后设置两相边沿计数,最后程序中设置中断就可以了。
具体可以参考这位大神:【STM32】【HAL库】定时器编码器模式测速_hal库编码器测速-CSDN博客
然后另一个定时器用于每10ms产生中断,调整psr(72-1),arr(10000),打开中断,即可产生10ms(100hz)的中断,这样在中断回调函数里面就可以计算转速了
在main之前打开一些中断:
HAL_TIM_Encoder_Start(&htim2, TIM_CHANNEL_ALL); //开启编码器模式
HAL_TIM_Base_Start_IT(&htim2); //开启编码器的中断
HAL_TIM_Base_Start_IT(&htim3); //开启定时器的中断
可以在begin2和end2对中添加。
编写回调函数:
int32_t Speed = 0;
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
int16_t zj;
if (htim == &htim2) //编码器的中断忽略
{
}
else if (htim == &htim2) //如果是计时器10ms的中断就计算转速
{
zj = __HAL_TIM_GetCounter(&htim1);//获取计数值
__HAL_TIM_SetCounter(&htim1, 0);//清空计数值
Speed = (float)zj*6000 / (4*22*30) ;//计算转速
printf("%d\r\n", Speed);//输出转速
}
}
补充:转速计算中,电机减速后的输出轴转一圈的脉冲数为4(代表四倍频)*11(代表分辨率,即线数)*30(代表减速比)。
即脉冲数除以转一圈的脉冲数再乘以6000(转换成转/分,即RPM)
(但是好像出的转速是错误的,大佬有了解的可以告诉我,感激不尽)
二.PID初探
基本PID可以分为位置式PID和增量式PID,对于电机的控制推荐使用增量式PID。
这里以增量式PID为例
增量式PID控制器代码:
int Incremental_PI (int Target)
{
static float Bias,Pwm,Last_bias;
Bias=Target-Speed; //计算偏差
Pwm+=Velocity_KP*(Bias-Last_bias)+Velocity_KI*Bias; //增量式PI控制器
Last_bias=Bias; //保存上一次偏差
return Pwm; //增量输出
}
但是由于Pwm可能会出现负数的情况,因此粗暴的进行修改
int Incremental_PI (int Target)
{
static float Bias,Pwm,Last_bias;
Bias=Target-Speed; //计算偏差
Pwm+=Velocity_KP*(Bias-Last_bias)+Velocity_KI*Bias; //增量式PI控制器
Last_bias=Bias; //保存上一次偏差
if(Pwm<0)
{Pwm=0;
}
set_pwm_param(htim4,TIM_CHANNEL_1,2000,Pwm);
return Pwm; //增量输出
}
未作深入探究,大佬轻喷