51單片機小車程序,按下按鍵功能實現不靈敏
#include<reg52.h>
#include<intrins.h>
#define uint unsigned int
#define uchar unsigned char
uint time=0;
uint timer=0;
float S=0;
sbit RX=P1^0; //接收端
sbit TX=P1^1; //發送端
sbit jia=P3^6; //角度增加按鍵檢測IO口
sbit jan=P3^7; //角度減少按鍵檢測IO口
sbit jias=P3^3; //角度增加按鍵檢測IO口
sbit jans=P3^4; //角度減少按鍵檢測IO口
uchar jd; //角度標識
uchar jds=0;
uchar count;
sbit pwm=P1^6;
sbit pwm1=P1^2; //PWM信號輸出
sbit pwm2=P1^3;
sbit pwm3=P1^4;
sbit pwm4=P1^5;
bit flag=0;
void counts()
{
time=TH1*256+TL1; //TH0是計數器0的高八位,TL0是計數器0的低八位,
//這個公式就是把高八位向左移八位加上低八位組成一個16的數值,也就是計數值,在賦值給tim
TH1=0;
TL1=0;
S=(time*1.87)/100; //時鐘周期位T0=11.0592M,機器周期為T1=1/11.0592*12us=1.08us定時器計時time1,
//實際為t=time1*1.08,此為聲波往返時間,距離要除以2,取聲速346m/s,
//S=v*t=346*time*T1/2/1000000m'=1.868*time1/100cm得S約等于time1*1.87/100cm
if(S<5)
jds=0;
}
void delay0(uint i)
{
while(i--);
}
void keyscan0() //按鍵掃描
{
if(jias==0) //角度增加按鍵是否按下
{
delay0(10); //按下延時,消抖
if(jias==0) //確實按下
{
jds=jds+10;
if(jds>200)
jds=200;
while(jias==0); //等待按鍵放開
}
}
if(jans==0) //角度減小按鍵是否按下
{
delay0(10);
if(jans==0)
{
jds=jds-10;
if(jds<10)
jds=0; //已經是0度,則保持
while(jans==0);
}
}
}
void keyscan() //按鍵掃描
{
if(jia==0) //角度增加按鍵是否按下
{
delay0(10); //按下延時,消抖
if(jia==0) //確實按下
{
jd++; //角度標識加1
count=0; //按鍵按下 則20ms周期從新開始
if(jd==26)
jd=25; //已經是180度,則保持
while(jia==0); //等待按鍵放開
}
}
if(jan==0) //角度減小按鍵是否按下
{
delay0(10);
if(jan==0)
{
jd--; //角度標識減1
count=0;
if(jd==4)
jd=5; //已經是0度,則保持
while(jan==0);
}
}
}
void delay(uint i)
{
while(i--)
{
if(jia==0||jan==0)
keyscan();
if(jias==0||jans==0)
keyscan0();
}
}
void StartModule() //延時,超聲波模塊Trig控制端給大于10us的高電平觸發模塊測距
{ //模塊就會自動發送 8 個 40khz 的方波,自動檢測是否有信號返回;
//操作簡單方便;假如有信號返回,超聲波模塊就會通過 IO(Echo(接收端)) 輸出一高電平,
//高電平持續的時間就是超聲波從發射到返回的時間.那么測試距離=(高電平時間*聲速(340M/S))/2;
TX=1;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
TX=0;
}
void main()
{
TMOD=0x11;
TH1=0;
TL1=0;
TH0=(65536-92)/256;
TL0=(65536-92)%256; //11.0592MZ晶振,0.1ms
ET0=1;
ET1=1;
TR0=1;
EA=1;
while(1)
{
StartModule();
while(!RX);
TR1=1; //開定時器位 (Echo(接收端)高電平持續的時間就是超聲波從發射到返回的時間.
//所以等待高電平的時間,就是定時器計時的時間。(while(RX));在等待然后關閉定時器,通過算法就能計數了。
while(RX);
TR1=0; //關定時器
counts(); //計數
delay(65535);
keyscan(); //按鍵掃描
keyscan0();
}
}
void Time0_Int() interrupt 1 //中斷程序
{
TH0 = (65536-92)/256; //重新賦值
TL0 = (65536-92)%256;
if(count< jd) //判斷0.1ms次數是否小于角度標識
pwm=1; //確實小于,PWM輸出高電平
else
pwm=0; //大于則輸出低電平
if(count<jds)
{
pwm1=1;
pwm2=0;
pwm3=1;
pwm4=0;
}
else
{
pwm1=0;
pwm2=0;
pwm3=0;
pwm4=0;
}
count++; //0.1ms次數加1
if(count==200)
count=0; //次數始終保持為200 即保持周期為20ms
}
|