两款舵机SG90和MG90S的对比和简单应用
文章目录
- 一、介绍舵机
- 1.什么是舵机?
- 2.SG90舵机和MG90S舵机有什么不同?
- 3.工作原理
- 二、使用步骤
- 1.硬件
- 2.软件
- 1.初始化配置代码如下(示例):
- 2.PWM写入代码如下(示例):
- 3.舵机控制角度函数如下(示例):
- 4.变量定义(示例):
- 5.测试(示例):
- 3.总结
一、介绍舵机
1.什么是舵机?
舵机是一种电动装置,常用于控制机械系统的转动角度和位置。它由电机、减速器、位置反馈器和控制电路组成。舵机通常通过接收控制信号来控制输出轴的转动角度和位置,并通过内部的位置反馈器和控制电路实现精确的控制。
舵机在机器人、模型飞机、无人机、遥控车等控制领域中广泛应用。通过使用不同规格的齿轮减速器,舵机可以产生不同的扭矩和转速输出,并且可以提供不同的控制精度和灵敏度。通常情况下,舵机可以分为两大类:180度舵机和360度舵机。
总之,舵机是一种广泛应用于机械控制和自动化领域的电动装置。它通过内部的位置反馈器和控制电路实现精确的角度和位置控制,从而为机械系统的运动提供了重要的支持。
2.SG90舵机和MG90S舵机有什么不同?
SG90,9克经典舵机是180度舵机,好像也有360度款式的,这里主要以180度来说明,它主要控制0-180度角度,左边90度,右边90度。
MG90S是360度舵机,但是它是没有0-360度角度控制的功能,在控制方式上和SG舵机其实是一样的,只不过它控制的不是角度,而是控制速度和方向(顺时针旋转/逆时针旋转),它实际就相当于无级变速的减速电机。
总之,SG90舵机和MG90S舵机的区别在于它们的旋转角度范围不同,选择哪种舵机需要根据具体的应用需求来决定。

3.工作原理
舵机的工作原理比较简单,当接收到脉冲信号时,舵机会根据信号的脉宽计算需要转动的角度,并通过电机驱动器输出转动力矩,从而控制输出轴的旋转。通过内部的位置反馈器,舵机可以检测电机当前的位置和角度,并精确地控制输出轴的角度和位置。

而360度舵机上面也说过了它是没有角度控制的功能,它控制的是速度和方向(顺时针旋转/逆时针旋转)。
下图是我实际测量的脉冲宽度和方向速度的关系图:
| 脉冲宽度(周期20ms) | 方向和速度 |
|---|---|
| 0.5ms | 顺时针,速度快 |
| 1.0ms | 顺时针,速度慢 |
| 1.5ms | 逆时针,速度慢 |
| 2.0ms | 逆时针,速度快 |
| 2.5ms | 停止状态 |
二、使用步骤
1.硬件
舵机的接线也相对比较简单,一般只有3根线,供电正负极和信号控制。
供电电压的话一般是3.0-7.2V,我这里是采用5V电压供电。
信号控制脚需要选择有PWM输出的引脚。

