对于一般的舵机来说,所对应的PWM波的周期为20ms。
其空占比与转动角度的关系。普通舵机的舵量是0~180°
0.5ms/20 ms = 0 度
1.0ms/20ms = 45 度
1.5ms/20ms = 90 度
2.0ms/20ms = 135 度
2.5ms/20ms = 180 度
本文代码中使用的晶振是12Mhz。我是使用定时器方式2,自动填装初值才能够使周期控制在50hz,刚开始使用的是方式1,使用示波器检测是52hz。不知道是为什么,不过还好问题解决了,本代码很稳。
-------------------------------------------------------------------------------------------*/
#include<reg52.h>
#define uint unsigned int
sbit key1 = P3^2; //减
sbit key2 = P3^3; //加
sbit pwm1 = P2^0;
uint target = 15;
uint percent = 0;
void Timer0Initial(); //定时器0装初值
void initial_Timer(); //定时器初始化
void delay(unsigned int x); //延时
void keyscan(); //键盘扫描
void keyscan()
{
delay(30); //缓冲舵机速度
if(key1 == 0) //减
{
delay(10); //消抖
if(key1 == 0)
{
if(target >= 5)
target -= 1;
while (key1 ==0);
}
}
// while (key1 != 1);
if(key2 == 0) //加
{
delay(10);
if(key2 == 0)
{
if(target < 25)
target += 1;
while (key2 ==0);
}
}
// while (key2 != 1);
}
void initial() //键盘、定时器初始化
{
key1 = 1;
key2 = 1;
initial_Timer();
}
void Timer0Initial() //定时器0装初值
{
// TH0 = (65536-65)/256; //该初值使每0.1ms产生一次中断.理论上,12Mhz晶振12分频之后,应该是100次计数时间是100us
// TL0 = (65536-65)%256; //通过示波器实测
TH0 = 0x9C; //选用65次计数产生一次中断
TL0 = 0x9C;
}
void initial_Timer() //定时器初始化
{
EA = 1; //开总中断--学校总闸
ET0 = 1; //开定时器0中断--光电楼总闸
TMOD = 0x02; //设置定时器0为工作方式
Timer0Initial(); //装初值
TR0 = 1; //启动定时器0--N707B总闸
}
void delay(unsigned int x) //延时
{
uint i,j;
for(i=x;i>0;i--)
for(j=110;j>0;j--);
}
void main()
{
initial(); //键盘、定时器初始化
while(1) //不断扫描键盘
{
keyscan();
}
}
void Timer0() interrupt 1 //中断服务程序
{
percent+=1;
if(percent<=target) //target初值是15,接电时居中
pwm1=1;
else
pwm1=0;
if(percent==200)
percent=0;
}