STM32CubeMX教程---通用定时器_PWM_舵机角度控制

本篇摘要:

  • 实验平台:CubeMX + HAL库 + Keil; 
  • 配置通用定时器 - TIM2,输出PWM信号控制舵机:周期20ms,  脉宽0.5ms~2.5ms;
  • 调用HAL函数,修改脉宽,控制舵臂的转动角度;
  • 设计角度控制函数,传入角度作参数,即可实现舵臂旋转至指定角度;

目录

一、PWM信号

二、舵机

三、新建一个Keil工程

四、CubeMX配置 (TIM时基、PWM周期)

五、Keil编写代码 

六、设计一个角度控制函数


一、PWM信号

1、什么是PWM信号

全称Pulse Width Modulation:脉冲宽度调制; 通俗地讲就是调节脉冲的宽度。

PWM是电子电力应用中非常重要的一种控制技术。通过调节占空比的变化,来调节信号、能量等的变化,常用于控制电机速度、调节LED亮度、产生音频信号等场景。

2、PWM的参数

  • 频率:1秒内,信号从高电平到低电平再回到高电平的次数,单位Hz。
  • 周期:1个脉冲信号的时长。T=1/f,T是周期,f是频率。50Hz = 1÷50 = 20ms 一个周期。
  • 脉宽:高电平持续的时间。
  • 占空比:一个脉冲周期内,高电平时长与周期时长的比例,用百分数表示,比如50%。

二、舵机

本篇所用舵机:MG996R ,为180°舵机 。同时适用MG995等180°舵机 

1、舵机的分类

①  按 旋转角度 分类:

  • 180°舵机:能给定角度、转速固定。 在0°~180°之间运动,超过范围,轻则齿轮打坏,重则烧坏内部电路.
  •  360°舵机:360度转动,、转速能控制,但不能控制角度。

②  按 控制信号 分类:

  • 模拟舵机:持续提供PWM信号才能固定角度。优点:便宜。
  • 数字舵机:只要给一次PWM信号就能固定角度。优点:高精度、响应快、抖动小、大扭矩。

2、舵机的重要参数

  • 最大扭矩:如上面的MG996, 最大扭矩: 13KG/cm. 这个是在舵机堵转时测得的, 即距离轴中心1cm处能挂起的重量.
  • 工作电压:如常用的3.0V~7.2V, 接入电压不同, 所能产生的工作扭矩自然不同. 直接影响角度固定力。

3、舵机接线

  • 红色:5V供电;舵机需要电流较大,建议独立供电; 小舵机在测试时可以开发板上取电;

  • 粽色:地线;如果独立供电,必须与SMT32控制芯片共地(GND互接);

  • 橙色:PWM信号线;接芯片TIM_CH引脚,本篇使用TIM2_CH1,即PA0;

4、舵机如何控制角度

舵机使用PWM信号进行控制:周期20ms, 脉宽0.5ms~2.5ms。

周期要求:50HZ,即周期为20ms。

脉宽要求:脉宽在0.5ms-2.5ms之间时,舵机就对应旋转到不同的角度。

          

为了更好地理解其信号构成,和便于编写代码,下面把PWM信号的关键参数转换为us值,

  1. 每个时钟步长:              1us
  2. PWM信号周期:     20000us   (20000个时钟)
  3. 舵臂0度时,脉宽:     500us    (500个时钟)
  4. 舵臂180度时, 脉宽: 2500us (2500个时钟)
  5. 每增加1 °,增加脉宽:(2500-500)÷180 = 11.1us  (即每1度的比例系数)
  6. 某角度值A,脉宽公式 :(A x11.1 +500)us   

三、新建一个Keil工程

使用CubeMX新建一个Keil工程,可参考下面链接,几分钟就能完成:        

        STM32CubeMX新建一个工程_STM32F103

        STM32CubeMX新建一个工程_STM32F407    

本篇所用工程,是直接复制之前已新建的LED工程。

建议习惯使用复制旧工程的方法,以减少新建工程的前后时间开支。


四、CubeMX配置 (TIM时基、PWM周期)

1、TIM输出PWM的要点

STM32的所有芯片型号,都带TIM外设。

TIM常用的3个主要功能:定时、PWM输出、捕获。

要使TIM输出PWM信号,主要是对4个关键寄存器值的理解和控制:

  • PSC:预分频器值。定时器的输入时钟,经过预分频器的分频处理,调整为需要的时钟频率,从而实现便捷的时间控制。PSC值决定着每个计数脉冲的步长。
  • CNT:计数器值。硬件自动控制,每个TIM工作脉冲,触发一次计数,使CNT值+1(或-1)。
  • ARR:自动重载值。决定多少个脉冲作为1周期。当CCR计数达到ARR设定的次数时,CNT值由硬件自动重载,开始下一轮计数。
  • CCR:比较器值。被与CNT作比较,以确定每个PWM脉宽。如当CNT<CCR,输出高电平。

