前言
最近做项目有用到mg90s这个180度的,看到网上HAL库的驱动不多,所以分享一下,毕竟谁都不喜欢干重复造轮子的事。在机器人制作、模型控制或是自动化项目中,舵机都因其精确的角度控制和易于使用的特性而备受青睐。
外观
- 舵机是一种集成了电机、传动机构和位置反馈系统的特殊电机,能够根据输入的信号自动调整到指定角度并保持稳定。主要由外壳、电机、齿轮组、电位计和控制电路板组成。
- 当控制信号(通常是PWM信号)发送到舵机时,控制电路会根据信号调整电机的旋转方向和速度,直至电位计检测到的角度与设定角度一致,实现闭环控制。
- 舵机通常有三个接口:电源线(红色,通常为+5V或+6V)、地线(黑色或棕色)和信号线(黄色或橙色)。
控制
![78e5e89413d74f58a12c753b483421de.jpeg](https://i-blog.csdnimg.cn/direct/78e5e89413d74f58a12c753b483421de.jpeg)
![5eb31b02821d403e893192b50623c548.png](https://i-blog.csdnimg.cn/direct/5eb31b02821d403e893192b50623c548.png)
舵机的控制信号为周期是 20ms (50Hz)的脉宽调制(PWM)信号,其中脉冲宽度从 0.5ms-2.5ms, 脉宽越大,转动角度越大。当然不能超过他最大脉宽,也不能否小于最小脉宽。
CubeMX配置
1.Clock Source(时钟源):这里选择Internal Clock(内部时钟)
2.Channel(通道):这里选一个你要输出的通道把他配置成PWM Generation (PWM输出模式)
3.底下的参数都保持默认就是默认低电平模式了,如果你的不是把下面PWM输出模式12切换一下
4.最重要的就是预分频器和自动重装值的设定了:这里一定要注意你选择的定时器是挂载在哪条总线上,以及定时器的频率,我这里用的是G431CBT6没有外部晶振,主频150MHz,我这里使用的TIMER1也是150Mhz,如果你主频64,150改64,72就150改72,这样最简单方便,注意取值范围和结果-1就行。
代码
derives_servo.h
#ifndef __DERIVES_SERVO_H
#define __DERIVES_SERVO_H
#include "main.h"
/********************移植修改********************/
#define Servo_Tim_Number htim1 //定时器序号
#define Servo_Tim_Channel TIM_CHANNEL_1 //定时器通道
#define Servo_Tim_Counter 200 //计数器数值
extern TIM_HandleTypeDef Servo_Tim_Number;
void Servo_Init(const uint8_t Angle);
int8_t Servo_Control(const uint8_t Angle);
void Servo_Test(void);
#endif /*__DERIVES_SERVO_H*/
derives_servo.c
/***********************************************************************************************
* 程序名称: MG90S舵机驱动
* 创建时间: 2024.6.12
* 注意事项: 仅支持MG90S舵机180度版本,移植其他舵机注意修改
**********************************************************************************************/
#include "drivers_servo.h"
/***********************************************************************************************
* 函数名称:SERIVO_Init
* 功能描述:舵机初始化
* 输入参数:初始化舵机的角度
* 输出参数:定时器数据
* 返 回 值:无
* 注意事项:移植注意修改定时器和通道
* 修改日期 版本号 修改人 修改内容
* --------------------------------------------------------------------------------------------
* 2021/06/12 V1.0 WangJoy 创建
**********************************************************************************************/
void Servo_Init(const uint8_t Angle)
{
Servo_Control(Angle); //设置初始化舵机的角度
HAL_TIM_PWM_Start(&Servo_Tim_Number, Servo_Tim_Channel); //开启定时器
}
/***********************************************************************************************
* 函数名称:SERIVO_Control
* 功能描述:控制舵机旋转
* 输入参数:角度 0~180
* 输出参数:定时器数据
* 返 回 值:-1输入角度错误
* 注意事项:移植注意修改定时器和通道
* 修改日期 版本号 修改人 修改内容
* --------------------------------------------------------------------------------------------
* 2021/06/12 V1.0 WangJoy 创建
**********************************************************************************************/
int8_t Servo_Control(const uint8_t Angle)
{
if(Angle > 180) return -1; //输入参数检查
uint16_t temp = Servo_Tim_Counter * (1755 - Angle) / 1800;
__HAL_TIM_SetCompare(&Servo_Tim_Number, Servo_Tim_Channel, temp);
return 1;
}
/***********************************************************************************************
* 函数名称:Servio_Test
* 功能描述:舵机测试程序
* 输入参数:无
* 输出参数:舵机控制角度
* 返 回 值:无
* 注意事项:需先调用初始化舵机程序
* 修改日期 版本号 修改人 修改内容
* --------------------------------------------------------------------------------------------
* 2021/06/12 V1.0 WangJoy 创建
**********************************************************************************************/
void Servo_Test(void)
{
Servo_Control(0);
osDelay(1000);
Servo_Control(180);
osDelay(1000);
}
移植注意
1.头文件里面的三个宏定义注意修改
2.测试程序我用的是osDelay,如果你没有用操作系统换成自己的延时函数。