基于AT89C51单片机的超声波传感器测距【程序详细代码及注释】

基于AT89C51单片机的超声波HC-SR04测距 LCD1604显示

硬件介绍

引脚四个,分别为VCC、TRIG、ECHO、GND
VCC 供 5V 电源, GND 为地线
TRIG 触发控制信号输入
ECHO 回响信号输出等 四个接口端
基于AT89C51单片机的超声波传感器测距【程序详细代码及注释】_第1张图片

超声波时序图

基于AT89C51单片机的超声波传感器测距【程序详细代码及注释】_第2张图片
以上时序图表明你只需要提供一个 10uS 以上脉冲触发信号,该模块内部将 发出 8 个 40kHz 周期电平并检测回波。一旦检测到有回波信号则输出回响信号。 回响信号的脉冲宽度与所测的距离成正比。由此通过发射信号到收到的回 响信号时间间隔可以计算得到距离。
公式:uS/58=厘米或者 uS/148=英寸; 或是:距离= 高电平时间*声速(340M/S)/2;建议测量周期为 60ms 以上, 以防止发射信号对 回响信号的影响。

注:
1、此模块不宜带电连接,若要带电连接,则先让模块的 GND 端先连接,否则 会影响模块的正常工作。
2、测距时,被测物体的面积不少于 0.5 平方米且平面尽量要求平整,否则影响 测量的结果

程序代码

/******************************************************************************/                              
/* 主控芯片  : STC89C52                                                       */
/* 文件名称  : UltraSonic                                                     */
/* 文件功能  : 超声波模块操作                                                 */
/*  注 :需要用杜邦线把超声波模块的 
VCC----VCC TRIG---P1.6 ECHO---P1.7 GND----GND 相连                            */                                                 
/******************************************************************************/
/**********************************包含头文件**********************************/
#include 
#include "1602.h"
/************************************宏定义************************************/
#define VELOCITY_30C	3495       //30摄氏度时的声速,声速V= 331.5 + 0.6*温度; 
#define VELOCITY_23C	3453       //23摄氏度时的声速,声速V= 331.5 + 0.6*温度; 
/************************************位定义************************************/
sbit Echo  = P1^6;                //回声接收端口
sbit Trig = P1^7;                //超声触发端口
sbit Beep   = P2^3 ;			   // 蜂鸣器 
/********************************定义变量和数组********************************/
long int distance=0;               //距离变量
uchar table[]="    Welcome to   ";
uchar table0[]="   626's home   ";
uchar table1[]="There's no echo.";
uchar table2[]="   UltraSonic   ";
uchar table3[]="Distance:";
uchar count;
/***********************************函数声明***********************************/
extern void initLCD();
extern void write_date(uchar date);
extern void write_com(uchar com);
extern void delay(uint x);
/******************************************************************************/
/* 函数名称  : Delay_xMs                                                      */
/* 函数描述  : 延时函数,单位毫秒                                                       */
/* 输入参数  : x                                                              */
/* 参数描述  : 延时时间                                                       */
/* 返回值    : 无                                                             */
/******************************************************************************/
void Delay_xMs(unsigned int x)
{
    unsigned int i,j;
    for(i = 0;i < x;i++ )
    {
        for(j = 0;j < 3;j++ )
        {
            ;
        }
    }
}
/******************************************************************************/
/* 函数名称  : Alarm                                                          */
/* 函数描述  : 蜂鸣器发声函数                                                 */
/* 输入参数  : t                                                              */
/* 参数描述  : 发声的次数                                                     */
/* 返回值    : 无                                                             */
/******************************************************************************/
void Alarm(uchar t)
{
	uchar i;
	for(i = 0;i < t;i++)
	{
		Beep = 0;
		Delay_xMs(1000);
		Beep = 1;
		Delay_xMs(1000);
	}
}	
/******************************************************************************/
/* 函数名称  : delayt                                                         */
/* 函数描述  : 延时函数   延时0.1ms                                                    */
/******************************************************************************/	
void delayt(uint x)
{
    uchar j;
    while(x-- > 0)
    {
  	    for(j = 0;j < 125;j++)
        {
            ;
        }
    }
}
/******************************************************************************/
/* 函数名称  : Init_MCU                                                       */
/* 函数描述  : 初始化单片机函数                                               */

