目录
一、什么是舵机
PWM
生成PWM波的原理
二、SG90工作原理
180度舵机
360度舵机
三、相关代码
main.c
timer0.c
timer0.h
delay.h
一、什么是舵机
“舵机是一种直流微型伺服电机,它能够接收并响应控制信号,实现角度或位置的精确控制。舵机通常由直流电机、电机控制器、电位器和减速器等部分构成,并封装在一个便于安装的外壳中。它通过闭环控制系统来工作,能够根据输入的信号精确地控制输出轴的角度,并在负载变化时自动调节以保持稳定的控制状态。舵机的应用非常广泛,包括在自动驾驶仪中操纵飞机舵面,以及在智能小车和机器人中实现转向和关节运动等功能。舵机可以分为不同的类型和角度,其中180°舵机最为常见。”——百度百科
我们今天的主角SG90是舵机中最为常见的种类之一,它分为180度舵机和360度舵机。
图1 SG90
PWM
图2
生成PWM波的原理
(1)用定时来实现,设定一个初始值,使其溢出时间为500us,再设定一个计数值,控制PWM波的周期,该值最大为40(500us*40=20 000us),如此便设定了周期为20ms;计数值会一直和比较值做比较,这样就可以实现高电平时间的控制。
(2)通过上述三个值的调节,就可以实现舵机不同角度的转动
二、SG90工作原理
按 红线 接 VCC,棕线 接 GND,黄线 接 IO口 这个方式接好SG90的三根线后,SG90将按照接收到的不同的PWM信号做出相应的“动作”。180度舵机和360度舵机反应不同,具体将在下文介绍。
180度舵机
180度舵机是为了让舵机旋转特定角度而设计的,其转动的角度与脉冲占空比有关。
角度 | 脉冲周期 | 脉冲高电平时间 | 对应占空比 |
---|---|---|---|
0 | 20ms | 0.5ms | 2.50% |
45 | 20ms | 1ms | 5.00% |
90 | 20ms | 1.5ms | 7.50% |
135 | 20ms | 2ms | 10.00% |
180 | 20ms | 2.5ms | 12.50 % |
为了更直观地看到不同占空比对角度的影响,我专门做了动画演示,如图2。
图3 演示动画
在使用单片机时,使用定时器加中断的方法改变占空比。
图4
360度舵机
此类舵机通用使用PWM控制,不同的是,不同PWM将影响舵机的转速。(180度舵机接收到PWM信号后转到指定角度便不再转动,而360度舵机则是一直旋转。)
转速及方向 | 脉冲高电平时间 | 对应占空比 |
---|---|---|
正向最大转速 | 0.5ms | 2.50% |
速度为0 | 1.5ms | 7.50% |
反向最大转速 | 2.5ms | 12.50% |
当然,和角度一样,可以改变参数以实现不同的转速。
三、相关代码
main.c
#include <REGX52.H>
#include "timer0.h"
#include "delay.h"
sbit SG_PWM=P2^7;
unsigned char count=0;
unsigned char PWM_count=0;
void main()
{
Timer0Init();
while(1)
{
PWM_count=1
Delay(1000);
PWM_count=2;
Delay(1000);
PWM_count=3;
Delay(1000);
PWM_count=4;
Delay(1000);
}
}
void Timer0() interrupt 1
{
TL0 = 0xA4; //设置定时初始值
TH0 = 0xFF; //设置定时初始值
count++;
count%=40; //使count的值一直处于0~39,正好四十个数,40*0.5=20,对应pwm
if(count<PWM_count)
{
SG_PWM=1;
}
else
{
SG_PWM=0;
}
}
/*
首先赋值PWM_count=1,然后延时1s,在这一秒内中断系统完全可以循环40次,也就是说在第一个延时期
间count只能是0,则SG_PWM=1只执行一次。TL0 = 0x33;TH0 = 0xFE;赋初值,表示计时500微秒即0.5毫秒,
对应pwm占空比,舵机转0度,等到PWM_count=2时,在第二次延时1秒期间内,cout++执行两次使其加到了1,
SG_PWM=1执行了两次,耗时1ms,舵机转45度。以此类推。
*/
timer0.c
#include <REGX52.H>
/**
* @brief 定时器0初始化,1毫米@11.0592MHz
* @param 无
* @retval 无
*/
void Timer0Init(void) //1毫秒@11.0592MHz
{
TMOD &= 0xF0; //设置定时器模式
TMOD |= 0x01; //设置定时器模式
TL0 = 0x66; //设置定时初始值
TH0 = 0xFC; //设置定时初始值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
ET0=1;
EA=1;
PT0=0;
}
timer0.h
#ifndef __TIMER0_H__
#define __TIMER0_H__
void Timer0Init(void);
#endif
delay.h
#ifndef __DELAY_H__
#define __DELAY_H__
void Delay(unsigned int xms);
#endif
void Delay(unsigned int xms)
{
unsigned char i, j;
while(xms--)
{
i = 2;
j = 239;
do
{
while (--j);
} while (--i);
}
}
若文章内容出现错误,恳请各位批评指正,感激不尽!