使用SG90舵机(180度版本)实现门锁开关功能
SG90舵机是一款广泛使用的微型伺服电机,具有小巧轻便、价格低廉的特点,适用于机器人、门锁控制等需要精确角度调节的场景。其180度版本通过PWM信号控制,典型参数为:周期20ms(50Hz),脉宽0.5ms-2.5ms对应0-180度角度。使用CH32V307单片机驱动时,需配置定时器2产生周期20ms的PWM信号,并初始化相应GPIO引脚。系统时钟96MHz经96分频后得到1MHz计数频率,配合
使用SG90舵机(180度版本)实现门锁开关功能
一、什么是SG90舵机
SG90 是一款非常常见且广泛使用的微型伺服电机(舵机),因其小巧、轻便、价格便宜且易于控制而受到创客和电子爱好者的青睐。它常用于各种项目,如机器人、遥控飞机、机械臂、相机云台等,需要精确角度控制的场景
以下是关于 SG90 的主要特点和工作原理:
主要特点:
- 尺寸与重量: 非常小巧,重量通常只有 9 克左右,因此被称为“9g舵机”。
- 旋转角度: 最常见的 SG90 版本可以旋转 0 到 180 度。也有一些特殊的 SG90 版本可以实现 360 度连续旋转(通常作为变速电机使用,控制转动方向和速度)。
- 控制方式: 通过脉冲宽度调制 (PWM) 信号进行控制。
- 舵机通常期望每 20 毫秒(即 50Hz)接收一个脉冲。
- 脉冲的宽度决定了舵机旋转的角度。例如:
- 0.5 毫秒的脉冲通常对应 0 度。
- 1.0毫秒的脉冲通常对应 45 度。
- 1.5毫秒的脉冲通常对应 90 度。
- 2.0毫秒的脉冲通常对应 135 度。
- 2.5毫秒的脉冲通常对应 180 度。
- 不同制造商生产的 SG90 舵机,其精确的脉冲宽度与角度对应关系可能略有差异,但大致范围是 0.5ms 到 2.5ms。
- 工作电压: 通常在 4.8V 到 6.0V 之间。
- 扭矩: 在 4.8V 电压下,堵转扭矩大约为 1.6 kg·cm 到 1.8 kg·cm。这意味着它可以在距离转轴 1 厘米处举起 1.6 到 1.8 公斤的重量。
- 速度: 在 4.8V 电压下,旋转 60 度大约需要 0.1 秒到 0.12 秒。
- 内部结构: 包含一个直流电机、塑料齿轮组(用于减速和增大扭矩)、一个电位器(用于检测当前角度)和一个控制电路板。
- 引脚: 通常有三根线:
- 棕色/黑色线: 接地 (GND)。
- 红色线: 电源 (VCC),通常接 5V。
- 橙色/黄色线: 信号线 (PWM),连接到微控制器(如 Arduino、树莓派)的 PWM 输出引脚。
工作原理:
PWM (脉冲宽度调制):这是一种用数字信号模拟模拟信号的技术。通过改变一个方波的高电平持续时间(即脉冲宽度),在固定周期内,可以控制等效的平均电压,或者在舵机控制中,控制其角度。
SG90 舵机的工作原理:
- 周期固定:SG90 舵机通常期望接收一个周期为 20ms(即 50Hz)的 PWM 信号。这意味着每 20 毫秒,舵机接收一个新的脉冲。
- 脉冲宽度决定角度:在这个固定的 20ms 周期内,高电平的持续时间(脉冲宽度)决定了舵机旋转到的角度。
- 最小脉宽(通常为 0.5ms 或 500us)对应一个极限角度(例如 0 度)。
- 中间脉宽(通常为 1.5ms 或 1500us)对应中间角度(例如 90 度)。
- 最大脉宽(通常为 2.5ms 或 2500us)对应另一个极限角度(例如 180 度)。
- 闭环控制:舵机内部有一个电位器来检测当前输出轴的角度,还有一个控制电路。当它接收到特定脉冲宽度的 PWM 信号时,内部电路会驱动电机转动,直到电位器反馈的当前角度与 PWM 信号所期望的角度匹配。
总结:SG90 舵机是一个闭环控制系统。当微控制器发送一个 PWM 信号到舵机的信号线时,舵机内部的控制电路会接收并解析这个信号。控制电路将 PWM 脉冲宽度与舵机内部电位器反馈的当前角度进行比较,计算出两者之间的误差。然后,它会驱动直流电机,通过齿轮组转动舵机输出轴,直到电位器反馈的当前角度与 PWM 信号设定的目标角度一致。一旦达到目标角度,舵机就会保持在该位置。
优点:
- 成本低廉: 价格非常便宜,非常适合预算有限的项目。
- 体积小: 便于集成到紧凑的设计中。
- 易于控制: 大多数微控制器平台(如 Arduino)都有成熟的库和示例代码来控制 SG90 舵机。
- 用途广泛: 适用于各种需要精确角度控制的入门级应用。
局限性:
- 扭矩较小: 对于需要较大力量的应用可能不够用。
- 塑料齿轮: 塑料齿轮相对容易磨损或损坏,不适合长时间高负载运行。
- 精度有限: 虽然可以实现角度控制,但对于非常高精度的应用可能不够。
- 功耗: 在堵转或频繁大幅度转动时,电流消耗可能会增加,需要注意电源是否能提供足够的电流(Arduino 的 5V 引脚直接供电可能不足,推荐使用外部电源)。
二、如何使用单片机驱动舵机(以沁恒CH32V307为例)
我们使用CH32的定时器2输出控制舵机的PWM脉冲。
1、常量/宏定义
#define PWM_PERIOD 20000 // PWM周期为20ms (20000us)
#define PWM_MIN 500 // 最小脉宽为0.5ms (500us)
#define PWM_MAX 2500 // 最大脉宽为2.5ms (2500us)
PWM_PERIOD 20000: 定义了 PWM 信号的周期为 20000 微秒 (us),即 20 毫秒 (ms)。这是伺服电机通常期望的 PWM 信号周期,即 50Hz 的频率 (1 / 0.02s = 50Hz)。PWM_MIN 500: 定义了 PWM 信号的最小脉冲宽度为 500 微秒 (0.5ms)。对于 SG90 舵机,这通常对应于其一个极限位置(例如 0 度)。PWM_MAX 2500: 定义了 PWM 信号的最大脉冲宽度为 2500 微秒 (2.5ms)。对于 SG90 舵机,这通常对应于其另一个极限位置(例如 180 度)。
这些宏定义直接反映了 SG90 舵机的工作特性:通过改变 0.5ms 到 2.5ms 范围内的脉冲宽度来控制其角度。
2、TIM2_PWM_Init函数:初始化TIM2以生成PWM信号
这个函数负责配置 TIM2 定时器,使其能够输出 PWM 信号。
// 初始化TIM2以生成PWM信号
void TIM2_PWM_Init(void)
{
// 1. 使能TIM2时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
// 2. 声明定时器和输出比较结构体
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
//3. 配置TIM2的基本参数 (时基单元)
// (这是一个常见的PLL设置),计数器从 0 计数到 TIM_Period 值后重新开始,决定了 PWM 周期。
TIM_TimeBaseStructure.TIM_Period = PWM_PERIOD - 1; // 设置自动重装值 (ARR)
// ARR = 20000 - 1 = 19999。计数器从0计到19999,共20000个计数周期。
TIM_TimeBaseStructure.TIM_Prescaler = 96 - 1; // 设置预分频器 (PSC)
// PSC = 96 - 1 = 95。这意味着时钟频率将被96分频。
// 定时器计数频率 = 系统时钟频率 / (PSC + 1)
// 系统时钟是96MHz,则 96MHz / 96 = 1MHz(1us)。
// 因此,定时器计数一次需要1us。
// PWM周期 = (ARR + 1) * (PSC + 1) / 系统时钟频率 = (19999 + 1) * (95 + 1) / 96MHz = 20000 * 96 / 96MHz = 20000us = 20ms。
//这与 PWM_PERIOD 的定义一致,说明配置正确。
//时钟分频,通常在定时器作为 ADC 触发源等高级应用中使用
TIM_TimeBaseStructure.TIM_ClockDivision = 0; // 不分频
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; // 向上计数模式,计数器从 0 向上计数到 TIM_Period,然后复位并重新开始。
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); // 初始化TIM2时基单元
// 4. 配置TIM2的PWM模式 (输出比较单元)
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; // 设置为PWM模式1
// PWM模式1:当计数器值小于比较寄存器值时,输出高电平;否则输出低电平(或反之,取决于极性)。
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; // 使能PWM输出
TIM_OCInitStructure.TIM_Pulse = PWM_MIN;
//设置了比较寄存器 (CCR) 的初始值。这个值决定了 PWM 信号的占空比,即脉冲的宽度。这里初始设置为 PWM_MIN (500),对应 0.5ms 的脉宽。这个值会在定时器计数值达到时触发输出电平翻转。
// 初始设置脉冲宽度为500us,即舵机初始处于0度位置。
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; // 输出极性:高电平有效
// 意味着脉冲宽度期间输出高电平。
// 5. 配置TIM2通道1 (因为PA0连接的是TIM2_CH1)
TIM_OC1Init(TIM2, &TIM_OCInitStructure); // 使用TIM2的通道1初始化输出比较模式
TIM_OC1PreloadConfig(TIM2, TIM_OCPreload_Enable); // 使能TIM2通道1的预装载寄存器
// 预装载功能:允许在更新事件发生时才将新的比较值 (TIM_Pulse) 写入实际的CCR寄存器,
// 避免PWM波形在更新时出现毛刺,确保波形平滑。
// 6. 使能TIM2的自动重装载寄存器预装载
TIM_ARRPreloadConfig(TIM2, ENABLE);
// 7. 使能TIM2
TIM_Cmd(TIM2, ENABLE);
}
3、GPIO_Init_PWM 函数:初始化GPIO以输出PWM信号
这个函数负责配置与 TIM2 输出 PWM 信号相关的 GPIO 引脚。
// 初始化GPIO以输出PWM信号
void GPIO_Init_PWM(void)
{
// 1. 使能GPIOA时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
// 2. 声明GPIO结构体
GPIO_InitTypeDef GPIO_InitStructure;
// 3. 配置PA0为复用推挽输出(TIM2通道1)
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; // 配置PA0引脚
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; // 设置为复用推挽输出模式
// 复用功能:将GPIO引脚的功能切换为片内外设(如定时器、SPI、UART等)的专用功能。
// 推挽输出:输出高电平或低电平。
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // 设置GPIO速度为50MHz
// 速度设置通常影响输出驱动能力和开关频率,对于PWM输出通常设置较高速度。
GPIO_Init(GPIOA, &GPIO_InitStructure); // 初始化GPIOA
}
详细解释:
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);: 使能 GPIOA 端口的时钟。所有 GPIO 端口在使用前都需要使能其时钟。GPIOA 属于 APB2 总线。GPIO_Pin_0: 指定要配置的引脚是PA0(Port A, Pin 0)。根据数据手册,PA0通常是 TIM2 的通道 1 (TIM2_CH1) 的默认复用功能引脚。GPIO_Mode_AF_PP: 这是关键的配置。AF(Alternate Function) 表示将该 GPIO 引脚的功能设置为其片内复用功能,而不是作为通用输入/输出。PP(Push-Pull) 表示推挽输出模式,能够提供比较强的驱动能力,适合输出数字信号。对于 PWM 输出,必须设置为复用功能模式,以便定时器模块可以直接控制该引脚。GPIO_Speed_50MHz: 设置 GPIO 引脚的输出速度。对于高速信号如 PWM,通常选择较高的速度以确保信号的上升沿和下降沿足够陡峭。
4、lock函数:修改舵机角度,实现开关门
这个函数旨在通过设置 TIM2 通道 1 的比较值(即 PWM 脉冲宽度)来控制 SG90 伺服电机(舵机)的角度。更直观的方式控制 SG90 舵机,使其在两个预设的角度之间切换,这两个角度标记为“上锁”和“关锁”。
void lock(u8 enable)//1上锁 0关锁
{
if(enable)
{
TIM_SetCompare1(TIM2,500);
}
else
{
TIM_SetCompare1(TIM2,1500);
}
}
详细解释:
u8 enable- 如果
enable为1,表示执行“上锁”操作。 - 如果
enable为0,表示执行“关锁”操作。
- 如果
TIM_SetCompare1(TIM2,…)函数负责将新的脉宽值写入 TIM2 的 CCR1 寄存器,从而实时改变 PWM 信号的占空比,进而控制舵机的角度。
功能分解:
if (enable):- 当
enable参数为真(即非零值,通常是1)时,执行此分支。 TIM_SetCompare1(TIM2, 500);: 这行代码将 TIM2 通道 1 的比较值(即 PWM 脉冲宽度)设置为500微秒。- 根据我们之前对 SG90 舵机的了解,
500us(0.5ms) 的脉冲宽度通常会使舵机旋转到其一个极限位置(例如 0 度)。因此,这个操作被定义为“上锁”。
- 当
else:- 当
enable参数为假(即0)时,执行此分支。 TIM_SetCompare1(TIM2, 1500);: 这行代码将 TIM2 通道 1 的比较值设置为1500微秒。1500us(1.5ms) 的脉冲宽度通常会使 SG90 舵机旋转到其中间位置(例如 90 度)。因此,这个操作被定义为“关锁”。
- 当
三、总结与控制原理:
- 初始化:
GPIO_Init_PWM()配置PA0引脚为 TIM2_CH1 的复用推挽输出,准备接收 TIM2 生成的 PWM 信号。TIM2_PWM_Init()配置 TIM2 的时基单元 (周期 20ms,计数频率 1MHz) 和输出比较单元 (PWM 模式 1,初始脉宽 0.5ms)。
- PWM 生成:
- TIM2 计数器从 0 开始以 1MHz 的频率向上计数。
- 当计数器值小于
TIM_Pulse(TIMx_CCRx寄存器) 时,PA0输出高电平。 - 当计数器值等于或大于
TIM_Pulse时,PA0输出低电平。 - 当计数器达到
TIM_Period(19999) 后,复位到 0,并重新开始计数,从而形成一个 20ms 周期的 PWM 波形。
- SG90 控制:
- SG90 舵机通过其信号线接收这个 PWM 信号。
- 舵机内部的控制电路会根据接收到的脉冲宽度来调整舵机的输出轴角度。
- 脉冲宽度为 0.5ms (对应
PWM_MIN) 通常使舵机转到 0 度位置。 - 脉冲宽度为 1.5ms (对应
PWM_MAX) 通常使舵机转到 90 度位置。 - 通过TIM_SetCompare1(TIM2,…)函数改变
TIM_Pulse的值(即更新 TIM2 的CCR1寄存器),就可以改变 PWM 信号的脉冲宽度,从而精确控制 SG90 舵机的角度。例如,要将舵机设置到 90 度,可能需要将TIM_Pulse设置为 1500 (对应 1.5ms 脉宽)。
更多推荐



所有评论(0)