
一.前言 利用STM32的TIM3的通道1、通道2,输出俩路PWM信号,驱动MG996R舵机。 涉及到:TIM定时器基本原理,TIM定时中断、TIM输出PWM信号、MG996R舵机驱动原理 二.MG996R舵机简介 MG996R舵机单线驱动,是一款360°舵机,180°舵机与360°舵机的区别就是:180°舵机可以直接控制舵机旋转的角度,但舵机只能够旋转180°;360°舵机无法直接控制其旋转角度,只能控制其转动方向和速度。 舵机的驱动信号由周期为20ms的脉冲来控制: 当高电平持续时间为0.5~1.5ms时,舵机正转,时间越小转动越快 当高电平持续时间为1.5~2.5ms时,舵机反转,时间越大转动越快 当高电平持续时间为1.5ms或者其他时间时,舵机停止转动 ![]() 三.TIM定时器简介 STM32F1系列中,有8个定时器,分别为基本定时器(2个)、通用定时器(2个)、高级定时器(2个),如图: ![]() 这些定时器的相同点: 1.计数器的分辨率都是16位; 2.预分频系数都是16位(2的16次方),1-65535; 3.都可以产生DMA请求; 各自的特点: 1.基本定时器只可以向上计数,而通用定时器和高级定时器既可以向上计数也可以向下计数; 2.基本定时器没有输入捕获、输出比较功能; 3.高级定时器支持互补输出; 一般输出PWM信号只用通用定时器即可。 四.通用定时器TIMx 1.TIMx主要功能 通用TIMx定时器(TIM2、TIM3、TIM4和TIM5)功能主要包括如下:16位向上、向下、向上/向下自动装载计数器 16位可编程(可以实时修改)预分频器,分频系数为1~65535四种独立通道功能: 1.输入捕获 2.输出比较 3.PWM生成 4.单脉冲输出 使用外部信号控制定时器和定时器互连的同步电路 可以由如下事件触发中断或者DMA: 1.更新,即计数器溢出,或者计数器初始化 2.特定的触发事件,比如:计数器启动、停止、初始化等等 3.输入捕获 4.输出比较 支持针对定位的增量(正交)编码器和霍尔传感电路 触发输入作为外部时钟或者按周期的电流管理 看起来功能很多,实际做项目的时候都是一条龙服务,就是一套流水线操作就完成了TIMx的全部功能配置。 2.TIMx框图 TIMx的框图如下: ![]() 按照我个人的理解和实践中积累的经验,可以将框图从逻辑上分为四部分: 橙色:时基部分,负责选择时钟源 蓝色:计数部分,负责根据预分频后的时钟进行计数、自动装载工作 绿色:输入捕获部分 紫色:输出比较部分 ![]() 3.计数单元 可编程通用定时器的主要部分是一个16位计数器和其相关的自动装载寄存器,前面也说了,计数器可以向上、向下、双向计数。既然要计数,那就必须要知道计数的多少和每一次计数的时间。计数器的时钟由预分频器对时钟源分频得到。 时基单元包括: 计数器寄存器(TIMx_CNT) 预分频器寄存器(TIMx_PSC) 自动装载寄存器(TIMx_ARR) 计数器寄存器中存储的是当前计数的值,自动装载寄存器中存储的是目标计数值,当计数器溢出后,会重新装填目标计数值,而预分频器寄存器中的是对时钟的分频系数。 4.时钟选择 计数器的时钟可以由如下时钟源提供: 内部时钟(CK_INT) 外部时钟模式1:外部输入引脚(TIx) 外部时钟模式2:外部触发输入(ETR) 内部触发输入(ITRx):使用一个定时器作为另一个定时器的预分频器 我们主要使用内部时钟CK_INT,CK_INT是从APB1倍频来的,当APB1的时钟分频数为1时(36MHz),TIMx的时钟就是APB1的2倍,即72MHz。 5.输出比较PWM 有专门的三个寄存器来控制PWM: 捕获/比较模式寄存器(TIMx_CCMR1/2) 捕获/比较使能寄存器(TIMx_CCER) 捕获/比较寄存器(TIMx_CCR1~4) 五.TIM3输出双路PWM信号代码详解 1.TIMx初始化结构体详解 输出PWM用到的TIMx初始化结构体有: 1.时基初始化结构体TIM_TimeBaseInitTypeDef 2.输出比较初始化结构体TIM_OCInitTypeDef 1.时基结构体TIM_TimeBaseInitTypeDef 用于定时器基本参数的设置,使用void TIM_TimeBaseInit(TIM_TypeDef* TIMx, TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct)函数进行初始化:
TIM_Prescaler:预分频器设置,只有经过预分频器后的时钟才是CK_CNT,计数器时钟频率 (fCK_CNT) 等于fCK_PSC / (PSC[15:0] + 1),可实现 1 至 65536 分频。 TIM_CounterMode:定时器计数模式,可设置向上计数、向下计数和中心对齐计数三种模式。 TIM_Period:设置的是自动重装寄存器ARR的值,ARR为要装载到影子寄存器的值,可设置 1 至 65536 。 TIM_ClockDivision:时钟分频,设置定时器时钟 CK_INT 频率与死区发生器以及数字滤波器采样时钟频率分频比。可以选择 1、 2、 4 分频。 TIM_RepetitionCounter:重复计数器,只有八位,只存在与高级定时器。 一般来讲,我们只需要设置
这三个成员就可以实现定时器的基本参数设置。 2.输出比较初始化结构体TIM_OCInitTypeDef 使用输出比较模式时就需要配置此结构体,使用void TIM_OCxInit(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct)函数进行初始化:
TIM_OCMode:比较输出模式选择,总共有八种,常用的为 PWM1/PWM2。它设定 CCMRx 寄存器 OCxM[2:0]位的值。 TIM_OutputState:比较输出使能,决定最终的输出比较信号 OCx 是否通过外部引脚输 出。它设定 TIMx_CCER 寄存器 CCxE/CCxNE 位的值。 TIM_OutputNState:比较互补输出使能,决定 OCx 的互补信号 OCxN 是否通过外部引脚 输出。它设定 CCER 寄存器 CCxNE 位的值。 TIM_Pulse:比较输出脉冲宽度,实际设定比较寄存器 CCR 的值,决定脉冲宽度。可 设置范围为 0 至 65535。 TIM_OCPolarity:比较输出极性,可选 OCx 为高电平有效或低电平有效。它决定着定 时器通道有效电平。它设定 CCER 寄存器的 CCxP 位的值。 TIM_OCNPolarity:比较互补输出极性,可选 OCxN 为高电平有效或低电平有效。它 设定 TIMx_CCER 寄存器的 CCxNP 位的值。 TIM_OCIdleState:空闲状态时通道输出电平设置,可选输出 1 或输出 0,即在空闲状 态(BDTR_MOE 位为 0)时,经过死区时间后定时器通道输出高电平或低电平。它设定 CR2 寄存器的 OISx 位的值。 TIM_OCNIdleState:空闲状态时互补通道输出电平设置,可选输出 1 或输出 0,即在 空闲状态(BDTR_MOE 位为 0)时,经过死区时间后定时器互补通道输出高电平或低电 平,设定值必须与 TIM_OCIdleState 相反。它设定是 CR2 寄存器的 OISxN 位的值。 当要输出PWM信号时只需要配置如下成员即可:
PWM的模式: PWM1:向上计数时CNT<CCR 时为有效电平,向下计数时CNT>CCR 时为有效电平 PWM2:向上计数时CNT<CCR 时为无效电平,向下计数时CNT>CCR 时为无效电平 输出极性决定了有效电平是高电平还是低电平。 2.TIM3输出俩路PWM初始化代码
传入函数的参数uint16_t arr,uint16_t psc确定了PWM信号的周期,使用void TIM_SetCompare2(TIM_TypeDef* TIMx, uint16_t Compare2);函数改变ccr,从而改变PWM信号的占空比。 3.主函数
可以控制俩个舵机的转动,因为是360°舵机,所以我采用控制舵机转动的速度和转动的时间来控制转动的角度, ———————————————— 版权声明:Aspirant-GQ 如有侵权请联系删除 |
STM32 GUI LTDC 最大像素时钟评估方法
【2025·STM32峰会】GUI解决方案实训分享1-对LVGL咖啡机例程的牛刀小试以及问题排查
OpenBLT移植到STM32F405开发板
为什么要先开启STM32外设时钟?
【STM32MP157】从ST官方例程中分析RPMsg-TTY/SDB核间通信的使用方法
【经验分享】STM32实例-RTC实时时钟实验④-获取RTC时间函数与中断服务函数
STM32 以太网 MAC Loopback 的实现
STM32功能安全设计包,助力产品功能安全认证
基于STM32启动过程startup_xxxx.s文件经验分享
HRTIM 指南