/*当晶振频率为11.0592M的晶振。
则每秒可产生机器周期为11.0592/12=0.9216M的机器周期,也就是921600个机器周期。
1ms等于0.001秒,所以需要921600*0.001=922个机器周期;
定时器在方式1工作,为16位,最大值为65536,
所以需设初值为65536-922=64614;转为16进制为(FC66),所以高位TH0=0xFC; TL0=0x66
*****************************************************************************/
void Init_MCU(void)
{
	TMOD = 0x01;	  //定时器2初始化,设置为16位自动重装模式
 	TH0 = 0xfc;	      //1ms	 (65536-922)/256		高八位求模(除法)
	TL0 = 0x66;		  //     (65536-922)%256		低八位求余
    ET0 = 1;	      //开定时器2
	EA = 1;		      //总中断使能
}
/******************************************************************************/
/* 函数名称  : Init_Parameter                                                 */
/* 函数描述  : 初始化参数和IO口函数                                           */
/******************************************************************************/
void Init_Parameter(void)
{
	 Trig =1;	  //Trig  触发控制信号输入
	 Echo = 1;	  //Echo  回响信号输出
	 count = 0;
	 distance = 0;
}
/******************************************************************************/
/* 函数名称  : display_char                                                   */
/* 函数描述  : 显示字符串函数                                                 */
/* 输入参数  : point,address                                                  */
/* 参数描述  : 写入的字符串的地址指针 1602显示对应的地址                      */
/* 返回值    : 无                                                             */
/******************************************************************************/
void display_char(uchar *point,uchar address)
{
	uchar i;
	write_com(0x80 + address);
	for(i = 0;i < 16; i++)
	{
		write_date(*point);	  //从指针指向的地址取数据
		point++;			  //指针+1
	}
}
/******************************************************************************/
/* 函数名称  : display                                                        */
/* 函数描述  : 显示数字                                                       */
/* 输入参数  : number,address                                                */
/* 参数描述  : number写入的数据,address地址                                  */
/* 返回值    : 无                                                             */
/******************************************************************************/	
void display(int number,uchar address)
{
	uchar b,c,d,e;
	b= (number / 1000);
	c= (number / 100) % 10;
	d = (number / 10) % 10;
	e = number % 10;

	write_com(0x80 + address);
    write_date(b + 48);		 //+48为了得到这个数字的ASCII码,这样才能显问示到液晶上
	write_date(c + 48);
	write_date(d + 48);
	write_date(46);           //小数点的ASCII
	write_date(e + 48);
    write_date(99);           //"c"的ASCII
	write_date(109);          //"m"的ASCII
}
/******************************************************************************/
/* 函数名称  : Trig_SuperSonic                                                */
/* 函数描述  : 发出声波函数                                                   */
/******************************************************************************/
void Trig_SuperSonic(void)//出发声波
{
	 Trig = 1; //发送trig信号
	 delayt(1);	 //延时0.1ms
	 Trig = 0; //发送trig信号完毕
}
/******************************************************************************/
/* 函数名称  : Measure_Distance                                               */
/* 函数描述  : 计算距离函数                                                   */
/******************************************************************************/
void Measure_Distance(void)
{
	uchar l;
	uint h,y;
	TR0 = 1;          //启动定时器0,收到回声则开始计时
	while(Echo)	  //
    {
        ;
    }	
	TR0 = 0;
	l = TL0;		//把定时器0低8位装入L
	h = TH0;		//把定时器0高8位装入h
	y = (h << 8) + l;	         //将计数值转换为16位(把h向左移八位加上低八位
	y = y - 0xfc66;              //us(微秒)部分,不足1ms的时间
	distance = y + 1000 * count; //计算总时间(定时器一次1ms) 单位:us
	TL0 = 0x66;
	TH0 = 0xfc;
	delayt(30);
	distance = VELOCITY_30C * distance / 20000;	 
	// 声速(m/s)*高电平时间(us)/2   再换算成厘米
}	// 为了能取小数点后一位,所以声速多一位
/******************************************************************************/
/* 函数名称  : main                                                           */
/* 函数描述  : 主函数                                                         */
/******************************************************************************/		

			
void main(void)
{
	initLCD();
	Init_MCU();
	Init_Parameter();
	Alarm(2);
	display_char(table,0x00);
	display_char(table0,0x40);
	Delay_xMs(30000);
	display_char(table2,0x00);
	display_char(table1,0x40);
	Delay_xMs(30000);
	while(1)
	{
		 Trig_SuperSonic();         //触发超声波发射
		 while(Echo == 0)          //等待回声 如果有回波则Echo=1 则跳出循环开始计时
         {
             ;
         }
		 Measure_Distance();        //计算脉宽并转换为距离
		 display_char(table3,0x40);
		 display(distance,0x49);    //显示距离
		 Init_Parameter();          // 参数重新初始化
		 delayt(600);               //延时,两次发射之间要至少有60ms间隔
	 }	
}
/******************************************************************************/
/* 函数名称  : timer0                                                         */
/* 函数描述  : 定时器0                                                 */
/******************************************************************************/
void timer0 (void) interrupt 1
{
	TF0 = 0;
	TL0 = 0x66;
	TH0 = 0xfc;		//1ms
	count++;
	if(count == 18) //超声波回声脉宽最多18ms
	{
		TR0 =0;
		TL0 = 0x66;
		TH0 = 0xfc;
		count = 0;
	}
}


