避障红外小车C语言程序c51,自动避障红外电动小车C51程序

#include"reg51.h"

#include

#define uchar unsigned char

#define uint  unsigned int

#define left_infrare  0

#define right_infrare 1

#define dj_state1        0X5F      //前进

#define dj_state2        0X4F      //右转

#define dj_state3        0X1F      //左转

#define dj_state4        0X0F      //后退

#define dj_state5        0XfF      //停车

#define light_off        0x0f      //关转向灯

#define left_light       0X5F      //左转向灯    两个是5f

#define right_light      0XaF      //右转向灯0xaf,两个是0xbf

#define back_light       0XcF      //刹车灯即后灯

#define front_light      0x3f      //前灯

#define light_on         0xff      //开所有灯

#define true  1

#define false 0

#define LCD_Data  P0

#define Busy  0x80            //用于检测LCD状态字中的Busy标识

sbit    c=P1^2;              //转向灯使能端

uchar code talk1[]={"backward"};

uchar code talk2[]={"forward"};

uchar code talk3[]={"Turnleft"};

uchar code talk4[]={"Turn right"};

uchar flage =0x00;

sbit  ledcs=P1^2;         //74H573的片选信号

//sbit  left_led=P0^2;     //左红外发射管

//sbit  right_led=P0^3;    //右红外发射管

sbit  LCD_RS = P1^5;     //LCD定义引脚

sbit  LCD_RW = P1^6;     //

sbit  LCD_E  = P1^7 ;

void Delay5Ms(void)

{

uint TempCyc = 5552;

while(TempCyc--);

}

//400ms延时

void Delay400Ms(void)

{uchar TempCycA = 5;

uint TempCycB;

while(TempCycA--)

{ TempCycB=7269;

while(TempCycB--);

}

}

//LCD读状态

unsigned char ReadStatusLCD(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写数据

void WriteDataLCD(unsigned char WDLCD )

{

ReadStatusLCD();  //检测忙

LCD_Data = WDLCD;

LCD_RS=1;

LCD_RW =0;

LCD_E = 0; //若晶振速度太高可以在这后加小的延时

LCD_E = 0; //延时 ,为了安全

LCD_E = 0; //延时

LCD_E = 1;

}

//LCD写指令

void WriteCommandLCD(unsigned char WCLCD,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;

}

void LCDInit(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); // 显示开及光标设置

}

//按指定位置显示一个字符

void DisplayOneChar(uchar X, uchar Y, uchar DData)

{

Y &= 0x1;

X &= 0xF;                 //限制X不能大于15,Y不能大于1

if (Y)

X |= 0x40;               //当要显示第二行时地址码+0x40;

X |= 0x80;               // 算出LCD的指令码

WriteCommandLCD(X, 0);   //这里不检测忙信号,发送地址码

WriteDataLCD(DData);

}

//按指定位置显示一串字符(只能写一行);

void DisplayListChar(uchar X, uchar Y,uchar ListLength, uchar  *DData,uchar n)

{ uchar i;

Y &= 0x01;

X &= 0x0F;                 //限制X不能大于15,Y不能大于1

for(i=0;i

{ if (X <= 0x0F) //X坐标应小于0xF

{   DisplayOneChar(X, Y, DData[i]); //显示单个字符

if(n==true)Delay400Ms();

X++;

}

}

}

/****************************

红外线接收子程序,利用了中断的下降沿触发方式

****************************/

void infrared_ray()interrupt 0  using 3

{  uchar i=90;

flage=0x01;             //接受标志位

while(i--);            //减小灵敏度

EX0=0;               //关掉中断,等到发射方波后才开启,处于别动

}

// 延时子程序

void delay(uint n)

{

while(--n);

}

//中断初始化

void Init0(void)

{  EA=1;

IT0=1;

}

/***************************************

/*原理是把中断打开并 发射方波,

当有中断时就转到中断产生中断位为下一步转向做准备,

当没有是关闭中断

****************************************/

void seng_wave(uchar timer,bit n)//timer通过载波发射信号的时间,n->左右发射管的选择

{  uchar i;

P1 |= 0X04;      //ledcs=1为74ls573为11脚为高电平时数据直接输出,为低时把数据锁存住,即保持

IE |= 0X01;

P0 |=0x0c;   //04

for(i=timer;i>0;i--)

{ if(n)P0^=0x08;                      // 右发射管通过载波发射信号//00

else P0^=0x04;                    // 左发射管通过载波发射信号//0c

delay(100);                     //这里控制着灵敏度(控制38khz的方波的多少)和距离

}                                     //timer*delay(x)即为发射管得到的平均电流

P1 &= 0Xfb;

IE &= 0Xfe;

}

//led转向灯指示子程序

void light_control(uchar deng)

{   ledcs=1;

P0 =deng;

ledcs=0;  //11111011

}

//电机和灯光的控制部分

void  control(uchar n,uchar dj_state,uchar light)

{   uchar i;

// P1|=0x04;

light_control(light);    //led转向指示灯

delay(100);

P2 =dj_state;              //电机的方向控制

WriteCommandLCD(0x01,1); //LCD显示清屏

switch(dj_state)

{ case dj_state2 :{ DisplayListChar(3,1,10,talk4,false);}break;

case dj_state3: { DisplayListChar(3,1,8,talk3,false);}break;

case dj_state4: { DisplayListChar(3,1,7,talk1,false); }break;

default :break;

}

for(i=n;i>0;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);

}

}

/****************************************

避障主要控制部分

*****************************************/

void move_car(void)

{

uchar temp =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;}

……………………

…………限于本文篇幅 余下代码请从51黑下载附件…………

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值