SG90舵机驱动原理和实现

SG90

基本参数

工作扭矩: 1.6KG/cm反应转速: 0.12-0.13秒/60°转动角度: 最大180度死区设定: 5微妙使用电压: 3.5-6V

舵机应用场景

  • 固定翼
  • 直升机
  • 滑翔
  • 小型机器人
  • 机器手

航模电机动力套餐

在航模中,舵机可以控制水平尾舵面,用来控制飞机的俯仰角;控制垂直尾舵面,可以控制飞机的偏航角;

舵机通过连杆等传动元件带动舵面的转动,从而改变飞机的运动状态。舵机因此得名:控制舵面的伺服电机。

不仅在航模飞机中,在其他的模型运动中都可以看到它的应用:船模上用来控制尾舵,车模中用来转向等等。由此可见,凡是需要操作性动作时都可以用舵机来实现。

(动图来源于网络,侵权请联系号主删除)

接线图

SG90舵机有三根引线:VCC、GND、CONTROL。

VCC、GND为舵机的电源线。CONTROL为舵机控制信号的输入线。

本实例中,SG90的红线接5V电源,棕线接GND。黄线为控制线,该线接到PB9上。

与舵机控制线相连的引脚我们选择了一个具有PWM输出功能的引脚PB9。

PWM相关功能介绍详情,可以参考文末的两篇参考阅读。

工作原理

控制信号为50Hz的PWM(脉冲调制)波形(矩形波),即控制信号为周期20ms的PWM信号,不同的脉宽(占空比)对应舵机不同的方位角。改变脉宽即可改变舵机的方位角。

在没有过载且控制信号持续稳定的条件下,舵机的方位角严格保持不变。

此控制信号适合所有类型的舵机。

需要注意的是尽管也可以使用延时函数的方式来实现PWM波,但舵机运行可能不平稳,而且若PWM波的频率偏离50Hz过大,舵机会出现震荡甚至会无法启动舵机。

PWM控制信号周期20ms,脉宽0.5ms-2.5ms对应的角度-90到+90度,范围180度(3度左右偏差),当脉宽1.5ms时舵机在中立点(0度)。

以180度角度舵机为例,那么对应的控制关系是这样的:

0.5ms  --------------  -90度;1.0ms  --------------  -45度;1.5ms  --------------  0度;2.0ms  --------------  45度;2.5ms  --------------  90度;

舵机输出转角与输入脉冲的关系

转动方向与占空比有关,占空比大往右转;占空比小往左转。

脉冲宽度从 0.5ms-2.5ms,相对应舵盘的位置为 -90-+90 度,呈线性变化。

也就是说,给它提供一定的脉宽,它的输出轴就会保持在一个相对应的角度上,无论外界转矩怎样改变,直到给它提供一个另外宽度的脉冲信号,它才会改变输出角度到新的对应的位置上。

可以通过调节PWM的占空比控制舵机的转向角度。

代码实现

实现功能:点击核心板上的预留按键,每点击一次,核心板上的LED翻转一次,并同时改变舵机的旋转角度,每次改变10度。

1. PWM引脚初始化代码:

void Led_PWM_Init(u16 arr,u16 psc)
{
    TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
    TIM_OCInitTypeDef       TIM_OCInitStructure;

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);

    LED_Init();

    TIM_DeInit(TIM4);

    /* Time Base configuration */
    TIM_TimeBaseStructure.TIM_Period            = arr;
    TIM_TimeBaseStructure.TIM_Prescaler         = psc;
    TIM_TimeBaseStructure.TIM_CounterMode       = TIM_CounterMode_Up;
    TIM_TimeBaseStructure.TIM_ClockDivision     = 0;
    TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;

    TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure);

    TIM_OCInitStructure.TIM_OCMode             = TIM_OCMode_PWM2;
    TIM_OCInitStructure.TIM_OutputState        = TIM_OutputState_Enable;  
    TIM_OCInitStructure.TIM_Pulse                   = 0; 
    TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
    TIM_OC3Init(TIM4, &TIM_OCInitStructure);
    TIM_OC4Init(TIM4, &TIM_OCInitStructure);

    TIM_CtrlPWMOutputs(TIM4, ENABLE);
  
    TIM_OC3PreloadConfig(TIM4, TIM_OCPreload_Enable);
    TIM_OC4PreloadConfig(TIM4, TIM_OCPreload_Enable);
  
    TIM_ARRPreloadConfig(TIM4, ENABLE);
    
    TIM_Cmd(TIM4, ENABLE);
}

2. 调整PWM输出占空比的代码:

void Led_Set_PWM_Compare(float rate)
{
  u8 dtbuf[50]; 
  
  long tmp = 2000;  //1999

  tmp = tmp - tmp * rate / 100;
  
  //修改CCR1,即修改占空比。
  TIM_SetCompare3(TIM4, tmp);
  TIM_SetCompare4(TIM4, tmp);
}

3. main函数中,随着按键的点击,舵机改变角度的代码:

//50Hz
Led_PWM_Init(1999, 719);  //PWM 频率=72000*1000/(1999+1)/720=50
while(1) 
{    
    key = KEY_Scan(0);
    
    if(key)   
    { 
        switch(key)    
        { 
            case KEY0_PRES:
            {
                LED0 = !LED0;
            
                nPercentageOfRotationAngle += 10;
            
                if(nPercentageOfRotationAngle > 180)
                    nPercentageOfRotationAngle = 0;
            
                Led_Set_PWM_Compare((0.5 + (2.5 - 0.5) * nPercentageOfRotationAngle/ 180) * 100 /20.0);
            
                printf("KEY0_PRES...\r\n");
            }
            break;                  
            default:
                break;
        }      
    }
}
    

视频演示

声明:本内容为作者独立观点,不代表电子星球立场。未经允许不得转载。授权事宜与稿件投诉,请联系:editor@netbroad.com
觉得内容不错的朋友,别忘了一键三连哦!
赞 1
收藏 2
关注 56
成为作者 赚取收益
全部留言
0/200
成为第一个和作者交流的人吧