自动避障红外电动小车C51程序#includereg51.h#includeintrins.h#defineucharunsignedchar#defineuintunsignedint#defineleft_infrare0#defineright_infrare1#definedj_state10X5F//前进#definedj_state20X4F//右转#definedj_state30X1F//左转#definedj_state40X0F//后退#definedj_state50XfF//停车#definelight_off0x0f//关转向灯#defineleft_light0X5F//左转向灯两个是5f#defineright_light0XaF//右转向灯0xaf,两个是0xbf#defineback_light0XcF//刹车灯即后灯#definefront_light0x3f//前灯#definelight_on0xff//开所有灯#definetrue1#definefalse0#defineLCD_DataP0#defineBusy0x80//用于检测LCD状态字中的Busy标识sbitc=P1^2;//转向灯使能端ucharcodetalk1[]={backward};ucharcodetalk2[]={forward};ucharcodetalk3[]={Turnleft};ucharcodetalk4[]={Turnright};ucharflage=0x00;sbitledcs=P1^2;//74H573的片选信号//sbitleft_led=P0^2;//左红外发射管//sbitright_led=P0^3;//右红外发射管sbitLCD_RS=P1^5;//LCD定义引脚sbitLCD_RW=P1^6;//sbitLCD_E=P1^7;voidDelay5Ms(void){uintTempCyc=5552;while(TempCyc--);}//400ms延时voidDelay400Ms(void){ucharTempCycA=5;uintTempCycB;while(TempCycA--){TempCycB=7269;while(TempCycB--);}}//LCD读状态unsignedcharReadStatusLCD(void){LCD_Data=0xFF;LCD_RS=0;LCD_RW=1;LCD_E=0;LCD_E=0;LCD_E=1;while(LCD_Data&Busy);//检测忙信号return(LCD_Data);}//LCD写数据voidWriteDataLCD(unsignedcharWDLCD){ReadStatusLCD();//检测忙LCD_Data=WDLCD;LCD_RS=1;LCD_RW=0;LCD_E=0;//若晶振速度太高可以在这后加小的延时LCD_E=0;//延时,为了安全LCD_E=0;//延时LCD_E=1;}//LCD写指令voidWriteCommandLCD(unsignedcharWCLCD,BuysC){if(BuysC)ReadStatusLCD();//根据需要检测忙,BuysC为0时忽略忙检测LCD_Data=WCLCD;LCD_RS=0;LCD_RW=0;LCD_E=0;//延时,为了安全LCD_E=0;LCD_E=0;//延时LCD_E=1;}voidLCDInit(void)//LCD初始化{Delay400Ms();LCD_Data=0;WriteCommandLCD(0x38,0);//三次显示模式设置,不检测忙信号Delay5Ms();WriteCommandLCD(0x38,0);Delay5Ms();WriteCommandLCD(0x38,0);Delay5Ms();WriteCommandLCD(0x38,1);//显示模式设置,开始要求每次检测忙信号WriteCommandLCD(0x08,1);//关闭显示WriteCommandLCD(0x01,1);//显示清屏WriteCommandLCD(0x06,1);//显示光标移动设置WriteCommandLCD(0x0C,1);//显示开及光标设置}//按指定位置显示一个字符voidDisplayOneChar(ucharX,ucharY,ucharDData){Y&=0x1;X&=0xF;//限制X不能大于15,Y不能大于1if(Y)X|=0x40;//当要显示第二行时地址码+0x40;X|=0x80;//算出LCD的指令码WriteCommandLCD(X,0);//这里不检测忙信号,发送地址码WriteDataLCD(DData);}//按指定位置显示一串字符(只能写一行);voidDisplayListChar(ucharX,ucharY,ucharListLength,uchar*DData,ucharn){uchari;Y&=0x01;X&=0x0F;//限制X不能大于15,Y不能大于1for(i=0;iListLength;i++){if(X=0x0F)//X坐标应小于0xF{DisplayOneChar(X,Y,DData[i]);//显示单个字符if(n==true)Delay400Ms();X++;}}}/****************************红外线接收子程序,利用了中断的下降沿触发方式****************************/voidinfrared_ray()interrupt0using3{uchari=90;flage=0x01;//接受标志位while(i--);//减小灵敏度EX0=0;//关掉中断,等到发射方波后才开启,处于别动}//延时子程序voiddelay(uintn){while(--n);}//中断初始化voidInit0(void){EA=1;IT0=1;}/***************************************/*原理是把中断打开并发射方波,当有中断时就转到中断产生中断位为下一步转向做准备,当没有是关闭中断****************************************/voidseng_wave(uchartimer,bitn)//timer通过载波发射信号的时间,n-左右发射管的选择{uchari;P1|=0X04;//ledcs=1为74ls573为11脚为高电平时数据直接输出,为低时把数据锁存住,即保持IE|=0X01;P0|=0x0c;//04for(i=timer;i0;i--){if(n)P0^=0x08;//右发射管通过载波发射信号//00elseP0^=0x04;//左发射管通过载波发射信号//0cdelay(100);//这里控制着灵敏度(控制38khz的方波的多少)和距离}//timer*delay(x)即为发射管得到的平均电流P1&=0Xfb;IE&=0Xfe;}//led转向灯指示子程序voidlight_control(uchardeng){ledcs=1;P0=deng;ledcs=0;//11111011}//电机和灯光的控制部分voidcontrol(ucharn,uchardj_state,ucharlight){uchari;//P1|=0x04;light_control(light);//led转向指示灯delay(100);P2=dj_state;//电机的方向控制WriteCommandLCD(0x01,1);//LCD显示清屏switch(dj_state){casedj_state2:{DisplayListChar(3,1,10,talk4,false);}break;casedj_state3:{DisplayListChar(3,1,8,talk3,false);}break;casedj_state4:{DisplayListChar(3,1,7,talk1,false);}break;default:break;}for(i=n;i0;i--){delay(2000);}P2=dj_state5;//停车light_control(light_off);//led关闭WriteCommandLCD(0x01,1);//LCD显示清屏P2=dj_state1;//前进if(dj_state1){P1|=0X04;//ledcs=1;P0=0x0f;P1&=0XFB;delay(100);DisplayListChar(0,0,7,talk2,false);}}/****************************************避障主要控制部分*****************************************/voidmove_car(void){uchartemp=0x00;//左边红外管发射seng_wave(1,left_infrare);//向下为中断开启有关闭后,要执行的语句if(flage==0x01){temp|=0x01;flage=0x00;}//右边红外管发射delay(30);seng_wave(1,right_infrare);//向下为中断开启有关闭后,要执行的语句if(flage==0x01){temp|=0x02;flage=0x00;}//左边有障碍物,右转if(temp==0x01){control(2,dj_state2,left_light);temp=0x00;}//右边有障碍物,左转elseif(temp==0x02){control(2,dj_state3,right_light);temp=0x00;}//两个方向都有障碍物,后退,右转elseif(temp==0x03){control(10,dj_state4,back_light);control(5,dj_state2,right_light);temp=0x00;}}voidmain(void){Init0();//中断初始化P1|=0X04;//开锁存器的控制位P0=0xFf;//数据口的清零P1&=0XFB;//关锁存器的控制位LCDInit();//LCD初始化WriteCommandLCD(0x01,1);//显示清屏delay(100);P2=dj_state1;DisplayListChar(0,0,8,talk2,false);while(1){move_car();//主要控制部分delay(200000);//延时}}