其它的周边参数,均用于配合这4个参数,以灵活地输出期待的信号。

特别地建议,把TIM的输入时钟分频成便于计数的频率,如,如1MHz(1us)、100KHz(10us)等; 

2、常用STM32型号各TIM的输入时钟

开始TIM的配置前,我们还要知道一个条件:当前芯片所使用TIM的输入时钟频率:

  • STM32F103系列:所有 TIM 的时钟频率都是72MHz;
  • STM32F407系列:TIM1、8、9、10、11是168MHz;其它TIM的时钟频率是84MHz。

只要知道当前TIM的输入时钟频率,我们就能通过CubeMX,轻松的配置出需要的PWM信号。

3、CubeMX的具体配置

使用CubeMX对定时器进行定时配置,过程相当简单、便捷。

下图是STM32F407的TIM2的PWM配置截图,以舵机的20ms周期作为配置示范。

这里开通了两路PWM输出,可以连接两个舵机,如果只需要一路,取消其中1个通道即可。

        注意1:我们上面把PSC设置为 84-1,即为84分频,分频后每个计数时钟步长1us。

        注意2:为什么要 "-1",因为PSC和ARR寄存器工作时,会把值+1,具体可查芯片参考手册。

        注意3:这里的Pulse,是启动TIM时直接就输出的"脉宽"时钟个数。

4、PWM的输出引脚

        使用CubeMX配置PWM输出,无需再手动配置某引脚为TIM功能。        

        在选择了Channel的工作模式为"PWM生成"后, CubeMX会自动使能相关引脚。

        如下图所示,CubeMX自动使能了:PA0为TIM2_CH1, PA1为TIM2_CH2。

        打开下述页面,可以查看到其使用的具体引脚。可以修改成其它引脚,但不建议!


五、Keil编写代码 

需要使用代码实现的:启动TIM、输出PWM、改变PWM脉宽。

其实,Keil这里,编写的代码量很少,简单得不得了,就两个函数:

  • 启动TIM并输出PWM:HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_1);
  • 修改PWM的脉宽:__HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_1, 1500);

1、初始化

 TIM的初始化,CubeMX已根据我们的配置,自动生成好了,无需再编写代码。

如果要学习它的代码,可以打开tim.c查看。

2、启动TIM

启动TIM需要的函数:HAL_TIM_PWM_Start (&htim2, TIM_CHANNEL_1);

在main函数中,MX_TIM2_Init()的后面、while()的前面,调用函数,即可启动TIM并输出PWM。        

插入上述函数行后,编译,烧录,我们来看看现场效果吧:

烧录完成后,可以发现,舵臂的角度是-90度,如下图所示。
     

3、改变周期的脉宽,使舵臂改变角度

        PWM信号中,500us~2500us的脉宽,对应着舵机-90°~90°的舵臂角度。

        想改变舵臂的角度,就需要修改PWM的脉宽。

        PWM的脉宽由CCR寄存器决定:CNT<CCR时,输出高电平。CCR值的大小,决定着脉宽。

        修改CCR值的HAL函数:__HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_1, 1500);

        程序中,增加函数调用,如下图147行:

       

        编译、烧录。现在的舵臂角度为:

这里解释一个代码书写习惯:

上面使用的函数名称:__HAL_TIM_SET_COMPARE( ),

在函数名称前有两个下划线,表示它一个宏定义(宏函数),而不是一个真正的函数。

另外 ,如果习惯使用寄存器写法的朋友,还能使用更简单的写法:

TIM2 -> CCR1 = 1500;    // 使用寄存器写法,更加简单清晰

至此,我们已实现TIM2的PWM信号输出、修改脉宽,能通过修改CCR值控制舵机的角度了。

下面,我们设计一个角度控制函数,使操作变得更直观。


           

六、设计一个角度控制函数

        上面的操作,如果想转动到指定角度,每次都需要预先计算角度对应的CCR值。

        为了更直观的使用,我们把计算对应CCR值的操作,封装成一个函数,输入角度参数即可。

1、 计算每1°需要的脉宽

        舵机手册中,角度与脉宽的关系:500us为-90°,1500us为0°,2500us为90°。

        为了更好地理解与换算,我们不使用-90°~90°的表示方法,改为使用0°~180°的表示方法:

        500us为0°,1500us为90°,2500us为180°

        180度角,每1°对应:(2500-500)÷180 = 11.11us。

        如下图中的理解。

2、编写函数

3、调用函数

        先注释了之前的 :__HAL_TIM_SET_COMPARE( ) ;

        调用我们刚写的函数:AnalogServo_1_Angle(125.5),现在,参数即为角度,更直观了。

再次编译、烧录,效果杠杠的:


如有错漏,望指正~

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值