stm32控制的智能小车源代码核心部分分析,因为程序大量使用了stm32定时器的功能,所以先介绍一下定时的作用。当然,这些软硬件都是完全开放的。你可以深入细节的学习研究。
定时器最基本的功能就是定时处理事情;我们上层应用通常使用cpu循环定时处理事情,这样会浪费cpu资源,使得cpu处于停止状态或者无效状态,也就是空转;有定时器控制的话,就可以通过定时器技术循环或者终端cpu执行事件。打个比方,定时发送USART数据、定时采集AD数据、定时检测IO口电位、还可以通过IO口输出波形等。定时器可以实现非常丰富的功能。定时器是一个很强大的外设,不同行业使用的方式不同,知识面很广。主板是stm32,嵌入式c程序控制智能小车动起来
下面我们来介绍小车的程序实现主要功能模块以及模块之间的关系,最后梳理一下程序流程:
1:本车的功能模块介绍:
TIM1:主要启动小车的舵机,也就是转向轮子的驱动,通过TIM1定时器触发io引脚输出PWM波形,控制舵机轮子的转向
TIM2:云台控制,和TIM1的原理一样,控制云台上下左右的转向
TIM3:控制电机驱动,也就是小车的动力驱动,向前向后动起来,原理也是和TIM1一样,输出PWM波形,通过占空比控制小车的转速;
TIM4和TIM8一样:是接收阿克曼电机的反馈编码值,通过PID比例微积分反馈闭环,更加准确的控制电机;
TIM5:定时5ms循环控制逻辑,是各个控制逻辑的入口,比如:调节CCD、读取左右编码器的值并转换成速度、给上位机示波器、普通模式或者蓝牙模式或者ps2手柄模式、巡航模式控制、雷达模式、电磁模式
uart1:一键下载和ros上位机控制接口
uart3:蓝牙控制
uart5:雷达控制
2:上面这些模块之间的关系
智能小车程序框架核心功能关系框图
3:每个核心模块的程序核心实现流程
3个uart的初始化和终端调用流程都一样:MX_UART5_Init();MX_USART1_UART_Init();MX_USART3_UART_Init();初始化波特率、停止位等等。如果串口有数据收到,就会触发回调HAL_UART_RxCpltCallback进行逻辑处理;HAL_UART_RxCpltCallback是在使用STM32 HAL库时,用于处理UART接收数据的中断回调函数。当使用HAL_UART_Receive_IT函数启动UART接收数据中断后,每当接收到一个字符时,该回调函数HAL_UART_RxCpltCallback就会被调用一次。
几个定时器主要有3个不同用法,一个是基本定时器的用法,一个是pwm脉冲波的用法,一个是获取编码器的用法
1):普通定时器在TIM5中:
控制功能放在TIM5定时器中,设置的每5ms调用一次,通过基本定时器HAL_TIM_Base_Init功能进行初始化,psc设置,50分频,Period arr设置的7200,正好就是5ms, 通过基本定时器HAL_TIM_Base_Start_IT启动,触发TIM5_IRQHandler这个终端,然后调用HAL_TIM_IRQHandler,最后调用stm32 定时器提供的基本用户回调函数:HAL_TIM_PeriodElapsedCallback;
这里顺便介绍一下基本定时器的用法和原理:
- 信号频率由 TIMx_ARR 寄存器值决定,也叫做重载值为ARR。
- 占空比则由 TIMx_CCRx 寄存器值决定,比较值为CRRx。
- PSC其实就是缩小频率的功能,一般stm32的时钟频率72MHz
通过以上公式就可以计算出周期或者频率,就是项目中TIM5通过这种办法定时5ms执行控制逻辑,HAL_TIM_Base_*
2):pwm脉冲波在TIM1、TIM2、TIM3中:
定时器脉冲PWM输出函数流程功能表
如果让速度或者舵机按照不同的脉冲控制,就需要修改比较值,实时修改比较值:__HAL__TIM__SET__COMPARE(x,x,x)
因为现在实现的是PA8,用的TIM1定时器,所以对应的PA11也是TIM1,所以也可以使用。
有的引脚可以重映射,gpio重映射写法是:
1:首先先使能重映射复用时钟: __HAL__RCC__AFIO__CLK__ENABLE()
2:然后查找手册"通用和复用功能I/O(GPIO/AFIO)里面的复用重映射和调试I/O配置寄存器"找到配置设置:
配置设置: __HAL__AFIO__REMAP__TIM3__PARTIAL() 这个需要寻找宏或者调用。。。稍微需要一些经验,刚开始可以照猫画虎吧
在tim.c中的HAL_TIM_MspPostInit函数中初始化TIM1和TIM3的gpio引脚,TIM1 PA8作为舵机使用,TIM3的PA6、PA7、PB0、PB1 作为电机驱动PWM使用
程序中改变舵机,控制舵机转向角度大小的比较变化值函数:SERVO_TIM_SetCompareX_FUN(&htim1,TIM_CHANNEL_1,Servo_PWM);
//控制触发电机pwm
#define PWMA_IN1 TIM3->CCR1
#define PWMA_IN2 TIM3->CCR2
#define PWMB_IN1 TIM3->CCR3
#define PWMB_IN2 TIM3->CCR4
3):电机霍尔编码器返回的pwm波形数值由下面定义:
TIM4、TIM8这两个处理返回波形的定时器,主要通过这个函数处理HAL_TIM_Encoder_MspInit
顺便了解一下PWM模式1和PWM模式2进行介绍:
时钟器中的PWM模式1:在向上计数时,一旦TIMx_CNT<TIMx_CCR1时通道1为有效电平,否则为无效电平;在向上计数时,一旦TIMx_CNT>TIMx_CCR1时通道1为无效电平(OC1REF=0),否则为有效电(OC1REF=1)。
时钟器中的PWM模式2:在向上计数时,一旦TIMx_CNT<TIMx_CCR1时通道1为无效电平,否则为有效电平;在向下计数时,一旦TIMx_CNT>TIMx_CCR1时通道1为有效电平,否则为无效电平。TIMx_CNT>TIMx_CCR1时通道1为有效电平,否则为无效电平。
最后提供一下ROS测试的字符串:
最后提供2个ROS串口测试数据:
异或校验(BCC校验)在线计算:7B00000000000000007B7D 和 7B010221B6000040802F7D