#include<reg52.h>
#include <math.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
sbit P10 = P1^0;
sbit P11 = P1^1; // 1號電機 右前輪
sbit P12 = P1^2;
sbit P13 = P3^2; // 2號電機 左前輪
sbit P14 = P1^4;
sbit P15 = P1^5; // 3號電機 左后輪
sbit P16 = P1^6;
sbit P17 = P1^7; // 4號電機 右后輪
sbit P20=P2^0;
sbit P21=P2^1; //風扇
sbit P26=P2^6; //噪聲
sbit P35=P3^5; //光敏
sbit TRIG = P3^6; // 控制端
sbit ECHO = P3^7; // 接收端
sbit a = P0^0; // 避障 前右
sbit b = P0^1; // 避障 前左
sbit c = P0^2; // 避障 后右
sbit d = P0^3; // 避障 后左
sbit f = P0^4; // 循跡 前右
sbit g = P0^5; // 循跡 前左
sbit h = P0^6; // 循跡 后右
sbit i = P0^7; // 循跡 后左
sbit PWM1=P2^2;
sbit PWM2=P2^3;
sbit PWM3=P2^4;
sbit PWM4=P2^5; //控制四個輪速度 需要用到定時器 在本程序中沒有設置
sbit Beep=P1^3; //蜂鳴器
uchar e;
uchar n,angle,count; //距離標志位,0.5ms次數,角度標識
float S; //距離變量
void delay()
{
uchar a;
for(a=450;a>0;a--)
{
_nop_();
}
}
void DelayUs2x(uchar t)
{
while(--t);
}
void DelayMs(uchar t)
{
while(t--)
{
DelayUs2x(245);
DelayUs2x(245);
}
} //大致延時1mS
void Time(void)
{
TMOD|=0x21; /*TMOD有高八位與第八位 GATE=0, C/T=0(定時器模式), |=位操作寫法,強制賦值
定時器1工作方式2(8位自動重裝定時器) (藍牙),
定時器0(16位定時器)超聲波 */
TH0=0x00; //定時器0 高八位的初值
TL0=0x00; //低八位的初值 定時最大的值65.536ms
SCON=0x50; //0101 0000 SM0=0 SM1=1 (10位異步收發器(8位數據)) SM2=0(多機通訊位) REN=1(串行接受允許位) 串口方式1 SM0 SM1 01 允許接收
PCON=0x00; /*PCON沒有位尋址的,不能直接操作 SMOD=0 16分頻 波特率不加倍
波特率=(2*SMOD)/32*定時器1的溢出率
定時器1的溢出率=單片機內的時鐘頻率/(256-X) X是定時器的初值
因此 波特率=(2*SMOD)/32*(單片機內部的時鐘頻率/(256-X)) */
TH1=0xFd;
TL1=0xFd; /*11.0592晶振 9600波特率
在串行通信時,T1定時器是用作波特率發生器的,且為方式2,這樣,TL1是作為8位計數器的,
而TH1是作為時間常數的寄存器的,可以實現TL1計數回0時自動重裝時間常數,即將TH1中的數自動送給TL1,再次計數。
TH1,TL1是單片機的16位定時器T1,只有給TH1,TL1賦值,定時器就開始計數,才能控制串行通信的波特率,而這值是根據需要的波特率計算出來的。*/
TR1=1; //打開定時器1
IE=0x92; //IE中斷允許寄存器 1001 1010 即EA=1(打開總中斷) ES=1(打開串口中斷) ET1=1(打開定時器1源中斷) ET0=1(打開定時器0源中斷)
}
void csb()
{
TRIG=1; //觸發信號是高電平脈沖,寬度大于10us
DelayUs2x(10);
TRIG=0;
while(!ECHO); //等待高電平
TR0=1; //T0開始運行
while(ECHO); //等待低電平
TR0=0; //T0關閉
S=TH0*256+TL0; //取出定時器值高8位和低8位合并
S=S/58; //為什么除以58等于厘米, Y米=(X秒*344)/2
// X秒=( 2*Y米)/344 -> X秒=0.0058*Y米 -> 厘米=微秒/58
if(S>=40)
{
n=1; //距離大于40cm 標記
}
if(S<40)
{
n=0; //距離小于40 標記
}
TH0=0;
TL0=0; //清除定時器0寄存器中的值
}
void FMQ()
{
uint n;
for(n=1;n<20;n++)
{
uint m;
for(m=800;m>0;m--)
{
Beep=~Beep;
delay();
}
for(m=500;m>0;m--)
{
Beep=~Beep;
delay();
delay();
}
}
}
void fsz()
{
P20=0;
P21=1;
}
void fsf()
{
P20=1;
P21=0;
}
void fst()
{
P20=0;
P21=0;
}
void run(void) // 前進
{
P10 =1;
P11 =0;
P12 =1;
P13 =0;
P14 =1;
P15 =0;
P16 =1;
P17 =0;
}
void backrun(void) // 后退
{
P10 =0;
P11 =1;
P12 =0;
P13 =1;
P14 =0;
P15 =1;
P16 =0;
P17 =1;
}
void stop(void) // 停止
{
P10 =0;
P11 =0;
P12 =0;
P13 =0;
P14 =0;
P15 =0;
P16 =0;
P17 =0;
}
void leftrun(void) // 左轉
{
P10 =1;
P11 =0;
P12 =0;
P13 =1;
P14 =0;
P15 =1;
P16 =1;
P17 =0;
}
void rightrun(void) // 右轉
{
P10 =0;
P11 =1;
P12 =1;
P13 =0;
P14 =1;
P15 =0;
P16 =0;
P17 =1;
}
void main(void)
{
Time(); //初始化定時器
while(1)
{
if(e=='2')
{
run();
while((a==1)&&(b==0)) //前左側遇到障礙物右拐
{
rightrun();
DelayMs(200);
}
while((a==0)&&(b==1)) //前右側遇到障礙物左拐
{
leftrun();
DelayMs(200);
}
while((a==0)&&(b==0)) //兩邊同時遇到障礙物左拐
{
stop();
DelayMs(5000);
}
while((c==1)&&(d==0)) //后右側遇到障礙物右拐
{
rightrun();
DelayMs(200);
}
while((c==0)&&(d==1)) //后右側遇到障礙物左拐
{
leftrun();
DelayMs(200);
}
while((f==1)&&(g==0)) //左邊遇到白右轉 1黑0白
{
rightrun();
DelayMs(170);
}
while((f==0)&&(g==1)) //右邊遇到白左轉
{
leftrun();
DelayMs(170);
}
while((h==0)&&(i==1)) //右邊遇到白左轉
{
leftrun();
DelayMs(170);
}
while((h==1)&&(i==0)) //左邊遇到白右轉
{
rightrun();
DelayMs(170);
}
} //按鍵2 前進(帶避障)
else if(e=='4') leftrun(); //按鍵4 向左轉
else if(e=='6') rightrun(); //按鍵6 向右轉
else if(e=='8')
{
backrun();
while((a==1)&&(b==0)) //前左側遇到障礙物右拐
{
rightrun();
DelayMs(200);
}
while((a==0)&&(b==1)) //前右側遇到障礙物左拐
{
leftrun();
DelayMs(200);
}
while((a==0)&&(b==0)) //兩邊同時遇到障礙物左拐
{
stop();
DelayMs(5000);
}
while((c==1)&&(d==0)) //后右側遇到障礙物右拐
{
rightrun();
DelayMs(200);
}
while((c==0)&&(d==1)) //后右側遇到障礙物左拐
{
leftrun();
DelayMs(200);
}
} //按鍵8 后退(帶避障)
else if(e=='1')
{
FMQ();
DelayMs(100); //按鍵1 蜂鳴器
}
else if(e=='A') run(); //向上箭頭 僅前進
else if(e=='B') backrun(); //向下箭頭 僅后退
else if(e=='C') leftrun(); //向左箭頭 僅左轉
else if(e=='D') rightrun(); //向右箭頭 僅右轉
else if(e=='7') fsz();
else if(e=='9') fsf();
else if(e=='5') fst();
else stop();
if(P26==0) FMQ();
else Beep=0;
}
}
void serial() interrupt 4
{
RI=0; //接受中斷位 必須由軟件置0 硬件置1
e=SBUF; //接受緩沖器SBUF賦值給e
}
void Time0_0(void) interrupt 1 //定時器中斷 (void)是必須的
{
ECHO=0;
}
|