记录速度环实操及STM32基本定时器开发

  1. 在STM32F103C8T6上添加PID算法(速度环)的实操教程

首先明确驱动一个编码电机并测速所需要的定时器资源,需要三个定时器,分别用于编码器的编码模式,产生PWM,产生定时器中断去获取编码器的脉冲数。
明确思路:每隔相同时间,进入一次中断服务函数读取编码器的值,所以在中断服务函数里读取编码器的值赋值给encoder_counter,中断服务函数建议放在main.c文件里,因为encoder_counter变量要用于pid算法,pid算法函数会写在while循环里重复执行输出pwm值,而while循环在main.c文件里。
各方面配置正常的话,电机会正常运行,只是转速没有达到我们的设定值,此时就是要利用vofa上位机和串口输出去调整p、i的值了(电机控制一般用p、i即可)。

  1. 实操过程出现的问题及解决方法——定时器基础知识不扎实

  1. 遇到的问题及解决方法、应该注意的问题(OLED显示是需要时间的,不建议放在中断服务函数里)

我在编码器测速并显示在0.96寸OLED显示屏的工程代码基础上加上PID算法后(pid算法函数在while循环中执行),我的电机出现了快速转停转停的现象,反思了很久,还是觉得问题出在了产生PWM的定时器参数和产生定时器中断的定时器参数不对,导致产生的高低电平不合适。
请教了实验室里调试成功的同学后,发现问题确实是出在了这里。
开始出问题时,cubmx定时器的配置如下(定时器1用于产生定时器中断、定时器3用于编码器模式、定时器4用于产生PWM驱动电机(不用勾选中断)):
定时器1的定时中断时间为720*10000/72*10^6=1s,定时器4的定时时间为1*7200/72*10^6=10^-4s=10ms。定时器4的参数配置还好,通过10ms的细分,累加以后可以正常产生合适的PWM信号,可是定时器中断的时间太长了,读取编码器的间隔太长了,1s读取一次速度,导致电机出现连续出现转停的现象;同样,也要注意产生PWM信号的定时器的参数的配置,PWM定时周期时间一般10ms,实测结果较合适。
修改后cubmx定时器的配置如下(定时器1用于产生定时器中断、定时器3用于编码器模式、定时器4用于产生PWM驱动电机(不用勾选中断)):
修改后,定时器1的定时中断时间为720*1000/72*10^6=0.1s,定时器4的定时时间为72*1000/72*10^6=10^-3s=1ms。电机运行正常。
所以就是出在定时器参数配置的问题。下面补充STM32定时器开发基础知识。
另外还要注意OLED显示函数是有延时的,所以它不适合放在定时器中断服务函数里面。另外一定要开启定时器中断的重装载模式。
  1. STM32定时器开发基础知识

(1)STM32常见定时器资源
  • 系统滴答定时器SysTick:这是一个集成在Cortex M3内核当中的定时器,它并不属于芯片厂商的外设,也就是说使用ARM内核的不同厂商,都拥有基本结构相同的系统定时器。主要目的是给实时操作系统RTOS提供时钟节拍做时间基准。

  • 看门狗定时器WatchDog:防止程序跑飞,监视程序的执行情况。

  • 实时时钟RTC:用来计算日期。

  • 基本定时器:TIM6、TIM7:基本功能,对时钟进行计数,定时等功能。

  • 通用定时器:TIM2、TIM3、TIM4、TIM5:在基本定时器的基础上,实现输出比较、输入捕获、PWM生成、单脉冲模式输出等功能。这类定时器最具代表性,使用也最广泛

  • 高级定时器:TIM1、TIM8:性能更高,功能更强大。

(2)STM32通用定时器的重要知识点
  • STM32的通用定时器是一个通过可编程预分频器(Prescaler)驱动的16位自动重装主计数(Counter Period)构成。可以对内部时钟或触发源以及外部时钟或触发源进行计数。

  • 通用定时器的基本工作原理:首先,定时器时钟信号送入16位可编程预分配器(Prescaler),该预分配器系数为0~65535之间的任意数值。预分配器溢出后,会向16位的主计数器(Counter Period)发出一个脉冲信号。预分频器,本质上是一个加法计数器,预分频系数实际上就是加计数的溢出值。

  • 定时器发生中断时间的计算方法:定时时间=(Prescaler+1 ) X(Counter Period+1)X1/定时器时钟频率。例如:时钟信号1KHz,Prescaler为9,Counter Period为999,定时时间?

频率1kHz即1/1000=1ms,每一个时钟脉冲为1ms,预分频器要接收10个时钟脉冲(即10ms来一个脉冲给主计数器,主计数器对脉冲计数)才会生成一个脉冲给主计数器,主计数器计数值加到1000才会产生定时器中断。定时时间=10ms*1000=10s

(3)定时器的应用:产生PWM,生成定时器中断等等。
  1. 调参,P、I两个参量控制电机,使速度环达到良好效果

  1. cubmx配置串口

  1. hal库中重定义printf函数,将采集到的编码器的脉冲值输出到上位机VOFA中,显示曲线。

#include "stdio.h"
/*串口重定向*/
 #ifdef __GNUC__
     #define PUTCHAR_PROTOTYPE int _io_putchar(int ch)
 #else
     #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
 #endif /* __GNUC__*/
 
 /******************************************************************
     *@brief  Retargets the C library printf  function to the USART.
     *@param  None
     *@retval None
 ******************************************************************/
 PUTCHAR_PROTOTYPE
 {
     HAL_UART_Transmit(&huart1, (uint8_t *)&ch,1,0xFFFF);
     return ch;
 }
  1. 通过在代码中调整P、I的值使实际值不断趋近于目标值。

可以将目标值和实际值都打印到上位机上,这样方便对比自己调参的效果。

速度环是增量式pid,这里控制电机,增量式pid只用到了p和i,建议先调i再调p;
让曲线最后能达到快准稳的效果。
VOFA上位机仅仅只是将串口发送的数据显示到电脑上,调参还需实际到工程代码中调。

猜你喜欢

转载自blog.csdn.net/weixin_62261692/article/details/129599114