最近有个项目需要用到SG90舵机,舵机需要使用单片机产生PWM波来控制。SG90舵机的黄线接IO口PWM输出,红线和黑线分别接5V和GND,注意:在测试中发现,该型号舵机的输入电压如果是在单片机上的5V引脚接线,一定要保证给单片机供电的地方也是5V,这里我用的ST-Link下载器供电,下载程序时单片机跟他本身接的3.3V,这时在单片机上的5V口实际电压是不足的,这会导致舵机抖动不转、不按程序乱转等问题。我是在下载完程序后把3.3V杜邦线换到5V上,问题解决。
PWM控制舵机转动原理
回归正题,脉冲宽度调制(PWM),是英文“Pulse Width Modulation” 的缩写,简称脉宽调制,是利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术。简单一点,就是对脉冲宽
度的控制。
STM32 的定时器除了 TIM6 和 TIM 7。其他的定时器都可以用来产生 PWM 输出。其中高级定
时器 TIM1 和 TIM8 可以同时产生多达 7 路的 PWM 输出。而通用定时器也能同时产生多达 4
路的 PWM 输出,这样, STM32 最多可以同时产生 30 路 PWM 输出。这里我们仅利用 TIM3
做四路 PWM 输出,如果要产生多路输出,大家可以根据代码稍作修改即可。
舵机控制需要一个20ms的时基脉冲,该脉冲高电平部分为0.5ms--2.5ms范围内的角度控制对应的脉冲,总间隔为2ms。对应的角度控制关系:
0° -------------------- 0.5ms
45° -------------------- 1.0ms
90° -------------------- 1.5ms
135° -------------------- 2.0ms
180° -------------------- 2.5ms
PWM占空比是指在一个周期内,高电平信号占整个信号周期的百分比,通过改变占空比实现各个角度的转动。计算方法(以45°为例):PWM周期为20ms,占空比应为1ms / 20ms=5%。
预分频系数psc设为7199,自动重装载寄存器arr设为199,则PWM周期:
20 ms =((7199+1)*(199+1))/72000000 = 0.02
因此TIM_SetComparex(TIM3, uint16_t Comparex) 中 Comparex值与角度对应关系:
0° -------------------- 195
45° -------------------- 190
90° -------------------- 185
135° -------------------- 180
180° -------------------- 175
STM32的定时器TIM3
我们要利用 TIM3 的 四个通道输出 PWM 来控制不同的舵机,但是 TIM3的各个通道又有不同的IO接口,STM32它比较高级的地方在于为了方便接线,提供了重映像和IO复用功能,查阅STM32F1开发指南手册,如下表,TIM3的四个通道利用部分重映像或者完全重映像功能可以全部放在PB或者PC口下,我的单片机是STM32F103mini板,PC6-PC9在一块儿,所以我使用了完全重映像功能,把四个通道输出分别映射到PC6、PC7、PC8、PC9。
代码实现
pwm.h :
#ifndef __PWM_H
#define __PWM_H
#include "stdio.h"
#include "sys.h"
void PWM_Init(u16 arr,u16 psc);//TIM3初始化
#endif
pwm.c 文件复制过来太乱了,放压缩包里。
主程序main.h :
#include "delay.h"
#include "sys.h"
#include "pwm.h"
int main(void)
{
delay_init();
PWM_Init(199,7199); //TIM3初始化
while(1)
{
TIM_SetCompare1(TIM3, 185);//90 Channel 1
delay_ms(1000);
TIM_SetCompare2(TIM3, 190);//45 Channel 2
delay_ms(1000);
TIM_SetCompare3(TIM3, 180);//135 Channel 3
delay_ms(1000);
TIM_SetCompare4(TIM3, 195);//0 Channel 4
delay_ms(1000);
TIM_SetCompare4(TIM3, 175);//180 Channel 4
delay_ms(1000);
}
}
//实质是通过改变TIM_SetCompareX(TIM3, n)中的 X 和 n 来改变通道和角度
实物控制效果
视频发不了,如图红框部分是两个SG90舵机组成的机械臂,附录代码是调试前写的测试代码,简单实现机械臂的初期调试没问题。
附上调试代码:详细pwm.c和pwm.h文件如下,有不当之处欢迎评论互相学习!
本文参考:STM32F1开发指南-库函数版本_V3.1