超声波测距模块:
1、采用IO口TRIG触发测距,给至少10us的高电平信号;
2、模块自动发送8个40khz的方波,自动检测是否有信号返回;
3、有信号返回,通过IO口ECHO输出一个高电平,高电平持续的时间就是超声波从发射到返回的时间。测试距离=(高电平时间*声速(340M/S))/2。
![](https://img-blog.csdnimg.cn/img_convert/fb74b96a3419ba2b636b93e50ac75fe5.jpeg)
液晶LCD1602电路接口
![](https://img-blog.csdnimg.cn/img_convert/c4b136945f56566b689844093df4e436.jpeg)
超声波测距LCD1602显示程序源代码
/*******************超声波测距1602显示********************
* 单片机:51单片机
* 开发环境:keil
* 名称:超声波测距1602显示
注意:用杜邦线将超声波模块的VCC接开发板5V对外供电接口
用杜邦线将超声波模块的GND接开发板GND
用杜邦线将超声波模块的Trig接单片机的P1.5
用杜邦线将超声波模块的Echo接单片机的P1.6
/************************包含头文件************************/
#include <reg51.h>
#define LCD_Data P0
#define Busy 0x80
/**************************宏定义**************************/
#define SPEED_30C 3495 //30摄氏度时的声速,声速V=331.5+0.6*温度;
#define SPEED_23C 3453 //23摄氏度时的声速,声速V=331.5+0.6*温度;
/**************************位定义**************************/
sbit ECHO = P2^1; //回声接收端口
sbit TRIG = P2^0; //超声触发端口
sbit BEEP = P2^3; //蜂鸣器
sbit LCD_RS = P1^0;
sbit LCD_RW = P1^1;
sbit LCD_E =P2^5;
/**********************定义变量和数组**********************/
long int distance = 0; //距离变量
unsigned char code table0[] = {" SL-51A "};
unsigned char code table1[] = {" NO ECHO "};
unsigned char code table2[] = {"Distance:xxx.xcm"};
unsigned char count;
void Delay5Ms(void);
void delay(int In,int Out);
void WriteDataLCD(unsigned char WDLCD);
void WriteCommandLCD(unsigned char WCLCD,BuysC);
unsigned char ReadDataLCD(void);
unsigned char ReadStatusLCD(void);
void LCDInit(void);
void DisplayOneChar(unsigned char X,unsigned charY,unsigned char DData);
void DisplayListChar(unsigned char X,unsigned charY,unsigned char code *DData);
/**********************************************************/
/* 函数名称 : Delay_xMs */
/* 函数描述 : 延时函数 */
/* 输入参数 : x */
/* 参数描述 : 延时时间 */
/* 返回值 : 无 */
/**********************************************************/
void Delay_xMs(unsigned int x)
{
unsigned inti,j;
for(i=0;i<x;i++)
{for(j=0;j<3;j++){;}}
}
/**********************************************************/
/* 函数名称 : delayt */
/* 函数描述 : 延时函数 */
/* 输入参数 : x */
/* 参数描述 : 延时时间数据 */
/* 返回值 : 无 */
/**********************************************************/
void delayt(unsigned int x)
{
unsigned charj;
while(x-->0)
{for(j=0;j<125;j++){;}}
}
/***********************5ms延时函数*********************/
void Delay5Ms(void)
{
unsigned intTempCyc = 3552;
while(TempCyc--);
}
/*************************延迟函数***********************/
void delay(int In,int Out)
{
int i,j;
for(i=0;i<In;i++)
{for(j=0;j<Out;j++){;}}
}
/**********************************************************/
/* 函数名称 : Alarm */
/* 函数描述 : 蜂鸣器发声函数 */
/* 输入参数 : t */
/* 参数描述 : 发声的次数 */
/* 返回值 : 无 */
/**********************************************************/
void Alarm(unsigned char t)
{
unsigned chari;
for(i=0;i<t;i++)
{BEEP=0;delay(10,1000);BEEP=1;delay(10,1000);}
}
/**********************************************************/
/* 函数名称 : Init_timer */
/* 函数描述 : 初始化单片机函数 */
/* 输入参数 : 无 */
/* 参数描述 : 无 */
/* 返回值 : 无 */
/**********************************************************/
void Init_timer(void)
{
TMOD=0x01; //定时器2初始化,设置为16位自动重装模式
TL0=0x66;TH0=0xfc; //1ms
ET0=1; //开定时器2
EA=1; //总中断使能
}
/**********************************************************/
/* 函数名称 : Init_Parameter */
/* 函数描述 : 初始化参数和IO口函数 */
/* 输入参数 : 无 */
/* 参数描述 : 无 */
/* 返回值 : 无 */
/**********************************************************/
void Init_Parameter(void)
{TRIG=1;ECHO=1;count=0;distance=0;}
/**********************************************************/
/* 函数名称 : display */
/* 函数描述 : 显示数字 */
/* 输入参数 : number,address */
/* 参数描述 : number写入的数据 */
/* 返回值 : 无 */
/**********************************************************/
void display(int number)
{
unsigned charb,c,d,e;
b=(number/1000);c=(number/100)%10;d=(number/10)%10;e=number%10;
DisplayOneChar(9,1,(0x30+b));
DisplayOneChar(10,1,(0x30+c));
DisplayOneChar(11,1,(0x30+d));
DisplayOneChar(13,1,(0x30+e));
}
/**********************************************************/
/* 函数名称 : Trig_SuperSonic */
/* 函数描述 : 发出声波函数 */
/* 输入参数 : 无 */
/* 参数描述 : 无 */
/* 返回值 : 无 */
/**********************************************************/
void Trig_SuperSonic(void) //出发声波
{TRIG=1;delayt(1);TRIG=0;}
/**********************************************************/
/* 函数名称 : Measure_Distance */
/* 函数描述 : 计算距离函数 */
/* 输入参数 : 无 */
/* 参数描述 : 无 */
/* 返回值 : 无 */
/**********************************************************/
void Measure_Distance(void)
{
unsigned charl;
unsigned inth,y;
TR0=1;
while(ECHO){;}
TR0=0;l=TL0;h=TH0;
y=(h<<8)+l;
y=y-0xfc66; //us部分
distance=y+1000*count; //计算总时间
TL0=0x66;TH0=0xfc;
delayt(30);
distance=SPEED_30C*distance/20000;
}
/*********************写数据函数***************************/
void WriteDataLCD(unsigned char WDLCD)
{
ReadStatusLCD(); //检测忙
LCD_Data=WDLCD;
LCD_E=0; //若晶振速度太高可以在这后加小的延时
LCD_E=0; //延时
LCD_RS=1;
LCD_RW=0;
LCD_E=1;
LCD_E=0;
}
/***********************写指令函数*************************/
void WriteCommandLCD(unsigned char WCLCD,BuysC)//BuysC为0时忽略忙检测
{
if (BuysC)ReadStatusLCD(); //根据需要检测忙
LCD_Data=WCLCD;
LCD_E=0;
LCD_E=0;
LCD_RS=0;
LCD_RW=0;
LCD_E=1;
LCD_E=0;
}
/************************读数据函数************************/
unsigned char ReadDataLCD(void)
{
LCD_RS=1;
LCD_RW=1;
LCD_E=0;
LCD_E=0;
LCD_E=1;
return(LCD_Data);
}
/************************读状态函数************************/
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 LCDInit(void) //LCD初始化
{
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 LCD_Clear(void)
{WriteCommandLCD(0x01,1);Delay5Ms();}
/*******************按指定位置显示一个字符******************/
void DisplayOneChar(unsigned char X,unsigned charY,unsigned char DData)
{
Y&=0x1;
X&=0xF; //限制X不能大于15,Y不能大于1
if(Y)X|=0x40; //当要显示第二行时地址码+0x40;
X|=0x80; //算出指令码
WriteCommandLCD(X, 0); //这里不检测忙信号,发送地址码
WriteDataLCD(DData);
}
/********************按指定位置显示一串字符*****************/
void DisplayListChar(unsigned char X,unsigned charY,unsigned char code *DData)
{
unsigned charListLength;
ListLength=0;
Y&=0x1;X&=0xF; //限制X不能大于15,Y不能大于1
while(DData[ListLength]>=0x20) //若到达字串尾则退出
{
if(X<=0xF) //X坐标应小于0xF
{
DisplayOneChar(X, Y, DData[ListLength]); //显示单个字符
ListLength++;
X++;
}
}
}
/**********************************************************/
/* 函数名称 : main */
/* 函数描述 : 主函数 */
/* 输入参数 : 无 */
/* 参数描述 : 无 */
/* 返回值 : 无 */
/**********************************************************/
void main(void)
{
LCDInit();
Init_timer();
Init_Parameter();
Alarm(2);
DisplayListChar(0,0,table0);
DisplayListChar(0,1,table1);
while(1)
{
Trig_SuperSonic(); //触发超声波发射
while(ECHO==0){;} //等待回声
Measure_Distance(); //计算脉宽并转换为距离
DisplayListChar(0,1,table2);
display(distance); //显示距离
Init_Parameter(); //参数重新初始化
delayt(100); //延时,两次发射之间要至少有10ms间隔
}
}
/**********************************************************/
/* 函数名称 : timer0 */
/* 函数描述 : T0中断处理函数 */
/* 输入参数 : 无 */
/* 参数描述 : 无 */
/* 返回值 : 无 */
/**********************************************************/
void timer0 (void) interrupt 1
{
TF0=0;TL0=0x66;TH0=0xfc;count++;
if(count==18) //超声波回声脉宽最多18ms
{TR0=0;TL0=0x66;TH0=0xfc;count=0;}
}