【STM32】定时器之PWM输出与舵机控制(CUBEMX+HAL库)

本文介绍了脉宽调制(PWM)基本概念,重点讲述了如何在CUBEMX中配置STM32定时器以生成PWM信号,控制舵机转动,并提供了舵机PWM参数设置和HAL库函数的使用示例。
摘要由CSDN通过智能技术生成

这里总结一下初次认识PWM的时候遇到的一些问题,也希望能帮大家解决一些在使用CUBEMX配置PWM输出的时候遇到的一些问题

PWM认识

PWM(Pulse Width Modulation)简称脉宽调制,是利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术,广泛应用在测量、通信、工控等方面。

占空比:可以简单理解为一个周期内脉宽时间与周期时间之比*100%,如20ms周期中,若脉宽为5ms,则占空比为25%。

通过PWM可以输出低于最大输出电压的电压值

对PWM有以上基础的认识我觉得就足够了

CUBEMX配置定时器输出PWM

PWM的输出主要用定时器完成,通过定时器的配置可以调控PWM的频率以及占空比,通过PWM占空比的设置就可以实现电机调速以及舵机转动等,当然PWM也可以用于控制LED灯的亮度等,下面以一个新手的视角讲解如何使用CUBEMX+HAL库控制舵机的转动

工程前期配置

一些基础的工程创建以及debug和时钟配置在这篇博文中有介绍,纯新手可以参考这篇博文完成一些前期的配置

【STM32】CUBEMX之串口:串口三种模式(轮询模式、中断模式、DMA模式)的配置与使用示例 + 串口重定向 + 使用HAL扩展函数实现不定长数据接收_cubemx stm32f1 dma 中断-CSDN博客

定时器的配置

打开PWM通道

找到timers->TIM1->channel1->PWM generation CH1

这里的只要目的是打开定时器1的PWM输出通道,而CH1N表示PWM互补波形输出,这里我们不需要

如果需要同时控制多个舵机,也可以打开channel2,3,4,可以看见,tim1可以同时输出四路PWM波(不算互补波形)

注意事项

以下有几点注意事项:

1、TIM1挂在APB2总线上,也就是说TIM1的基础频率与APB2相同,通过查看时钟树可以知道APB2频率为72MHz

2、一般舵机的PWM周期为20ms,且脉宽范围在500μs-2500μs之间,其中500μs时舵机旋转到最小角度,2500μs是转到最大角度

3、对于一些参数的介绍

Prescaler/PSC(预分频):大部分时候定时器不需要总线那么高的频率,预分频可以将APB总线上的频率降低,具体降低后频率大小为 总线频率/(PSC+1),如若PSC值为71,APB2总线频率为72MHz,则输入tim1的频率为72/(71+1) = 1MHz

counter mode(计数方式):字面意思,就是决定定时器的计数方式,有向上,向下,中心对齐计数,这里不必深究

Counter Period(计数周期):指定时器中的数值累积到多少后算完成一次计数,大小为该数值+1,如若配置为19999,则表示定时器接收到20000个脉冲后结束一次计数,并开始下一次的计数,可以理解为计数的上限

auto reload preload(自动重装载预加载):这个可了解可不了解,具体的可以看看其他博主更详细的讲解

Pulse:表示PWM脉宽长度,Pulse/Counter Period *100%就表示占空比的大小

了解如上注意事项和知识点,我们就可以开始配置用于舵机输出的PWM了

PWM频率、占空比的计算与配置

预分频值设置为71,则定时器频率为72/(71+1)=1MHz,1*10^-6s计数值+1

计数周期设置为19999,周期为(19999+1)*10^-6=20ms

将auto-reload preload配置为Enable

占空比暂时不需要设置,注:此时占空比为500-2500时对应的PWM脉宽为500-2500μs.

HAL库函数与Keil工程代码编写

HAL库函数

启动PWM函数

HAL_StatusTypeDef HAL_TIM_PWM_Start(TIM_HandleTypeDef *htim, uint32_t Channel);
//参数分别是时钟句柄、通道,示例
HAL_TIM_PWM_Start(&htim1,TIM_CHANNEL_1);

设置占空比函数

#define __HAL_TIM_SET_COMPARE(__HANDLE__, __CHANNEL__, __COMPARE__) \
  (((__CHANNEL__) == TIM_CHANNEL_1) ? ((__HANDLE__)->Instance->CCR1 = (__COMPARE__)) :\
   ((__CHANNEL__) == TIM_CHANNEL_2) ? ((__HANDLE__)->Instance->CCR2 = (__COMPARE__)) :\
   ((__CHANNEL__) == TIM_CHANNEL_3) ? ((__HANDLE__)->Instance->CCR3 = (__COMPARE__)) :\
   ((__HANDLE__)->Instance->CCR4 = (__COMPARE__)))
//参数分别为时钟句柄,通道,脉宽长度,示例
	__HAL_TIM_SET_COMPARE(&htim1,TIM_CHANNEL_1,500);

关闭PWM函数

HAL_StatusTypeDef HAL_TIM_PWM_Stop(TIM_HandleTypeDef *htim, uint32_t Channel);
//参数分别是时钟句柄、通道,示例
HAL_TIM_PWM_Stop(&htim1,TIM_CHANNEL_1);

需要的基本HAL库函数如上就足够了,还有一些函数,想了解的可以去了解一下

//获取定时器计数值函数
	__HAL_TIM_GET_COUNTER(_HANDLE_);
//设置定时器计数值函数
	__HAL_TIM_SET_COUNTER(_HANDLE_);
//获取重装载寄存器的值函数
	__HAL_TIM_GET_AUTORELOAD(_HANDLE_);
//设置重装载寄存器的值函数
	__HAL_TIM_SET_AUTORELOAD(_HANDLE_);
//设置预分频器的值函数
	__HAL_TIM_SET_PRESCALER(_HANDLE_);
//定时器更新中断启动函数
	HAL_TIM_Base_Start_IT(TIM_HandleTypeDef *htim);

代码编写

打开keil

在main.c函数中添加如下代码块

HAL_TIM_PWM_Start(&htim1,TIM_CHANNEL_1);		//打开定时器通道
__HAL_TIM_SET_COMPARE(&htim1,TIM_CHANNEL_1,500);		//最低脉宽500,让舵机复位到0度

接好对应的线,我们可以看到舵机复位到了0度

接下来更改脉宽为1500,便会观察到舵机转动90度

这里角度与脉宽值的对应关系就是脉宽的500-2500对应映射到舵机转动角度的0-最大角度

比如我用的最大角度为180,则500-2500分别对应0-180度

  • 30
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

翎智骁

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值