今日进行SG90舵机驱动开发,功能:实现舵机精准旋转角度

1.SG90原理

SG90舵机在大家入门STM32时应该都接触过,也叫伺服电机,在嵌入式开发中,舵机作为一种常见的运动控制组件,具有广泛的应用。其中,SG90 舵机以其高效、稳定的性能特点,成为了许多工程师和爱好者的首选,无论是航模、云台、机器人、智能小车中都有它的身影。

img
在下王同学
​​​​

工作参数如下:

  • 工作扭矩:1.6kg/cm

  • 反应速度:0.12 - 0.13秒/60°

  • 死区设定:5us

  • 转动角度:常见0°、90°、180°、360°

  • 齿轮材质:尼龙塑料齿

  • 工作电压:3V - 6V

  • 温度范围:-30° ~ +60°

引脚接线参考如下:

SG90 STM32
PWM 信号线(橙色线) 任意GPIO
VCC(红线) 3.3/5V
GND(棕色线) GND

舵机的控制信号是通过脉冲宽度调制(PWM)来实现的。PWM 信号的周期通常为20ms,而脉冲宽度则在 0.5ms 至 2.5ms 之间变化。这个脉冲宽度与舵盘的位置呈线性关系,范围从0度到180度。

当给舵机提供特定宽度的脉冲信号时,输出轴会保持在相应的角度上,不受外界转矩的影响,直到接收到不同宽度的脉冲信号才会改变输出角度,使舵盘移动到新的位置。舵机内部有一个基准电路,产生周期为 20ms、宽度为 1.5ms 的基准信号。同时,还有一个比较器,用于将外部输入信号与基准信号进行比较,以确定转动方向和幅度,并生成驱动电机转动的信号。

控制电路板接收来自信号线的 PWM 控制信号,然后控制电机的转动。电机带动一系列齿轮组,在经过减速传动后,将力量传递到输出舵盘上。舵机的输出轴与位置反馈电位计相连,当舵盘旋转时,位置反馈电位计也会随之变化,向控制电路板输出电压信号进行反馈。控制电路板根据位置反馈信号判断当前位置,并决定电机的转动方向和速度,以实现目标停止。

为了控制舵机,需要使用单片机来生成周期为 20ms 的脉冲信号,并通过控制脉冲的高电平时间在 0.5ms 至 2.5ms 之间来控制舵机的角度。这样,我们可以通过调整 PWM 信号的脉冲宽度来精确控制舵机的位置和运动。

以 SG90,180度版为例,那么对应的控制关系是这样的:

0.5ms 2.5%
1.0ms 45° 5.0%
1.5ms 90° 7.5%
2.0ms 135° 10.0%
脉冲高电平 角度 占空比
2.5ms 180° 12.5%

2.编写设备树信息

查看韦东山STM32MP157开发板的外接模块,我选择了PD8引脚(后续发现这个引脚不可用)

修改pwm 的pinctrl设备树信息:

vi stm32mp157-100ask-pinctrl.dtsi

找到pwm1_pins_a,在其pinmux中增加定时器1通道3,指定PD8引脚

然后找到定时器的设备树文件stm32mp15xx-100ask.dtsi,修改定时器1

vi arch/arm/boot/dts/stm32mp15xx-100ask.dtsi

将状态设置为okay,并在pwm前添加pwm1

最后编写SG90设备节点,找到设备树stm32mp157c-100ask-512d-lcd-v1.dts,修改设备树将指定好的pwm映射到sg90所连接的GPIO引脚(即pinctrl子系统,我这里映射到了PD8上)(周期20ms应该是20000000,我搞错了。

vi arch/arm/boot/dts/stm32mp157c-100ask-512d-lcd-v1.dts

编译内核,上传开发板,编写驱动程序、测试程序

3.上机测试

加载驱动后提示报错,从错误信息来看,问题出现在设备树匹配上,具体错误是:

[  553.986279] stm32mp157-pinctrl soc:pin-controller@50002000: invalid function.
[  553.995751] my_sg90: probe of pwm_sg90 failed with error -22

错误代码-22表示EINVAL(无效参数)。这通常是因为设备树节点配置不正确,或者平台设备无法正确匹配和初始化。

需要确认PD8的正确复用功能。根据STM32MP157的数据手册

通过数据手册可知,PD8不可用复用为定时器引脚,并且我查阅开发板外设模块其它引脚信息,发现都不可以复用为定时器引脚。

查询了一些资料,可用的GPIO引脚都不能复用为定时器通道,那么无法使用硬件PWM。但是我们可以通过软件方式模拟PWM信号来控制SG90舵机。

SG90舵机要求的是50Hz的PWM信号(周期20ms),脉宽在0.5ms到2.5ms之间。我们可以使用一个GPIO引脚,通过软件控制高低电平的时间来模拟PWM。

注意:软件模拟PWM会占用CPU资源,但SG90舵机只需要50Hz,这个频率不高,在Linux系统中可以通过内核定时器来实现。

方案:使用GPIO模拟PWM

我们将使用一个GPIO引脚,然后通过内核定时器来精确控制高低电平的持续时间。具体步骤:

  1. 请求GPIO引脚,并设置为输出。

  2. 使用高精度定时器(hrtimer)来精确控制时间。

  3. 在定时器中断处理函数中切换GPIO电平,并计算下一个中断的时间。

但是,由于Linux内核是抢占式的,软件模拟的PWM精度可能会受到系统负载的影响。但对于舵机控制,50Hz的频率和毫秒级的精度要求,通常是可以接受的。

好像也可以使用步进电机来代替舵机,等过几天我再尝试一下,目前lab事情比较多,每天就上午可以捣鼓一下这个。

Logo

更多推荐