我想通过51单片机控制舵机,通过一个开关与一个距离传感器控制舵机角度。程序运行后,pwm正常输出,但是经过几次角度改变后,pwm就无法产生了。请教一下是什么原因,下面是源代码,希望大家多多指教,多谢了!
#include "reg51.h"
#include "intrins.h"
#define uint unsigned int;
#define lint long int;
uint jd , count , time;
lint S;
void delay1(unsigned int i) //长延时函数,ms级,不准确
{
unsigned int j,k;
for(j=i;j>0;j--)
for(k=125;k>0;k--);
}
void delay() //短延时函数,us级,相对精确,本函数为延时21us
{
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
}
void Time_init() //两个计数器与定时器的初始化
{
TMOD = 0x11; //Time1工作模式1,Time0工作模式1
TH0 = 0xfe;
TL0 = 0x33; //设置time0计数初值,定时0.5ms
TH1 = 0;
TL1 = 0; //设置time1计数初值,等待触发
TR0 = 1; //Time0开始计数
ET0 = 1; //打开Time0的中断
ET1 = 1; //打开Time1的中断
EA = 1; //开启总中断
}
long Distence()
{
time = TH1*256+TL1;
TH1 = 0;
TL1 = 0;
S = (long)(time*0.017); //算出来是cm
return S;
//if(S >= 20)
// return 0;
//else
// return 1;
}
void Time0_Int() interrupt 1 //定时器0的中断服务程序
{
TH0 = 0xfe; //定时器重填,重新计时
TL0 = 0x33;
if(count < jd) //判断0.5ms计时的次数
pwm = 1; //PWM输出高电平,控制占空比
else
pwm = 0; //PWM输出低电平,控制占空比
count = (count + 1); //控制脉冲周期为20ms
count = count%41;
WDT_CONTR = 0x35; //目前解决定时中断无法进入的方法是添加看门狗,此行为喂狗
}
void keyscan() //微动开关与虚拟开关按键处理(微动开关,按下置0,松开置1)
{
if(D_SW == 0) //如果超声检测到有物体
{
delay1(50);
if(D_SW == 0)
{
jd = 1; //高电平0.5ms,舵机角度为-90
led = 1;
}
}
else if(S_SW == 0) //微动开关触发,检测到有物体
{
delay1(20);
if(S_SW == 0)
{
jd = 3; //高电平1.5ms,舵机角度0
led = 0;
}
}
else
{
jd = 1;
led = 1;
}
}
void main()
{
long sw = 0; //变量初始化
jd = 1;
count = 0;
time = 0;
S = 0;
Time_init(); //定时器初始化
WDT_CONTR = 0x35; //看门狗初始化
while(1)
{
TR0 = 1;
ET0 = 1;
TX = 1;
delay();
TX = 0; //使能超声波模块
while(!RX); //当RX为零时等待
TR1 = 1; //开启计数
while(RX); //当RX为1计数并等待
TR1 = 0; //关闭计数
sw = Distence(); //计算
if(sw >= 20)
D_SW = 1;
else
D_SW = 0;
keyscan();
}
}
|