#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;
}
|