郭天祥51开发板——超声波测距+lcd1602

使用超声波模块实现测距功能,测量结果显示在LCD1602上、并通过串口发送给电脑,测量距离大于或小于5~400cm,LCD1602显示“Waring!”同时蜂鸣器报警、串口发送“Waring”。

超声波测距原理

超声波测距的方法有很多种,最常用的是脉冲回波法。原理框图如图,
郭天祥51开发板——超声波测距+lcd1602_第1张图片
超声波传感器发射超声波,在空气中传播至被测目标,经反射后由超声波传感器接收反射脉冲,测量出超声波脉冲从发射到接收的时间,经过计算 S=1/2vt 可以得到距离。h较小时,S≈d ,所以通过测量超声波往返时间,就可以计算出距离长短。

HC-SR04模块

工作原理:采用IO触发测距,给trig至少10us的高电平信号;
模块自动发送8个40khz的方波,自动检测是否有信号返回;有信号返回,通过IO输出一高电平,高电平持续的时间就是超声波从发射到返回的时间。
时序图如下图所示:
郭天祥51开发板——超声波测距+lcd1602_第2张图片
具体实现,控制口发一个10us以上的高电平,就可以在接收口等待高电平输出。一有输出就可以开定时器计时,当接收口变为低电平时就可以读定时器的值,此时就为此次测距的时间,从而算出距离。如此不断地周期测量,就可以达到移动测量的值。

代码

#include	
#include
sbit trig=P1^1;		                //控制端口定义
sbit echo=P1^0;		                //接收端口定义
sbit RS=P3^5;	                    //lcd1602数据/命令端
sbit EN=P3^4; 	                    //使能端
sbit U1=P2^6;                       //数码管段选
sbit U2=P2^7;                       //数码管位选
sbit bi=P2^3;                       //buzz

unsigned char str[]={"Distance:"};      //lcd显示字符串
unsigned char juli[]={"0000cm"};        //lcd距离显示字符串
unsigned char change[]={"\r\n"};        //串口打印换行符
unsigned char jg[]={"Waring"};          //串口打印
unsigned int time;	                    //时间
unsigned long s;	                    //距离
bit flag=0;                             //标志位(定时器)
bit flag1=0;                            //标志位(串口打印)

void delayms(unsigned int xms);         //延时
void buzz();                            //蜂鸣器
void wcmd(unsigned char cmd)            //写命令
{
    RS = 0;                     
    P0 = cmd;
	delayms(5);
    EN = 1;
	delayms(5);
    EN = 0;    
}
void wdat(unsigned char dat)            //写数据
{
	RS = 1;
	P0 = dat;
	delayms(5);
	EN = 1;
	delayms(5);
	EN = 0;
}  
void Init()                             //1602初始化
{	U1=0;                           
    U2=0;
    EN=0;
    wcmd(0x38);                         //功能设置:8位,2行,5*7
    wcmd(0x0c);                         //显示控制:显示,有光标,闪烁
    wcmd(0x06);                         //输入模式:光标右移,屏不移位
    wcmd(0x01);                         //清屏   
}

void wstr(unsigned char addr,unsigned char *p)  
{
    wcmd(addr);     
    while(*p!='\0')  
    {   wdat(*p);   
        p++;        
    }    
}
void start()                            //超声波发送模块
{   
    trig=1;			                    
    _nop_();
    _nop_();
    _nop_();
    _nop_();
    _nop_();
    _nop_();
    _nop_();
    _nop_();
    _nop_();
    _nop_();
    _nop_();
    _nop_();
    trig=0;			             
} 
void count()                            //距离计算
{   time=TH0*256+TL0;				
    s=time*1.7/100;				    
    if((s>400)||(s<5)||(flag==1) )
    {   wstr(0xC0,"Waring!");
        buzz();
        flag1=1;
    }
    else								
    {
        juli[3] = s%10+0x30;				
        juli[2] = s/10%10+0x30;			
        juli[1] = s/100%10+0x30;		    
        juli[0] = s/1000+0x30;				
        wstr(0xC0,"       ");
        wstr(0xC0,juli);
        flag1=0;
    }
    TH0=0x00;						
    TL0=0x00;						
    flag=0;							
 }
void uart()                             //串口
{   
    TMOD |= 0x20;                       //定时器模式1  
    TH1 = 0xFD;                         //波特率9600    
    TL1 = 0xFD;
    TR1 = 1;                            //打开定时器
    REN = 1;                            //允许串行接收
    SM0 = 0;                            //串行口工作方式1
    SM1 = 1;                            
    ES = 1;                             //允许串行中断
}
void main()
{   
    unsigned char i,j;
    Init();			                    //LCD初始化
    wstr(0x80,str);	   
    TMOD=0x01;			   
    TH0=0x00;			   
    TL0=0x00;			   
    EA=1;			       
    ET0=1;	
    uart();                             //串口初始化
    while(1)
    {
        start();			            
        while(echo==0);                 //接收到才打开定时器
        TR0=1;			   
        while(echo==1);                 //接收不到后就关闭定时器
        TR0=0;			   
        count();			   
        delayms(1000);
        for(i=0;i<=5;i++)
        {   
            if(flag1==0)
            {   SBUF=juli[i];
                while(TI==0);           //发完后TI会被置为1
                TI = 0;                 //TI置为0,为了下一次传输
            }
            else
            {   
                SBUF=jg[i];
                while(TI==0);
                TI = 0;
                
            }
        }
        for(j=0;j<=3;j++)
        {
            SBUF=change[j];
            while(TI==0);
            TI = 0;
        }
    }
}
void buzz()
{
    bi=0;
    delayms(200);
    bi=1;
}
void delayms(unsigned int xms)     
{ 
    unsigned int i,j;
    for(i=xms;i>0;i--)
        for(j=110;j>0;j--);
}
void InterruptTimer0() interrupt 1			  
{
    flag=1;					
}

开发板效果图

郭天祥51开发板——超声波测距+lcd1602_第3张图片郭天祥51开发板——超声波测距+lcd1602_第4张图片
郭天祥51开发板——超声波测距+lcd1602_第5张图片

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