不想写文章,只放代码自己拷。
#include <REGX52.H>
#define SG90_PORT P1_0 //端口
//获取位值
#define GET_BIT_H(BIT) (BIT>>8)
#define GET_BIT_L(BIT) (BIT&0xFF)
//计算定时器值
#define GET_VAL(US, FREQ) (65535-(unsigned short)(US*FREQ/12)) //计算定时器计数值
//电平标志
#define LEVEL_HIGH 1
#define LEVEL_LOW 0
unsigned short high_level;
unsigned short low_level;
void sg90_init(int ang)
{
//周期20ms
int us = (int)((float)ang/180.0*2000+500); //计算计时频率
high_level = GET_VAL(11.0592, us); //计算pwm高电平
low_level = GET_VAL(11.0592, 20000-us); //计算pwm低电平
SG90_PORT = LEVEL_HIGH;
T2MOD = 0;
T2CON = 0;
TH2 = GET_BIT_H(low_level);
TL2 = GET_BIT_L(low_level);
ET2 = 1;
EA = 1;
PT2 = 0;
TR2 = 1;
}
void sg90_set(int ang)
{
int us = (int)((float)ang/180.0*2000+500); //计算计时频率
high_level = GET_VAL(11.0592, us); //计算pwm高电平
low_level = GET_VAL(11.0592, 20000-us); //计算pwm低电平
//电平为高
SG90_PORT = LEVEL_HIGH;
//更新定时器计数
RCAP2H = GET_BIT_H(low_level);
RCAP2L = GET_BIT_L(low_level);
}
void sg90_contrl_handler(void) interrupt 5
{
if (SG90_PORT == LEVEL_HIGH)
{
//设置端口电平
SG90_PORT = LEVEL_LOW;
//更新定时器值
RCAP2H = GET_BIT_H(high_level);
RCAP2L = GET_BIT_L(high_level);
}
else
{
//设置端口电平
SG90_PORT = LEVEL_HIGH;
//更新定时器值
RCAP2H = GET_BIT_H(low_level);
RCAP2L = GET_BIT_L(low_level);
}
//清除标志位
TF2 = 0;
}