标题:
oh yeah···单片机智能小何程序完成了
[打印本页]
作者:
daming
时间:
2014-12-29 01:12
标题:
oh yeah···单片机智能小何程序完成了
#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;
}
}
//到这里就写完啦···整体的硬件还没做出来,但是分开的我都做过一次了,程序都没问题···哈哈,整体作出来后再测试吧,哈哈···
复制代码
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1