SLAM智能小车DIY乐趣-小车控制stm32软件基础
####写在前面####
前面介绍了小车控制stm32硬件基础,本文就来介绍配套的小车控制stm32软件基础。关于stm32开发相关的基础知识这里就不多说了,有需要的小伙伴可以查阅相关资料进行学习,这里重点从小车控制项目入手,直接进行跟实际需求相关的开发。本文主要内容:
1) 电机控制
2) 编码器数据读取
3) 串口数据收发
4) 电机速度PID控制
5) 周期性控制
6) 小车控制软件整体框图
####正文####
1.电机控制
电机控制分为两个部分(电机转向控制、电机转速控制),这些都集成在了电机驱动芯片TB6612FNG里面,所以只需要用单片机的IO口产生控制转向的高低电平和控制转速的PWM波就能实现。初始化IO口作为输出脚,用于产生高低电平输出来控制转向,实例代码如下:
用通用定时器TIM4的通道CH1和CH2分别产生两路PWM输出用于两个电机的转速控制,定时器默认引脚分配如下:
初始化通用定时器TIM4的通道CH1和CH2为PWM输出,实例代码如下:
最后,将电机转向和速度控制的操作封装在一个函数中,便于其它地方调用,实例代码如下:
2.编码器数据读取
编码器对小车来说至关重要,一方面小车通过编码器的反馈进行PID闭环速度控制,另一方面小车通过编码器进行航迹推演得到里程计用于后续的定位与导航等高级算法中。这里用到的编码器是正交编码器,所以直接使用通用定时器的输入捕获中的编码器模式来读取编码器。采用通用定时器TIM2的通道CH1和CH2捕获encoder1的A相和B相脉冲,采用通用定时器TIM3的通道CH1和CH2捕获encoder2的A相和B相脉冲,先初始化TIM2作为编码器捕获,实例代码如下:
然后,将读取编码器计数值的操作封装在一个函数中,便于其它地方调用,实例代码如下:
最后编写计数溢出时的中断处理函数,实例代码如下:
同理可得TIM3捕获encoder2的代码实现,这里就不在赘述了。
3.串口数据收发
串口2负责接收上位机发送过来的控制指令,同时将编码器值返回给上位机;串口1负责接收上位机发送过来的PID设定值,同时将程序中的debug打印信息返回给上位机。一般在正常工作时,只需要串口2,如果需要进行调试可启用串口1。首先配置串口1,先对串口1的输出进行printf函数打印支持,实例代码如下:
然后初始化串口1,实例代码如下:
最后编写串口1接收中断处理函数,此函数主要进行对上位机发过来的数据进行协议解析,实例代码如下:
接下来,介绍串口2,初始化串口2,实例代码如下:
然后将串口2发送数据的操作封装到函数中,便于其它地方调用,实例代码如下:
最后编写串口2接收中断处理函数,此函数主要进行对上位机发过来的数据进行协议解析,实例代码如下:
4.电机速度PID控制
本文采用的是增量型PID算法,编程涉及到的数学表达式有3个,分别是
e(k) = target_value - current_value
delta_u(k) = Kp*[e(k)-e(k-1)] + Ki*e(k) + Kd*[e(k)-2*e(k-1)+e(k-2)]
u(k) = u(k-1) + delta_u(k)
将这3个数学表达式封装到函数中,便于其它地方调用,实例代码如下:
电机1与电机2采用同样的PID算法,所以电机2的PID算法代码实现就不赘述了。
5.周期性控制
通过上面的讲解,各个模块的驱动代码都准备就绪了,现在需要产生一个周期性的过程,在里面实现编码器计数值采样、PID控制等具体实现。这里采用定时器TIM1产生一个周期性的中断,在中断处理函数中实现各模块的具体操作,首先配置定时器TIM1,实例代码如下:
然后编写中断处理函数,实例代码如下:
6.小车控制软件整体框图
通过上面的讲解,对小车控制的stm32程序实现有了一定的了解,接下来就来做一个总结。先来看看main()函数实现:
结合上面TIM1中断处理函数,不难发现,整个stm32程序的执行过程:
在main()函数中初始化各个模块;
TIM1中断处理函数周期性的读取编码器值、反馈获取的编码值、PID控制;
剩下的就是串口1和串口2的通信交互。
具体流程图如下:
需要说明的是,在周期性循环体中,要首先读取编码器的值,来保证严格的等间隔采样。
原文地址:https://www.cnblogs.com/hiram-zhang/p/9634170.html