#include <REGX52.H>
#include <intrins.h>
#include <QXA51.H>sbit DU = P2^6;//数码管段选
sbit RX = P2^0;//ECHO超声波模块回响端
sbit TX = P2^1;//TRIG超声波模块触发端
sbit LCM_RW = P3^6;     //定义LCD引脚
sbit LCM_RS = P3^5;
sbit LCM_E = P3^4;
#define LCM_Data  P0   //定义液晶屏数据口
#define Busy    0x80   //用于检测LCM状态字中的Busy标识unsigned char pwm_left_val = 180;//左电机占空比值 取值范围0-170,0最快
unsigned char pwm_right_val = 180;//右电机占空比值取值范围0-170 ,0最快
unsigned char pwm_t;//周期
unsigned int  time = 0;//传输时间
unsigned long S = 0;//距离
bit      flag = 0;//超出测量范围标志位unsigned char code Range[] ="==Range Finder==";//LCD1602显示格式
unsigned char code ASCII[13] = "0123456789.-M";
unsigned char code table[]="Distance:000.0cm";
unsigned char code table1[]="!!! Out of range";
unsigned char disbuff[4] = { 0,0,0,0};//距离显示缓存void delay(unsigned int z)//毫秒级延时
{unsigned int x,y;for(x = z; x > 0; x--)for(y = 114; y > 0 ; y--);
}void Delay10us(unsigned char i)        //10us延时函数 启动超声波模块时使用
{ unsigned char j; do{ j = 10; do{ _nop_(); }while(--j); }while(--i);
}void cmg88()//关数共阴极码管
{DU=1;       P0=0X00;//共阴极数码管阳极给低电平,全部熄灭DU=0;
} /************************************LCD1602液晶屏驱动函数************************************************/
//*******************读状态*************************//
unsigned char ReadStatusLCM(void)
{LCM_Data = 0xFF; LCM_RS = 0;Delay10us(1); LCM_RW = 1;Delay10us(1); do{LCM_E = 0;Delay10us(1); LCM_E = 0;Delay10us(1); LCM_E = 1;Delay10us(1); }while (LCM_Data & Busy); //检测忙信号return(LCM_Data);
}/****************写数据************************/
void WriteDataLCM(unsigned char WDLCM)
{ReadStatusLCM(); //检测忙LCM_Data = WDLCM;LCM_RS = 1;Delay10us(1); LCM_RW = 0;Delay10us(1); LCM_E = 0; //若晶振速度太高可以在这后加小的延时Delay10us(1); LCM_E = 0; //延时Delay10us(1); LCM_E = 1;Delay10us(1);
}//****************写指令*************************//
void WriteCommandLCM(unsigned char WCLCM,BuysC) //BuysC为0时忽略忙检测
{if (BuysC) ReadStatusLCM(); //根据需要检测忙LCM_Data = WCLCM;LCM_RS = 0;Delay10us(1); LCM_RW = 0;  Delay10us(1); LCM_E = 0;Delay10us(1); LCM_E = 0;Delay10us(1); LCM_E = 1;Delay10us(1);
}//*******************LCM初始化**********************//
void LCMInit(void)
{LCM_Data = 0;WriteCommandLCM(0x38,0); //三次显示模式设置,不检测忙信号delay(5); WriteCommandLCM(0x38,0);delay(5); WriteCommandLCM(0x38,0);delay(5); WriteCommandLCM(0x38,1); //显示模式设置,开始要求每次检测忙信号WriteCommandLCM(0x08,1); //关闭显示WriteCommandLCM(0x01,1); //显示清屏WriteCommandLCM(0x06,1); // 显示光标移动设置WriteCommandLCM(0x0c,1); // 显示开及光标设置
}//*********************按指定位置显示一个字符***********************//
void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData)
{Y &= 0x1;X &= 0xF; //限制X不能大于15,Y不能大于1if (Y) X |= 0x40; //当要显示第二行时地址码+0x40;X |= 0x80; //算出指令码WriteCommandLCM(X, 1); //发命令字WriteDataLCM(DData); //发数据
}//**********************按指定位置显示一串字符*************************//
void DisplayListChar(unsigned char X, unsigned char Y, unsigned char code *DData)
{unsigned char ListLength;ListLength = 0;Y &= 0x1;X &= 0xF; //限制X不能大于15,Y不能大于1while (DData[ListLength]>0x19) //若到达字串尾则退出{if (X <= 0xF) //X坐标应小于0xF{DisplayOneChar(X, Y, DData[ListLength]); //显示单个字符ListLength++;X++;}}
}/***************************************************************************//*定时器0中断*/
void timer0() interrupt 1   //T0中断用来计数器溢出,超过测距范围
{flag=1;                            //中断溢出标志
}
void  StartModule()                  //启动超声波模块
{TX=1;                              //启动一次模块Delay10us(2);TX=0;
}/*小车前进*/
void forward()
{left_motor_go; //左电机前进right_motor_go; //右电机前进
}/*PWM控制使能 小车后退*/
void backward()
{left_motor_back; //左电机后退right_motor_back; //右电机后退
}/*小车停止*/
void stop()
{right_motor_stops;//右电机停止left_motor_stops; //左电机停止
}/*PWM控制使能 小车高速左转*/
void left_rapidly()
{left_motor_back;right_motor_go;
}/*定时器1中断输出PWM信号*/
void timer1() interrupt 3
{pwm_t++;//周期计时加if(pwm_t == 255)pwm_t = EN1 = EN2 = 0;if(pwm_left_val == pwm_t)//左电机占空比    EN1 = 1;       if(pwm_right_val == pwm_t)//右电机占空比EN2 = 1;
}
/*判断S2是否被按下*/
void keyscan()
{for(;;)    //死循环{if(key_s2 == 0)// 实时检测S2按键是否被按下{delay(5); //软件消抖if(key_s2 == 0)//再检测S2是否被按下{while(!key_s2);//松手检测beep = 0;   //使能有源蜂鸣器delay(200);//200毫秒延时beep = 1; //关闭有源蜂鸣器break;     //退出FOR死循环}}}
}/*计算超声波所测距离并显示*/
void Conut(void)
{time=TH0*256+TL0;TH0=0;TL0=0;S=(float)(time*1.085)*0.17;     //算出来是MMif((S>=7000)||flag==1) //超出测量范围{    flag=0;DisplayListChar(0, 1, table1);//1602显示数组table1}else{disbuff[0]=S/1000; //距离数值千位disbuff[1]=S%1000/100;//距离数值百位disbuff[2]=S%100/10;//距离数值十位disbuff[3]=S%10; //距离数值个位DisplayListChar(0, 1, table); //显示:Distance:000.0cmDisplayOneChar(9, 1, ASCII[disbuff[0]]); //显示千位DisplayOneChar(10, 1, ASCII[disbuff[1]]);   DisplayOneChar(11, 1, ASCII[disbuff[2]]);DisplayOneChar(12, 1, ASCII[10]);      //显示 .  DisplayOneChar(13, 1, ASCII[disbuff[3]]);}
}/*超声波避障*/
void    Avoid()
{if(S < 400)//设置避障距离 ,单位毫米    刹车距离{beep = 0;//使能蜂鸣器stop();//停车backward();//后退delay(100);//后退时间越长、距离越远。后退是为了留出车辆转向的空间do{left_rapidly();//高速左转delay(70);//时间越长 转向角度越大,与实际行驶环境有关stop();//停车delay(200);//时间越长 停止时间越久长StartModule();   //启动模块测距,再次判断是否while(!RX);       //当RX(ECHO信号回响)为零时等待TR0=1;               //开启计数while(RX);            //当RX为1计数并等待TR0=0;             //关闭计数Conut();          //计算距离}while(S < 280);//判断前面障碍物距离beep = 1;//关闭蜂鸣器}else{forward();//前进}
}void main()
{cmg88();//关数码管LCMInit(); //LCM初始化delay(5);//延时片刻DisplayListChar(0, 0, Range);//1602第一行显示Range数组内容DisplayListChar(0, 1, table);//1602第二行显示table数组内容keyscan();//等待按下S2启动小车delay(1000);//延时1秒TMOD |= 0x20;//定时器1工作模式2,8位自动重装。用于产生PWMTMOD |= 0x01;//定时器0工作模块1,16位定时模式。T0用测ECH0脉冲长度TH1 = 220; //TL1 = 220; //100HZ T1TH0    = 0;TL0    = 0;//T0,16位定时计数用于记录ECHO高电平时间         ET1  = 1;//允许T1中断ET0 = 1;//允许T0中断TR1 = 1;//启动定时器1EA  = 1;//启动总中断while(1){StartModule();  //启动模块测距while(!RX);     //当RX(ECHO信号回响)为零时等待TR0=1;               //开启计数while(RX);            //当RX为1计数并等待TR0=0;             //关闭计数Conut();          //计算距离Avoid();          //避障delay(65);          //测试周期不低于60MS         }
}
#ifndef __QXA51_H__
#define __QXA51_H__/*电机驱动IO定义*/
sbit IN1=P1^2; //为1 左电机反转
sbit IN2=P1^3; //为1 左电机正转
sbit IN3=P1^6; //为1 右电机正转
sbit IN4=P1^7; //为1 右电机反转
sbit EN1=P1^4; //为1 左电机使能
sbit EN2=P1^5; //为1 右电机使能
sbit left_led1=P3^3;//左寻迹信号 为0没有识别到黑线 为1识别到黑线
sbit right_led1=P3^2;//右寻迹信号 为0没有识别到黑线 为1识别到黑线
sbit left_led2=P3^4;//左避障信号 为0识别到障碍物 为1没有识别到障碍物
sbit right_led2=P3^5;//右避障信号 为0识别到障碍物 为1没有识别到障碍物
sbit beep=P2^3;
sbit key_s2=P3^0;
sbit key_s3=P3^1;
#define left_motor_en           EN1=1 //左电机使能
#define left_motor_stops        EN1=0 //左电机停止
#define right_motor_en        EN2=1 //右电机使能
#define right_motor_stops       EN2=0 //右电机停止#define left_motor_go         IN1=0,IN2=1 //左电机正转
#define left_motor_back       IN1=1,IN2=0 //左电机反转
#define right_motor_go        IN3=1,IN4=0 //右电机正转
#define right_motor_back        IN3=0,IN4=1 //右电机反转#endif

