通过单片机的PWM控制SG90舵机运动

 

一.PWM介绍

1.PWM概念

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


2.要点概括


1.2.1:他可以调节脉冲的宽度
1.2.2:通过占空比模拟编码信号
1.2.3:占空比:在一个周期内,高电平占全部周期的百分比

二、实现PWM的方法

1.芯片模块块内部自带的PWM输出,一般可以通过软件手册查询是否支持
2.芯片模块没有自带:可以通过指定的IO端口模拟PWM信号,但是精度相较于芯片自带的比较差

三.如何控制舵机

1.对于舵机而言,一般有三根线,其中两条是电源线,另外一条是PWM信号线,通过给PWM信号线输入信号,使得舵机旋转相应的角度,进而控制舵机
2.其中PWM的频率不能太高,通常情况下,一般为50Hz,也就是0.02s,就是20ms为一个周期

PWM数据转动角度
高电平时间舵机旋转的角度函数对应的占空比
0.5ms0度2.5%占空比250
1.0ms45度5.0%占空比500
1.5ms90度7.5%占空比750
2.0ms135度10.0%占空比1000
2.5ms180度12.5%占空比1250

不同的舵机有可能旋转角度不同,具体的根据舵机手册查询

四.编程实现

1.编程思路:

通过上面的表格可以发现,高电平都是基于0.5ms的,也就是说所有的都是以0.5ms为基础来进行,我们可以通过设定一个0.5ms也就是500微秒的定时器,通过统计定时器的爆表次数来控制PWM信号,比如想让电机旋转90度,那么高电平就是1.5ms,通过定时器爆表3次(1.5ms是0.5ms的3倍),如果定时器爆表次数小于3,则将定义的PWM管脚输出高电平,其余输出低电平,这样就输出一个可以使电机旋转90度的PWM信号。当爆表次数到达40次之后,将计数归零,重新开始计数。

2.程序代码

#include <regx52.h>
#include <intrins.h>    
sbit SG90_PWM = P1^0;
int ctu;
int angle;
void Delay300ms()		//@11.0592MHz
{
	unsigned char i, j, k;

	_nop_();
	i = 3;
	j = 26;
	k = 223;
	do
	{
		do
		{
			while (--k);
		} while (--j);
	} while (--i);
}
void Delay2000ms()		//@11.0592MHz
{
	unsigned char i, j, k;

	_nop_();
	i = 15;
	j = 2;
	k = 235;
	do
	{
		do
		{
			while (--k);
		} while (--j);
	} while (--i);
}
/*定时器初始化函数*/
void Timer0Init(void)		
{
	AUXR &= 0x7F;		
	TMOD &= 0xF0;		
	TMOD |= 0x01;		
	TL0 = 0x33;		
	TH0 = 0xFE;		
	TF0 = 0;		
	TR0 = 1;		
    EA = 1; 
 }
/*主函数调用部分*/       
void main()
{
    Delay300ms();
    Timer0Init(void);
    while(1)
    {
       	angle = 3; 
		ctu = 0;
		Delay2000ms();
		angle = 1; 
		ctu = 0;
		Delay2000ms();
    }
}
void Time0Handler() interrupt 1
{
	ctu++; //每次经过0.5ms,计数值就自动加一
	TL0=0x33;
	TH0=0xFE;
	if( ctu< angle)
         {
		sg90_PWM = 1;
	     }
    else
         {
		sg90_PWM = 0;
	     }
	
	if(ctu == 40)
         { 
		  ctu = 0;   
		  sg90_PWM = 1;
	     }
		
}

3.可能产生的疑问

(1)定义“angle”的意义:定义angle是为了更方便的控制电机旋转的角度,电机控制的角度不在是一个固定值

(2)angle = 3; 
        ctu = 0;
        Delay2000ms();
        angle = 1; 
        ctu = 0;
        Delay2000ms();

以上代码的含义是:给出确定的角度,当电机每次发生一次跳变时,便会将计数值归零一次,防止产生误差

  • 6
    点赞
  • 39
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值