2.软件
1.初始化配置代码如下(示例):
舵机的工作频率通常为 50Hz。我们这里的TIM2 定时器的计数周期 (Period) 设置为 20000-1,预分频器 (PSC) 设置为 72-1。(后面有宏定义可以看到)
根据定时器的工作原理,计数器的时钟频率可以计算如下:
计数器时钟频率 = 主时钟频率 / (预分频器 + 1) =72MHZ /(71+1)=1MHZ
舵机的工作频率 = 计数器时钟频率/(计数周期 + 1)=1MHZ/20000=50hz
从而可以得到舵机的工作周期 = 1/f=1/50HZ=20ms
/******************************************************************************** 函数名:User_Servo_Init* 描述 :舵机初始化* 输入 :void* 输出 :void* 调用 :初始化 * 备注 :
*******************************************************************************/
void User_Servo_Init(void)
{User_TIM2_Init();//PWM配置
}/******************************************************************************** 函数名:User_TIM2_Init* 描述 :定时器2初始化* 输入 :void* 输出 :void* 调用 :初始化* 备注 :
*******************************************************************************/
void User_TIM2_Init(void)
{RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); //开启TIM2的时钟RCC_APB2PeriphClockCmd(Servo_GPIO_RCC, ENABLE); //开启GPIOA的时钟/*GPIO初始化*/GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;//受外设控制的引脚,均需要配置为复用模式GPIO_InitStructure.GPIO_Pin = Servo1_Pin | Servo2_Pin;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(Servo_GPIO_Port, &GPIO_InitStructure);//将PA1引脚初始化为复用推挽输出 /*配置时钟源*/TIM_InternalClockConfig(TIM2); //选择TIM2为内部时钟,若不调用此函数,TIM默认也为内部时钟/*时基单元初始化*/TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure; //定义结构体变量TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1; //时钟分频,选择不分频,此参数用于配置滤波器时钟,不影响时基单元功能TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up; //计数器模式,选择向上计数TIM_TimeBaseInitStructure.TIM_Period = TIM2_Period; //计数周期,即ARR的值TIM_TimeBaseInitStructure.TIM_Prescaler = TIM_Prescaler; //预分频器,即PSC的值TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0; //重复计数器,高级定时器才会用到TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStructure); //将结构体变量交给TIM_TimeBaseInit,配置TIM2的时基单元/*输出比较初始化*/ TIM_OCInitTypeDef TIM_OCInitStructure; //定义结构体变量TIM_OCStructInit(&TIM_OCInitStructure); //结构体初始化,若结构体没有完整赋值//则最好执行此函数,给结构体所有成员都赋一个默认值//避免结构体初值不确定的问题TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //输出比较模式,选择PWM模式1TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //输出极性,选择为高,若选择极性为低,则输出高低电平取反TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //输出使能TIM_OCInitStructure.TIM_Pulse = 0; //初始的CCR值TIM_OC2Init(TIM2, &TIM_OCInitStructure); //将结构体变量交给TIM_OC2Init,配置TIM2的输出比较通道2TIM_OCInitStructure.TIM_Pulse = 0; //初始的CCR值TIM_OC1Init(TIM2, &TIM_OCInitStructure); //将结构体变量交给TIM_OC2Init,配置TIM2的输出比较通道2 /*TIM使能*/TIM_Cmd(TIM2, ENABLE); //使能TIM2,定时器开始运行
}
2.PWM写入代码如下(示例):
这里我用到的主控芯片是STM32F103C8芯片,SG90控制脚接的是PA1,刚好是定时器2的通道2,MG90S控制脚接的是PA0,刚好是定时器2的通道1。(后面有宏定义可以看到)
/******************************************************************************** 函数名:PWM1_SetCompare* 描述 :PWM设置CCR* 输入 :Compare 要写入的CCR的值* 输出 :void* 调用 :初始化* 备注 :CCR和ARR共同决定占空比,此函数仅设置CCR的值,并不直接是占空比.占空比Duty = CCR / (ARR + 1)
*******************************************************************************/
void PWM1_SetCompare(uint16_t Compare)
{TIM_SetCompare2(TIM2, Compare);//设置CCR2的值
}/******************************************************************************** 函数名:PWM2_SetCompare* 描述 :PWM设置CCR* 输入 :Compare 要写入的CCR的值* 输出 :void* 调用 :初始化* 备注 :CCR和ARR共同决定占空比,此函数仅设置CCR的值,并不直接是占空比.占空比Duty = CCR / (ARR + 1)
*******************************************************************************/
void PWM2_SetCompare(uint16_t Compare)
{TIM_SetCompare1(TIM2, Compare); //设置CCR1的值
}
3.舵机控制角度函数如下(示例):
根据舵机的控制原理,SG90舵机要实现0-180°旋转,就是要PWM输出0.5ms-2.5ms周期的一个变化,Servo1_SetAngle函数刚好根据写入的角度Angle来实现写入不同周期的PWM。MG90S舵机没有控制角度的功能,控制的是速度和方向。
/******************************************************************************** 函数名:Servo1_SetAngle* 描述 :舵机设置角度* 输入 :Angle 要设置的舵机角度,范围:0~180* 输出 :void* 调用 :* 备注 :
*******************************************************************************/
void Servo1_SetAngle(float Angle)
{PWM1_SetCompare(Angle / 180 * 2000 + 500); //设置占空比//将角度线性变换,对应到舵机要求的占空比范围上
}/******************************************************************************** 函数名:Servo1_SetAngle* 描述 :舵机设置速度/方向* 输入 :Angle,范围:0~360* 输出 :void* 调用 :* 备注 :
*******************************************************************************/
void Servo2_SetAngle(float Angle)
{PWM2_SetCompare(Angle / 360 * 2000 + 500); //设置占空比//将角度线性变换,对应到舵机要求的占空比范围上
}
4.变量定义(示例):
/* Defines ------------------------------------------------------------------*/
#define Servo_GPIO_RCC RCC_APB2Periph_GPIOA
#define Servo_GPIO_Port GPIOA
#define Servo1_Pin GPIO_Pin_1
#define Servo2_Pin GPIO_Pin_0//根据实际的引脚修改#define TIM2_Period 20000 - 1//计数周期,即ARR的值
#define TIM2_Prescaler 72 - 1 //预分频器,即PSC的值
5.测试(示例):
测试视频内容就是MG90S舵机逆时针360度旋转,SG90舵机逆时针180度旋转。
舵机测试视频
3.总结
今天主要讲了舵机的工作原理和SG90与MG90S的区别,舵机一般是应用在摄影、监控和导航系统中的装置,它可以通过控制舵机的转动来改变相机或传感器的视角和方向。对舵机感兴趣的可以玩一玩,感谢你的观看,谢谢!