|
- #include<reg52.h>
- #include<stdio.h> //标准输入输出
- #include<intrins.h> //
- sbit left1=P1^0; //左边1电机转
- sbit right1=P1^1; //右边1电机转
- sbit left2=P1^6; //左边2电机转
- sbit right2=P1^7; //右边2电机转
- sbit cleft0=P1^2; //左边第一号红外检测
- sbit cleft1=P1^3; //左边第二号红外检测
- sbit cright0=P1^4; //右边第一号红外检测
- sbit cright1=P1^5; //右边第二号红外检测
- sbit key=P3^2; //外部按键
- sbit rs=P0^5; //数据/命令控制位
- sbit rw=P0^6; //读写控制位
- sbit enable=P0^7; //使能控制位
- sbit xl=P3^0; //寻线左红外
- sbit xr=P3^1; //寻线右红外
- sbit TX =P3^6; //超声波信号发送端
- sbit RX =P3^7; //超声波信号接收端
- #define date P2 //用于LCD数据输出
- char data test1[]=" "; //第一行显示table
- char data test2[]=" "; //第二行显示table
- unsigned char wflag; //工作位标志,包括避障,寻线,超声波探测
- unsigned long S; //超声波测试距离
- unsigned int time; //超声波高电平时间
- unsigned char qian,bai,shi,ge; //千百十个位
- void delay(int i) //不精确延时
- {
- while(i--);
- }
- unsigned char test() //小车正向避障监测子程序
- {
- unsigned char k;
- if((cleft0&&cleft1&&cright0&&cright1)==1)
- {
- k=1; //小车前面完全没有障碍物标志为1
- }
- if((cleft0&&cleft1)==0)
- {
- k=2; //左边有障碍物时标志为2
- }
- if((cright0&&cright1)==1)
- {
- k=3; //右边有障碍物时标志为3
- }
- return k;
- }
- unsigned char test3() //寻线红外检测子程序
- {
- unsigned char p;
- if((xl&&xr)==1)
- {
- p=1; //此标志显示小车可向前移动
- }
- if((xl=1)&&(xr=0))
- {
- p=2; //小车右边碰到黑线,小车需纠正位置
- }
- if((xl=0)&&(xr=1))
- {
- p=3; //小车左边碰到黑线,小车需要纠正位置
- }
- if((xl=0)&&(xr=0))
- {
- p=4; //小车全部碰到黑线,倒车
- }
- return p;
- }
- void zhengxiang() //正向
- {
- delay(500);
- right1=1;
- right2=0;
- left1=1;
- left2=0;
- delay(500); //全部置零 停止小车,减速
- right1=0;
- right2=0;
- left1=0;
- left2=0;
- delay(2000);
- }
- void youxiang() //右向
- {
- delay(500);
- right1=0;
- right2=0;
- left1=1;
- left2=0;
- delay(500); //全部置零 停止小车,减速
- right1=0;
- right2=0;
- left1=0;
- left2=0;
- delay(2000);
- }
- void zuoxiang() //左向
- {
- delay(500);
- right1=1;
- right2=0;
- left1=0;
- left2=0;
- delay(500); //全部置零 停止小车,减速
- right1=0;
- right2=0;
- left1=0;
- left2=0;
- delay(2000);
- }
- void daoche() //倒车
- {
- delay(500);
- right1=0;
- right2=1;
- left1=0;
- left2=1;
- delay(500); //全部置零 停止小车,减速
- right1=0;
- right2=0;
- left1=0;
- left2=0;
- delay(2000);
- }
-
- void bizhang() //避障子程序
- {
- unsigned char flag; //障碍标志位
- test(); //运行监测
- flag=test();
- if(flag==1) //判断处理
- {
- zhengxiang();
- }
- if(flag==2)
- {
- zuoxiang();
- }
- if(flag==3)
- {
- youxiang();
- }
- }
- void xunxian()
- {
- unsigned char flag;
- test3();
- flag=test3();
- if(flag==1)
- {
- zhengxiang();
- }
- if(flag==2)
- {
- zuoxiang();
- }
- if(flag==3)
- {
- youxiang();
- }
- if(flag==4)
- {
- daoche();
- }
- }
- void delayms(int x) //粗略的MS延时
- {
- while(x--)
- {
- delay(500); //调用US延时
- delay(500);
- delay(500);
- }
- }
-
- void write_com(unsigned char c) //LCD液晶写命令
- {
- delayms(5); //这一部分请参考1602C型号的LCD使用手册
- enable=0;
- rs=0;
- rw=0;
- _nop_();
- _nop_();
- enable=1;
- _nop_();
- date=c;
- _nop_();
- enable=0;
- }
- void write_date(unsigned char s) //LCD写数据命令
- {
- delayms(5); //这一部分请参考1602C型号的LCD使用手册
- enable=0;
- rs=1;
- rw=0;
- _nop_();
- enable=1;
- _nop_();
- date=s;
- _nop_();
- enable=0;
- }
- void init() //LCD初始指令
- {
- delayms(15);
- write_com(0x38); //0XXX为命令指令,请参考1602C型号LCD的使用手册
- write_com(0x38);
- write_com(0x38);
- write_com(0x0f);
- write_com(0x06);
- write_com(0x01); //显示清屏
- write_com(0x80); //数据起始书写地址
- }
-
- void showjie(unsigned char pos,unsigned char c) //写入一个字节的数据
- {
- unsigned char p;
- if(pos>=0x10)
- p=pos+0xb0;
- else
- p=pos+0x80;
- write_com(p);
- write_date(c);
- }
- void showchuan(unsigned char line,char *ptr) //写入一个字符串的数据并包含行数
- {
- unsigned char l,o;
- l=line<<4;
- for (o=0;o<16;o++)
- showjie(l++,*(ptr+o));
- }
- void sent() //定义一个发送
- {
- TX=1; //发送端发送信号
- delay(25); //给一个大于10US的信号
- TX=0; //关闭发送端信号
- }
- void Count()
- {
- time=TH0*256+TL0; //计算时间
- TH0=0; //复位
- TL0=0; //复位
- S=(time*1.7)/10; //计算距离,单位MM
- if(S<5000)
- {
- qian=S/1000; //定义第四位
- bai=S/100%10; //定义第三位
- shi=S/10%10; //定义第二位
- ge=S%10; //定义第一位
- test2[5]=(qian+48);
- test2[6]=(bai+48);
- test2[7]=(shi+48);
- test2[8]=(ge+48);
- showchuan(1,test2);
- }
- }
- void receive() //定义一个接收
- {
- TR0=1; //定时器0开
- while(RX); //持续延时RX为高电平的时间
- TR0=0; //定时器0关
- Count(); //调用Count
- }
- void welcome() //起始LCD欢迎词
- {
- delayms(20);
- init(); //初始化LCD
- delayms(20);
- sprintf(test1,"welcome to robot"); //调用sprintf
- showchuan(0,test1); //using showchuan
- sprintf(test2," by jack "); //using sprintf
- showchuan(1,test2); //using showchuan
- while(1);
- }
- void chaoshengbo() //超声波子程序
- {
- int lv;
- delayms(20);
- init();
- delayms(20);
- sprintf(test1,"the distance is ");
- showchuan(0,test1);
- for(lv=1000;lv>0;lv--)
- {
- RX=1; //给RX一个高电平
- sent(); //给发送端一个>10us的信号
- if(RX==1)
- {
- receive(); //调用RECEIVE
- }
- }
- }
- void main()
- {
- EA=1; //中断打开
- EX0=1; //外部中断打开
- IT0=0; //外部中断低电平有效
- ET0=1; //定时器中断0开
- ET1=1; //定时器中断1开
- TMOD=0X11; //定义TO,T1由TCON控制,工作方式为方式1
- TH0=0;
- TL0=0;
- TH1=0;
- TL1=0;
- while(wflag==0) //LCD欢迎界面
- {
- welcom();
- }
- while(wflag==1) //避障模式
- {
- bizhang();
- }
- while(wflag==2) //寻线模式
- {
- xunxian();
- }
- while(wflag==3)
- {
- chaoshengbo();
- }
-
- }
- void ISR_KEY(void) interrupt 1 using 1 //外部中断函数 控制工作标志位的改变 切换工作状态
- {
- delay(500);
- if(!key)
- {
- wflag++;
- if(wflag==4)
- wflag=0;
- }
- }
-
- //到这里就写完啦···整体的硬件还没做出来,但是分开的我都做过一次了,程序都没问题···哈哈,整体作出来后再测试吧,哈哈···
复制代码
|
|