1602.h代码

/******************************************************************************/
/* 项目名称  :  超声波测距                                         */
/* 主控芯片  : STC89C52                                                       */
/* 文件名称  : 1602                                                           */
/* 文件功能  : 1602液晶操作                                                   */                                                             
/******************************************************************************/
/************************************宏定义************************************/
#define uchar unsigned char
#define uint unsigned int
/************************************位定义************************************/
sbit dula  = P2^6;
sbit wela  = P2^7;
sbit rs    = P3^5;
sbit lcden = P3^4;
/******************************************************************************/
/* 函数名称  : delay                                                          */
/* 函数描述  : 延时函数                                                       */
/******************************************************************************/
void delay(uint x)
{
	uint a,b;
	for(a = x;a > 0;a--)
    {
		for(b = 10;b > 0;b--) 
        {
            ;
        }
    }
}
/******************************************************************************/
/* 函数名称  : write_com                                                      */
/* 函数描述  : 1602写命令函数                                                 */
/* 输入参数  : com                                                            */
/* 参数描述  : 控制命令                                                       */
/* 返回值    : 无                                                             */
/******************************************************************************/
void write_com(uchar com)
{
	P0 = com;
	rs = 0;
	lcden = 0;
	delay(10);
	lcden = 1;
	delay(10);
	lcden = 0;	
}
/******************************************************************************/
/* 函数名称  : write_date                                                     */
/* 函数描述  : 1602写数据函数                                                 */
/* 输入参数  : date                                                           */
/* 参数描述  : 要写入的数据                                                   */
/* 返回值    : 无                                                             */
/******************************************************************************/
void write_date(uchar date)
{
	P0 = date;
	rs = 1;
	lcden = 0;
	delay(10);
	lcden = 1;
	delay(10);
	lcden = 0;	
}
/******************************************************************************/
/* 函数名称  : initLCD                                                        */
/* 函数描述  : 1602初始化函数                                                 */
/******************************************************************************/
void initLCD(void)
{
	dula = 0;
	wela = 0;
	write_com(0x38);
	delay(20);
	write_com(0x0f);
	delay(20);
	write_com(0x06);
	delay(20);
	write_com(0x01);
	delay(20);	
}
/****************************/

你可能感兴趣的:(51单片机)