这里运用了LCD1602的显示数据,按键启动,超声波测距,蜂鸣器,定时器,中断功能,

避障原理:运用超声波测距来检测距离如果距离小于指定距离的话,蜂鸣器开始响,然后停车开始向后退,高速左转后停车,然后继续运用超声波模块测距,如果大于指定距离继续前进

51智能小车超声波避障相关推荐

  1. distance在函数 int_Arduino智能小车——超声波避障

    Arduino智能小车--超声波避障 Arduino智能小车系列教程时空门: Arduino智能小车--拼装篇 点击跳转 Arduino智能小车--测试篇 点击跳转 Arduino智能小车--调速篇 ...

  2. Arduino智能小车——超声波避障

    Arduino智能小车--超声波避障 Arduino智能小车系列教程时空门: Arduino智能小车--拼装篇 点击跳转 Arduino智能小车--测试篇 点击跳转 Arduino智能小车--调速篇 ...

  3. ZYAR20A 亚克力2驱 蓝牙 298寻迹避障机器人 —— 小车超声波避障实验(有舵机)

    在下载到开发板之前要选择好板和端口,具体参见: ZYAR20A 亚克力2驱 蓝牙 298寻迹避障机器人 -- Arduino相关设置 代码 // 智能小车超声波避障实验(有舵机) // 程序中电脑打印 ...

  4. ZYAR20A 亚克力2驱 蓝牙 298寻迹避障机器人 —— 小车超声波避障实验(无舵机)

    在下载到开发板之前要选择好板和端口,具体参见: ZYAR20A 亚克力2驱 蓝牙 298寻迹避障机器人 -- Arduino相关设置 代码 // 智能小车超声波避障实验(无舵机) //======== ...

  5. 基于51单片机的超声波避障小车设计(含Proteus仿真)

    超声波避障程序随处可见,基于51单片机的超声波避障小车也很成熟,但是完整的Proteus仿真并不容易找到开源资料. 这次主要给大家分享其Proteus仿真部分. 涉及到的模块有:超声波模块(hc-sr ...

  6. 智能循迹避障小车C语言程序编写思路,基于单片机的智能小车红外避障循迹系统设计与制作...

    余秀玲 余秀娟 摘 要:随着科技的高速发展,人们对生活质量的要求越来越高,无人驾驶汽车已经被广为研发和试用,由此智能小车的快速发展也是在情理之中.通过对基于单片机的智能小车的硬件及软件设计分析,实现红 ...

  7. 智能小车红外避障原理

    红外避障电路 红外避障电路由电位器R17,R28:发光二极管D8,D9:红外发射管 D2,D4和红外接收管D3,D5和芯片LM324等组成,LM234用于信号的比较,并产生比较结果输出给单片机进行处理 ...

  8. 51单片机之智能小车(避障、跟随、循迹)

    目录 基本概述 硬件组成 功能 关键字 模块介绍 电机模块L9110S 循迹模块(TCRT5000传感器) 红外避障模块 测速模块 小车 移动小车(控制电机转动,使小车前进.后退.左转.右转 ) 遥控 ...

  9. 智能小车红外避障模块----使用教程

    博主本科期间做过两个智能小车,链接如下 b站小车视频分享 今天就给·大家分享一下,何如在你的单片机或者树莓派上调用红外避障模块. 循迹模块介绍 循迹模块和红外避障模块类似.循迹模块的红外发射二极管不断 ...

最新文章

  1. RPA有哪些优点和缺点?
  2. Android中 AsyncTask
  3. c 在realse下为什么生成不了exe_exe文件?你也可以编写!
  4. 让一张图片随着手指的移动而移动
  5. 深度学习:从MLP到朴素的神经网络
  6. js 循环拆词_javascript forEach通用循环遍历方法
  7. 热烈庆祝个人博客突破1万人!
  8. mysql存入中文乱码解决方法(windows环境)
  9. mysql 5.7.26 linux安装_mysql-5.7.28 在Linux下的安装教程图解
  10. 微信模板消息的发送动态封装(Java完美封装)
  11. virtualbox虚拟机安装win10详细教程
  12. 量化投资 | 统计套利策略
  13. Python 判断列表中是否含有给定字符串
  14. v-for报错Cannot use v-for on stateful component root element because it renders multiple elements.
  15. Chaos Emulator v0.2.3 自建引力模拟器分享
  16. 时间复杂度(超详解+例题)
  17. sm总线控制器找不到驱动程序_【KHGEARS钧兴谐波 | 新品】埃斯顿发布总线伺服驱动系统 ProNet Summa...
  18. Ubuntu技巧:windows和Ubuntu下给ping包加时间戳
  19. 炫龙笔记本的gtx965m显卡玩游戏很卡
  20. 数据可视化大屏应用场景有哪些?

热门文章

  1. 量化分析师的Python日记【第2天:再接着介绍一下Python呗】
  2. uefi启动 多硬盘gtp_BIOS支持UEFI,整个硬盘GUID(GPT)分区,能否安装原版Mac OS
  3. Android8.1编译Kil库
  4. Cocos游戏带你告别光棍节:欢迎对号入座、修成正果!
  5. 网络信息安全攻防学习平台(基础关)
  6. 深度剖析国内人脸识别主流技术及发展走向
  7. HTML5网页动画效果
  8. 谁能分享一下PMP备考攻略?
  9. IMSI、TMSI和P-TMSI
  10. md5检验本地和服务器包的一致性