51单片机使用 PWM 控制 SG90 舵机

一、SG90舵机简介

舵机是伺服电机的一种,伺服电机就是带有反馈环节的电机,我们可以通过伺服电机进行精确的位置控制或者输出较高的扭矩;舵机有常用三根接线,黄色为PWM信号控制线,红色为VCC,棕色为GND,主要用来实现转动。

51单片机使用 PWM 控制 SG90 舵机 1 - 斯塔克电子

SG90舵机有两种旋转范围分别是0°~ 180°,0°~ 360°。它是是由可变宽度的脉冲控制的,脉冲的参数有最小值、最大值和频率。基准信号周期为20ms,频率为50kHz,脉冲宽度和舵机的转角相对应的。

二、PWM简介

PWM,英文名 Pulse Width Modulation,是脉冲宽度调制缩写,它是通过对一系列脉冲的宽度进行调制,等效出所需要的波形(包含形状以及幅值),对模拟信号电平进行数字编码;通过调节占空比的变化来调节信号、能量等的变化,占空比就是指在一个周期内,信号处于高电平的时间占据整个信号周期的百分比,例如方波的占空比就是50%。

占空比:一个周期内,高电平占据时长的百分比。

舵机转动角度与占空比的关系:

以180度角度伺服为例 0.5ms - 2.5us 的PWM高电平部分对应控制180°舵机的0°-180°

0.5ms--------------0°,2.5%对应函数中占空比为250
1.0ms------------45°,5.0%对应函数中占空比为500
1.5ms------------90°,7.5%对应函数中占空比为750
2.0ms-----------135°,10.0%对应函数中占空比为1000
2.5ms-----------180°,12.5%对应函数中占空比为1250
51单片机使用 PWM 控制 SG90 舵机 2 - 斯塔克电子
三、代码实现

#include "reg52.h"            // 头文件
sbit Sevro_moto_pwm = P3 ^ 4; // 舵机信号线(黄、橙色)
unsigned char pwm_val = 0;    // 变量定义
unsigned char push_val;       // 舵机归中,产生约,1.5MS 信号
void delay1ms(unsigned int k) // 延时1ms函数,k等于多少就延时多少ms
{
    unsigned int a, b, c, d;
    for (d = 0; d < k; d++)
        for (c = 1; c > 0; c--)
            for (b = 50; b > 0; b--)
                for (a = 2; a > 0; a--)
                    ;
}
/**********************************************************************************************
** TIMER1中断服务子函数产生PWM信号
**********************************************************************************************/
void time1() interrupt 3 using 2
{
    TH1 = (65536 - 100) / 256; // 100US定时 以晶振频率为11.0592Mhz计算
    TL1 = (65536 - 100) % 256;
    pwm_val++;
    if (pwm_val <= push_val)
        Sevro_moto_pwm = 1; // PWM信号高电平时间
    else
        Sevro_moto_pwm = 0; // PWM信号高电平时间
    if (pwm_val >= 100)
        pwm_val = 0;
}
/**********************************************************************************************
** 主函数
**********************************************************************************************/
void main(void)
{
    TMOD = 0X10;
    TH1 = (65536 - 100) / 256; // 100US定时
    TL1 = (65536 - 100) % 256;
    TR1 = 1;
    ET1 = 1;
    EA = 1;
    while (1)
    {
        int i;
        for (i = 22; i >= 4; i--) // 偏转角需要微调
        {
            push_val = i;
            delay1ms(100);
        }
        for (i = 4; i <= 22; i++)
        {
            push_val = i;
            delay1ms(100);
        }
    }
}
0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
有新私信 私信列表
搜索