#include <reg51.h>
#include <intrins.h>
#define LCD1602_DATAPINS P0
# define uchar unsigned char
# define uint unsigned int
uint distance=0;
sbit K1=P3^3;
uchar xuehao[]={"id: 131114105"};
uchar dis[]={"dis= "};
sfr P4=0xc0;
sfr P4M1 = 0xb3;
sfr P4M0 = 0xb4;
sbit LCD1602_E=P4^4;
sbit LCD1602_RW=P4^2;
sbit LCD1602_RS=P4^1;
sbit RX=P1^7; //Rx为输出回响信号 echo
sbit TX=P1^6; //tx为输入触发信号 trig
long time;//time为双高精度浮点数
uint temp=0,t=0,n=0,th,tl;
bit flag_csb_juli; //超声波超出量程
uint m=0,flag_time0;
uchar th0,tl0;
uchar code num[] = "0123456789";
unsigned char disbuff[4] ={ 0,0,0,0,};
uint j;
void delayms(unsigned int ms)
{
unsigned char i=100,j;
for(;ms;ms--)
{
while(--i)
{
j=10;
while(--j);
}
}
}
void Delay10ms(unsigned int c) //误差 0us
{
unsigned char a, b;
//--c已经在传递过来的时候已经赋值了,所以在for语句第一句就不用赋值了--//
for (;c>0;c--)
{
for (b=38;b>0;b--)
{
for (a=130;a>0;a--);
}
}
}
void LcdWriteCom(uchar com) //写入命令
{
LCD1602_E = 0; //使能
LCD1602_RS = 0; //选择发送命令
LCD1602_RW = 0; //选择写入
LCD1602_DATAPINS = com; //放入命令
Delay10ms(1); //等待数据稳定
LCD1602_E = 1; //写入时序
Delay10ms(5); //保持时间
LCD1602_E = 0;
}
void LcdWriteData(uchar dat) //写入数据
{
LCD1602_E = 0; //使能清零
LCD1602_RS = 1; //选择输入数据
LCD1602_RW = 0; //选择写入
LCD1602_DATAPINS = dat; //写入数据
Delay10ms(1);
LCD1602_E = 1; //写入时序
Delay10ms(5); //保持时间
LCD1602_E = 0;
}
void Delay_ms(uint c) //误差 0us
{
uint x,y ;
for(x=c;x>0;x--)
for(y=110;y>0;y--);
}
void LcdInit() //LCD初始化子程序
{
LcdWriteCom(0x38); //开显示
LcdWriteCom(0x0c); //开显示不显示光标
LcdWriteCom(0x06); //写一个指针加1
LcdWriteCom(0x01); //清屏
LcdWriteCom(0x80); //设置数据指针起.点
}
//数字显示函数
void LCD_Write_number(uint i)
{
LcdWriteData(num[i]);
Delay_ms(1);
}
/***********************lcd1602上显示超声波距离************************/
void Display()
{
/* LcdWriteCom(0x80+0x40);
LCD_Write_number(distance/100%10);
LcdWriteData('.');
LCD_Write_number(distance/10%10);
LCD_Write_number(distance%10); */
LcdWriteCom(0x80+0x40);
disbuff[1]=distance%1000/100;
disbuff[2]=distance%1000%100/10;
disbuff[3]=distance%1000%10 %10;
for(j=0;j<5;j++)
{
LcdWriteData(dis[j]);
Delay_ms(1);
}
LCD_Write_number(disbuff[1]);
LcdWriteData('.');
LCD_Write_number(disbuff[2]);
LCD_Write_number(disbuff[3]);
LcdWriteData(' ');
LcdWriteData(' ');
LcdWriteData('m');
}
//T0中断用来计数器溢出,超过测距范围
void T0_time() interrupt 1
{
}
//定时器初始设置
void time_init()
{
EA = 1; //开总中断
TMOD = 0X01; //定时器0工作方式1
ET0 = 1; //开定时器0中断
TR0 = 1; //允许定时器0定时
}
//小时间延迟函数
void delay()
{
_nop_(); //执行一条_nop_()指令就是1us
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_(); //执行一条_nop_()指令就是1us
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
}
void send_wave1()
{
// delay();
TX=1;
delay();
TX=0;
// delay();
}
/*********************超声波测距程序*****************************/
void send_wave()
{
// time_init();
// distance=0;//test,distance clear
send_wave1();
// TR0 = 1;
while(!RX);
TR0=1; //当c_recive为零时等待
while(RX);
TR0=0; //当RX为1计数并等待
flag_time0 = TH0 * 256 +TL0;
TH0 = 0; //给定时器0清零
TL0 = 0;
if((flag_time0 > 40000)) //当超声波超过测量范围时,显示3个888
{
flag_csb_juli = 2;
distance = 888;
}
else
{
flag_csb_juli = 1;
}
if(flag_csb_juli == 1)
{ //测试,为什么要关掉定时器
distance =flag_time0; //读出定时器0的时间
distance *= 0.017; // 0.017 = 340M / 2 = 170M = 0.017M 算出来是米
if((distance > 500)) //距离 = 速度 * 时间
{
distance = 888; //如果大于3.8m就超出超声波的量程
}
}
}
void main(void)
{
uint t=0;
// time_init();//定时器初始化
TMOD = 0X01;
TH0=0;
TL0=0;
TR0=1;
LcdInit(); //lcd
//第一行写学初始化
LcdWriteCom(0x80);
for(t =0; t<14; t++)
{
LcdWriteData(xuehao[t]);
}
while(1)
{
send_wave(); //超声波模块发射超声波
Display();
delayms(80); //测试
//delay10ms(100);//测试,延时
}
}
#include <intrins.h>
#define LCD1602_DATAPINS P0
# define uchar unsigned char
# define uint unsigned int
uint distance=0;
sbit K1=P3^3;
uchar xuehao[]={"id: 131114105"};
uchar dis[]={"dis= "};
sfr P4=0xc0;
sfr P4M1 = 0xb3;
sfr P4M0 = 0xb4;
sbit LCD1602_E=P4^4;
sbit LCD1602_RW=P4^2;
sbit LCD1602_RS=P4^1;
sbit RX=P1^7; //Rx为输出回响信号 echo
sbit TX=P1^6; //tx为输入触发信号 trig
long time;//time为双高精度浮点数
uint temp=0,t=0,n=0,th,tl;
bit flag_csb_juli; //超声波超出量程
uint m=0,flag_time0;
uchar th0,tl0;
uchar code num[] = "0123456789";
unsigned char disbuff[4] ={ 0,0,0,0,};
uint j;
void delayms(unsigned int ms)
{
unsigned char i=100,j;
for(;ms;ms--)
{
while(--i)
{
j=10;
while(--j);
}
}
}
void Delay10ms(unsigned int c) //误差 0us
{
unsigned char a, b;
//--c已经在传递过来的时候已经赋值了,所以在for语句第一句就不用赋值了--//
for (;c>0;c--)
{
for (b=38;b>0;b--)
{
for (a=130;a>0;a--);
}
}
}
void LcdWriteCom(uchar com) //写入命令
{
LCD1602_E = 0; //使能
LCD1602_RS = 0; //选择发送命令
LCD1602_RW = 0; //选择写入
LCD1602_DATAPINS = com; //放入命令
Delay10ms(1); //等待数据稳定
LCD1602_E = 1; //写入时序
Delay10ms(5); //保持时间
LCD1602_E = 0;
}
void LcdWriteData(uchar dat) //写入数据
{
LCD1602_E = 0; //使能清零
LCD1602_RS = 1; //选择输入数据
LCD1602_RW = 0; //选择写入
LCD1602_DATAPINS = dat; //写入数据
Delay10ms(1);
LCD1602_E = 1; //写入时序
Delay10ms(5); //保持时间
LCD1602_E = 0;
}
void Delay_ms(uint c) //误差 0us
{
uint x,y ;
for(x=c;x>0;x--)
for(y=110;y>0;y--);
}
void LcdInit() //LCD初始化子程序
{
LcdWriteCom(0x38); //开显示
LcdWriteCom(0x0c); //开显示不显示光标
LcdWriteCom(0x06); //写一个指针加1
LcdWriteCom(0x01); //清屏
LcdWriteCom(0x80); //设置数据指针起.点
}
//数字显示函数
void LCD_Write_number(uint i)
{
LcdWriteData(num[i]);
Delay_ms(1);
}
/***********************lcd1602上显示超声波距离************************/
void Display()
{
/* LcdWriteCom(0x80+0x40);
LCD_Write_number(distance/100%10);
LcdWriteData('.');
LCD_Write_number(distance/10%10);
LCD_Write_number(distance%10); */
LcdWriteCom(0x80+0x40);
disbuff[1]=distance%1000/100;
disbuff[2]=distance%1000%100/10;
disbuff[3]=distance%1000%10 %10;
for(j=0;j<5;j++)
{
LcdWriteData(dis[j]);
Delay_ms(1);
}
LCD_Write_number(disbuff[1]);
LcdWriteData('.');
LCD_Write_number(disbuff[2]);
LCD_Write_number(disbuff[3]);
LcdWriteData(' ');
LcdWriteData(' ');
LcdWriteData('m');
}
//T0中断用来计数器溢出,超过测距范围
void T0_time() interrupt 1
{
}
//定时器初始设置
void time_init()
{
EA = 1; //开总中断
TMOD = 0X01; //定时器0工作方式1
ET0 = 1; //开定时器0中断
TR0 = 1; //允许定时器0定时
}
//小时间延迟函数
void delay()
{
_nop_(); //执行一条_nop_()指令就是1us
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_(); //执行一条_nop_()指令就是1us
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
}
void send_wave1()
{
// delay();
TX=1;
delay();
TX=0;
// delay();
}
/*********************超声波测距程序*****************************/
void send_wave()
{
// time_init();
// distance=0;//test,distance clear
send_wave1();
// TR0 = 1;
while(!RX);
TR0=1; //当c_recive为零时等待
while(RX);
TR0=0; //当RX为1计数并等待
flag_time0 = TH0 * 256 +TL0;
TH0 = 0; //给定时器0清零
TL0 = 0;
if((flag_time0 > 40000)) //当超声波超过测量范围时,显示3个888
{
flag_csb_juli = 2;
distance = 888;
}
else
{
flag_csb_juli = 1;
}
if(flag_csb_juli == 1)
{ //测试,为什么要关掉定时器
distance =flag_time0; //读出定时器0的时间
distance *= 0.017; // 0.017 = 340M / 2 = 170M = 0.017M 算出来是米
if((distance > 500)) //距离 = 速度 * 时间
{
distance = 888; //如果大于3.8m就超出超声波的量程
}
}
}
void main(void)
{
uint t=0;
// time_init();//定时器初始化
TMOD = 0X01;
TH0=0;
TL0=0;
TR0=1;
LcdInit(); //lcd
//第一行写学初始化
LcdWriteCom(0x80);
for(t =0; t<14; t++)
{
LcdWriteData(xuehao[t]);
}
while(1)
{
send_wave(); //超声波模块发射超声波
Display();
delayms(80); //测试
//delay10ms(100);//测试,延时
}
}