基于51单片机的雷达倒车测距装置程序
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
#include <reg51.h>
#include <intrins.h>
#define uint unsigned int
#define uchar unsigned char
#define comm 0
#define dat 1
sbit RS=P2^6; //高电平数据,低电平命令
sbit RW=P2^5; //读写控制脚,高电平读,低电平写sbit E=P2^7; //输入使能
sbit busy=P0^7; //忙信号检测
sbit SDA=P1^0; //I2C数据线
sbit SCL=P1^1; //I2C时钟线
sbit Buzz=P1^2; //蜂鸣器控制脚
sbit LED_G=P1^3; //绿色指示灯控制脚
sbit LED_R=P1^4; //红色指示灯控制脚
uchar buf[6],dis_buf[6]; //数据缓冲区
uint buffer[3]; //测量距离存储区
uint dis; //最小距离存储器
uchar code tab1[]={"距离障碍物:"}; //显示字符
uchar code tab2[]={"无障碍物"};
uchar code tab[]={"0123456789cm"};
/*****************函数声明*****************/
void start_bit(void); //I2C起始函数
void stop_bit(void); //I2C停止函数
void mast_ack(void); //主答函数
bit write_8bit(uchar ch); //I2C总线写8位数据函数
bit page_rd(uchar device,uint fir_ad,uint count,uchar *firw_ad);//I2C总线页面读函数
uint measure(uchar device); //启动测距函数
uint get_distance(void); //读测距值函数
void judge(void); //判断距离函数
void init_lcd (void); //LCD初始化函数
void wr_lcd(uchar dat_comm,uchar content);//LCD写数据函数
void chk_busy (void); //忙信号检测
void chn_disp(uchar code *chn,uchar pos,uchar n);//显示提示汉字函数
uchar dat_adj(uint dat1); //显示数据调整函数
void disp_dist(uchar dat1); //显示距离函数
void disp(void); //显示函数
void delay (uint us); //延时函数
void delay1 (uint ms); //延时函数
/*********************主程序***********************/
void main ()
{
init_lcd (); //初始化LCD
while (1)
{
judge(); //判断障碍物距离
disp(); //显示提示信息}
}
/********************I2C起始函数*******************/
void start_bit(void)
{
SCL=1;_nop_();
SDA=1;_nop_();
SDA=0;_nop_();
SCL=0;_nop_();
}
/*******************I2C停止函数********************/
void stop_bit(void)
{
SDA=0;_nop_();
SCL=1;_nop_();
SDA=1;_nop_();
}
/****************I2C总线写8位数据函数**************/
bit write_8bit(uchar ch)
{
uchar i=8;
bit fan_w;
SCL=0;_nop_();
while (i--)
{
SDA=(bit)(ch&0x80);_nop_(); //获取发送位数据
ch<<=1;
SCL=1;_nop_();
SCL=0;_nop_();
}
SDA=1;_nop_();
SCL=1;_nop_();
fan_w=SDA; //应答位
SCL=0;_nop_();
return(fan_w); //返回应答位
}
/*****************I2C总线页面读函数****************/
bit page_rd(uchar device,uint fir_ad,uint count,uchar *firw_ad)
{
uchar j=8;
uchar data *ufirstwr_ad;
ufirstwr_ad=firw_ad;
start_bit();
if(write_8bit(device)!=0){stop_bit();return(0);}//送器件地址,写数据
if(write_8bit(fir_ad)!=0){stop_bit();return(0);}//送读数据寄存器首地址start_bit();
if(write_8bit(device|0x01)!=0){stop_bit();return(0);}//准备读数据
while(count--)
{
uchar i=8;
while(i--) //读入数据
{
(*ufirstwr_ad)<<=1;
SCL=1;_nop_();
if(SDA) (*ufirstwr_ad)|=0x01;
SCL=0; _nop_();
}
ufirstwr_ad++;
mast_ack(); //主机产生应答位}
while(j--)
{
(*ufirstwr_ad)<<=1;
SCL=0;_nop_();_nop_();SCL=1;
if(SDA) (*ufirstwr_ad)|=0x01;
}
stop_bit(); //停止I2C数据传送return(1);
}
/*********************主答函数*********************/
void mast_ack(void)
{
SCL=0;_nop_();
SDA=0;_nop_();
SCL=1;_nop_();
SCL=0;_nop_();
SDA=1;_nop_();
}
/********************测距函数******************/
uint measure(uchar device)
{
uint temp;
start_bit(); //启动I2C
while(!write_8bit(device)); //发器件地址
while(!write_8bit(0x00)); //命令寄存器
while(!write_8bit(0x51)); //以厘米为单位返回距离stop_bit(); //停止I2C
delay1(100);
while(!page_rd(device,0x02,2,buf)); //读距离值
temp=(buf[0]<<8)|buf[1];
return(buffer); //返回距离值
}
/*******************求最小测距值函数*****************/
uint get_distance(void)
{
uint mix;
buffer[0]=measure(0xe0); //读左侧测距值
buffer[1]=measure(0xe2); //读中间测距值
buffer[2]=measure(0xe4); //读右侧测距值
if(buffer[0]<buffer[1])
mix=buffer[0];
else
mix=buffer[1];
if(mix>buffer[2])mix=buffer[2]; //合并为一个16位数据return(mix);
}
/*******************判断距离函数*******************/
void judge(void)
{
dis=get_distance(); //读取测量距离最小值if(dis<5000)
{
LED_R=0; //红色报警灯亮
LED_G=1; //绿色报警灯灭}
else
{
LED_R=1; //红色报警灯灭
LED_G=0; //绿色报警灯亮}
if(dis<3000)
Buzz=0; //蜂鸣器报警else
Buzz=1; //蜂鸣器停止报警}
/******************LCD初始化函数*******************/
void init_lcd (void)
{
wr_lcd (comm,0x30); //基本指令动作
wr_lcd (comm,0x01); //清屏
wr_lcd (comm,0x06); //光标的移动方向
wr_lcd (comm,0x0c); //开显示,关游标
}
/*******************LCD写数据函数*****************/
void wr_lcd (uchar dat_comm,uchar content)
{
chk_busy ();
if(dat_comm)
{
RS=1; //数据
RW=0; //写入
}
else
{
RS=0; //命令
RW=0; //写入
}
P0=content; //输出数据或命令
E=1;
E=0;
}
/********************忙信号检测********************/
void chk_busy (void)
{
P0=0xff;
RS=0;
RW=1;
E=1;
while(busy==1); //检验LCD是否处于忙状态E=0;
}
/****************显示提示汉字函数******************/
void chn_disp(uchar code *chn,uchar pos,uchar n)
{
uchar i;
wr_lcd (comm,0x30); //基本指令动作
wr_lcd (comm,pos); //显示位置
for (i=0;i<n;i++)
wr_lcd (dat,chn[i]);
}
/****************显示数据调整函数******************/
uchar dat_adj(uint dat1)
{
uchar i;
dis_buf[0]=(uchar)(dat1/1000); //高度千位
dis_buf[1]=(uchar)((dat1%1000)/100); //高度百位
dis_buf[2]=(uchar)((dat1%100)/10); //高度十位
dis_buf[3]=(uchar)(dat1%10); //高度个位
dis_buf[4]=10;
for(i=0;i<3;i++)
{
if(dis_buf[i]!=0)break; //确定显示位数}
return(i);
}
/******************显示距离函数********************/
void disp_dist(uchar dat1)
{
uchar temp,i;
if(dat1>5000)
{
chn_disp(tab2,0x92,4); //无障碍显示}
else
{
temp=dat_adj(dat1);
wr_lcd(comm,0x30); //基本指令
wr_lcd(comm,temp+0x92); //设置显示起始位置
for (i=temp;i<6;i++) //送显示数据
wr_lcd(dat,tab[dis_buf[i]]);
}
}
/********************显示函数**********************/
void disp(void)
{
chn_disp(tab1,0x80,11); //显示提示汉字
disp_dist(dis); //显示距离值
}
/********************延时函数**********************/
void delay (uint us)
{
while(us--);
}
/********************延时函数**********************/
void delay1 (uint ms)
{
uint i,j;
for(i=0;i<ms;i++)
for(j=0;j<15;j++)
delay(1);
}。