我想通過51單片機控制舵機,通過一個開關(guān)與一個距離傳感器控制舵機角度。程序運行后,pwm正常輸出,但是經(jīng)過幾次角度改變后,pwm就無法產(chǎn)生了。請教一下是什么原因,下面是源代碼,希望大家多多指教,多謝了!
#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) //長延時函數(shù),ms級,不準確
{
unsigned int j,k;
for(j=i;j>0;j--)
for(k=125;k>0;k--);
}
void delay() //短延時函數(shù),us級,相對精確,本函數(shù)為延時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() //兩個計數(shù)器與定時器的初始化
{
TMOD = 0x11; //Time1工作模式1,Time0工作模式1
TH0 = 0xfe;
TL0 = 0x33; //設(shè)置time0計數(shù)初值,定時0.5ms
TH1 = 0;
TL1 = 0; //設(shè)置time1計數(shù)初值,等待觸發(fā)
TR0 = 1; //Time0開始計數(shù)
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計時的次數(shù)
pwm = 1; //PWM輸出高電平,控制占空比
else
pwm = 0; //PWM輸出低電平,控制占空比
count = (count + 1); //控制脈沖周期為20ms
count = count%41;
WDT_CONTR = 0x35; //目前解決定時中斷無法進入的方法是添加看門狗,此行為喂狗
}
void keyscan() //微動開關(guān)與虛擬開關(guān)按鍵處理(微動開關(guān),按下置0,松開置1)
{
if(D_SW == 0) //如果超聲檢測到有物體
{
delay1(50);
if(D_SW == 0)
{
jd = 1; //高電平0.5ms,舵機角度為-90
led = 1;
}
}
else if(S_SW == 0) //微動開關(guān)觸發(fā),檢測到有物體
{
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; //開啟計數(shù)
while(RX); //當RX為1計數(shù)并等待
TR1 = 0; //關(guān)閉計數(shù)
sw = Distence(); //計算
if(sw >= 20)
D_SW = 1;
else
D_SW = 0;
keyscan();
}
}
|