http://mp.weixin.qq.com/mp/homepage?__biz=MzU3OTczMzk5Mg==&hid=7&sn=ad5d5d0f15df84f4a92ebf72f88d4ee8&scene=18#wechat_redirect --------------------------------------------------------------------------------------------------------------------------
(1)通过系统的设计与实现,能够解决汽车行进过程中由于驾驶员分心导致汽车碰撞的问题;
(2)构造型号为STC89C52RC作为系统的中心处理单元,单片机最小工作电路负责接收超声传感器测量的距离值、控制液晶屏显示内容、控制声光报警电路和继电器电路;
(3)设置超声传感器HC-SR04在汽车行驶过程中实时收集前后车之间的距离;
(4)当收集的距离值小于设定的最小报警距离值时,声光报警电路工作并提示报警;
(5)应用液晶屏1602显示实时距离和设定的最小报警距离值,并指示当前汽车继续行驶的状态,即安全和危险;
(6)系统设置独立按键电路,设置系统设置的最小报警距离值,切换系统模式的正常工作模式和休眠模式;
(7)构建一路继电器电路,模拟制动装置通过继电器吸合自动开启动作;
(8)建立电源电路,满足系统的供电需求。
#include<reg51.h> #include<intrins.h> #include"lcd.h" sbit Trig = P2^1; sbit Echo = P2^0; sbit led_0 = P1^0; sbit led_1 = P1^1; sbit beep = P1^3; sbit jdq = P1^4; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// sbit k1=P3^2; ///加法按钮 sbit k2=P3^3; ///减法按钮 sbit k3=P3^1; ///休眠按钮 sbit k4=P3^0; //复位按钮 / unsigned char PuZh[]="CM shi juli"; unsigned char code ASCII[15] = {'0',二,三,四,五,六,七.','-','M'}; static unsigned char DisNum = 0; //显示指针 unsigned int time=0; unsigned long S=0; bit flag =0; unsigned char disbuff[4] ={ 0,0,0,0,}; /******************************************************************************* * 函 数 名 : main * 函数功能 : 主函数 * 输 入 : 无 * 输 出 : 无 *******************************************************************************/ void Conut(unsigned char q) { unsigned int anquanjuli = q; time=TH0*256 TL0; TH0=0; TL0=0; S=(time*1.7)/100; //计算是的CM if((S>=700)||flag==1) 超出测量范围显示- { flag=0; DisplayOneChar(0, 1, ASCII[11]); DisplayOneChar(1, 1, ASCII[10]); //显示点 DisplayOneChar(2, 1, ASCII[11]); DisplayOneChar(3, 1, ASCII[11]); DisplayOneChar(4, 1, ASCII[12]); //显示M } else { disbuff[0]=S00/100; disbuff[1]=S000/10; disbuff[2]=S00 ; DisplayOneChar(0, 1, ASCII[disbuff[0]]); DisplayOneChar(1, 1, ASCII[10]); //显示点 DisplayOneChar(2, 1, ASCII[disbuff[1]]); DisplayOneChar(3, 1, ASCII[disbuff[2]]); DisplayOneChar(4, 1, ASCII[12]); //显示M } if(S<=anquanjuli) ///小于安全距离就亮红灯,蜂鸣器响继电器工作 { led_0=0; led_1=1; beep=0; jdq=0; } else if(S>anquanjuli&&S<=700) ///在安全范围内,绿灯蜂鸣器不响 { led_0=1; led_1=0; beep=1; jdq=1; } } void Conut2(unsigned char q) { unsigned int anquanjuli = q; time=TH0*256 TL0; TH0=0; TL0=0; S=(time*1.7)/100; //计算是的CM if((S>=700)||flag==1) 超出测量范围显示- { flag=0; DisplayOneChar(0, 1, ASCII[11]); DisplayOneChar(1, 1, ASCII[10]); //显示点 DisplayOneChar(2, 1, ASCII[11]); DisplayOneChar(3, 1, ASCII[11]); DisplayOneChar(4, 1, ASCII[12]); //显示M } else { disbuff[0]=S00/100; disbuff[1]=S000/10; disbuff[2]=S00 ; DisplayOneChar(0, 1, ASCII[disbuff[0]]); DisplayOneChar(1, 1, ASCII[10]); //显示点 DisplayOneChar(2, 1, ASCII[disbuff[1]]); DisplayOneChar(3, 1, ASCII[disbuff[2]]); DisplayOneChar(4, 1, ASCII[12]); //显示M } } void zd0() interrupt 1 //T0中断用于计数器溢出,超过测距范围 { flag=1; //中断溢出标志 } void StartModule() //启动模块 { Trig=1; ///启动一次模块 _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); Trig=0; } void delayms(unsigned int ms) { unsigned char i=100,j; for(;ms;ms--) { while(--i) { j=10; while(--j); } } } /// /* 字符串转十进制整形 */ int atoi(char s[]) { int i; int n = 0; for (i = 0; s[i] >= '0' && s[i] <= '9'; i) { n = 10 * n (s[i] - '');
}
return n;
}
///
void main(void)
{
unsigned char safe[]={"10"};
// unsigned char safe3[1]=0;
// unsigned char safe4[1]=0;
// unsigned char safe5[2] = 0;
unsigned char safe6[3] = 0;
//
// unsigned char safe2[]={'C','M'};
unsigned int getdata= atoi(safe);
unsigned int a=0; ///个位
unsigned int b=0; 十位
unsigned int c=0; ///百位
// unsigned char *p=PuZh;
// unsigned char *q=&safe[0];
// unsigned char *t=safe2;
TMOD=0x01; //设T0为方式1,GATE=1;
TH0=0;
TL0=0;
ET0=1; //允许T0中断
EA=1; //开启总中断
InitLcd1602();
/第一次显示//
a=getdata;
c=a/100;
b=a/10%10;
a=a%10;
safe6[0]=c+0x30;
safe6[1]= b+0x30;
safe6[2]=a+0x30;
DisplayOneChar(0,0,safe6[0]);
DisplayOneChar(1,0,safe6[1]);
DisplayOneChar(2,0,safe6[2]);
LcdShowStr(4,0,PuZh);
// safe4[0]=getdata+0x30;
// DisplayOneChar(0,0,safe4[0]);
while(1)
{
StartModule();
while(!Echo); //当RX为零时等待
TR0=1; //开启计数
while(Echo); //当RX为1计数并等待
TR0=0; //关闭计数
Conut(getdata); //计算 安全距离,需要传入参数
delayms(80);
while(1)
{
if(!k1||!k2||!k3||!k4)//判断有无键按下
{
delayms(10);//消抖动
if(!k1)
{
while(!k1);//按键1按下
getdata=getdata+3;
}
else if(!k2)//按键2按下
{
while(!k2);
getdata=getdata-3;
}
else if(!k3)//按键3按下
{
while(!k3);
getdata=0;
c=getdata/100;
b=getdata/10%10;
a=getdata%10;
safe6[0]=c+0x30;
safe6[1]= b+0x30;
safe6[2]=a+0x30;
DisplayOneChar(0,0,safe6[0]);
DisplayOneChar(1,0,safe6[1]);
DisplayOneChar(2,0,safe6[2]);
LcdShowStr(4,0,PuZh);
StartModule();
while(!Echo); //当RX为零时等待
TR0=1; //开启计数
while(Echo); //当RX为1计数并等待
TR0=0; //关闭计数
Conut2(getdata); //计算 安全距离,需要传入参数
delayms(80);
}
else if(!k4)//按键2按下
{
while(!k4);
getdata=10;
}
if(getdata>9&&getdata<100)
{
c=getdata/100;
b=getdata/10%10;
a=getdata%10;
safe6[0]=c+0x30;
safe6[1]= b+0x30;
safe6[2]=a+0x30;
DisplayOneChar(0,0,safe6[0]);
DisplayOneChar(1,0,safe6[1]);
DisplayOneChar(2,0,safe6[2]);
LcdShowStr(4,0,PuZh);
}
else if(getdata>0&&getdata<10)
{
safe6[0]=0+0x30;
safe6[1]=0+0x30;
safe6[2]=getdata+0x30;
DisplayOneChar(0,0,safe6[0]);
DisplayOneChar(1,0,safe6[1]);
DisplayOneChar(2,0,safe6[2]);
LcdShowStr(4,0,PuZh);
}
else if(getdata>=100&&getdata<1000)
{
safe6[0]=getdata/100+0x30;
safe6[1]=getdata/10%10+0x30;
safe6[2]=getdata%10+0x30;
DisplayOneChar(0,0,safe6[0]);
DisplayOneChar(1,0,safe6[1]);
DisplayOneChar(2,0,safe6[2]);
LcdShowStr(4,0,PuZh);
}
break ;
}
StartModule();
while(!Echo); //当RX为零时等待
TR0=1; //开启计数
while(Echo); //当RX为1计数并等待
TR0=0; //关闭计数
Conut(getdata); //计算 安全距离,需要传入参数
delayms(80);
}
}
}
#include"lcd.h"
void Read_Busy() //忙检测函数,判断bit7是0,允许执行;1禁止
{
unsigned char sta; //
LCD1602_DB = 0xff;
LCD1602_RS = 0;
LCD1602_RW = 1;
do
{
LCD1602_EN = 1;
sta = LCD1602_DB;
LCD1602_EN = 0; //使能,用完就拉低,释放总线
}while(sta & 0x80);
}
void Lcd1602_Write_Cmd(unsigned char cmd) //写命令
{
Read_Busy();
LCD1602_RS = 0;
LCD1602_RW = 0;
LCD1602_DB = cmd;
LCD1602_EN = 1;
LCD1602_EN = 0;
}
void Lcd1602_Write_Data(unsigned char dat) //写数据
{
Read_Busy();
LCD1602_RS = 1;
LCD1602_RW = 0;
LCD1602_DB = dat;
LCD1602_EN = 1;
LCD1602_EN = 0;
}
void LcdSetCursor(unsigned char x,unsigned char y) //坐标显示
{
unsigned char addr;
if(y == 0)
addr = 0x00 + x;
else
addr = 0x40 + x;
Lcd1602_Write_Cmd(addr|0x80);
}
//按指定位置显示一个字符
void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData)
{
Y &= 0x1;
X &= 0xF; //限制X不能大于15,Y不能大于1
if (Y) X |= 0x40; //当要显示第二行时地址码+0x40;
X |= 0x80; //算出指令码
Lcd1602_Write_Cmd(X); //发命令字
Lcd1602_Write_Data(DData); //发数据
}
void LcdShowStr(unsigned char x,unsigned char y,unsigned char *str) //显示字符串
{
LcdSetCursor(x,y); //当前字符的坐标
while(*str != '\0')
{
Lcd1602_Write_Data(*str++);
}
}
void InitLcd1602() //1602初始化
{
Lcd1602_Write_Cmd(0x38); //打开,5*8,8位数据
Lcd1602_Write_Cmd(0x0c);
Lcd1602_Write_Cmd(0x06);
Lcd1602_Write_Cmd(0x01); //清屏
}
#ifndef __LCD_H_
#define __LCD_H_
/**********************************
当使用的是4位数据传输的时候定义,
使用8位取消这个定义
**********************************/
//#define LCD1602_4PINS
/**********************************
包含头文件
**********************************/
#include<reg51.h>
//---重定义关键词---//
#ifndef uchar
#define uchar unsigned char
#endif
#ifndef uint
#define uint unsigned int
#endif
/**********************************
PIN口定义
**********************************/
#define LCD1602_DB P0 //data bus 数据总线
sbit LCD1602_RS = P3^5; //寄存器选择,高电平数据寄存器,低电平指令寄存器
sbit LCD1602_RW = P3^6; //读写信号线,1为读,0写
sbit LCD1602_EN = P3^4; //使能端,1读取信息,
/**********************************
函数声明
**********************************/
/*在51单片机12MHZ时钟下的延时函数*/
void Lcd1602_Delay1ms(uint c); //误差 0us
void Read_Busy(); //忙检测函数,判断bit7是0,允许执行;1禁止
void Lcd1602_Write_Cmd(unsigned char cmd); //写命令
void Lcd1602_Write_Data(unsigned char dat); //写数据
void LcdSetCursor(unsigned char x,unsigned char y); //坐标显示
void LcdShowStr(unsigned char x,unsigned char y,unsigned char *str); //显示字符串
void InitLcd1602(); //1602初始化
void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData);
#endif
--------------------- 作者:hequnwang10 来源:CSDN 原文:https://blog.csdn.net/hequnwang10/article/details/81141267