HY-SRF05超声波测距

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/hhye_l/article/details/50262717

1. 模块(OUT脚不知有什么用)

这里写图片描述

2. 工作原理

这里写图片描述

3. 时序图

这里写图片描述

4. 计算公式

这里写图片描述

5. 51测试源码,串口显示

/**********************************************************************************
* 功能:HY-SRF05超声波测距模块测试,通过串口打印
* 处理器:STC89C52RC
* 晶振:11.0592
* 编译环境:Keil uVision4
* 时间:2015-12-10
* 作者:ly
* 备注:Trig  ---  P1_0
*       Echo  ---  外部中断0(P3_2)
*       OUT   ---  
*       Vcc   ---  VCC
*       GND   ---  GND
**********************************************************************************/
#include <reg52.h>
#include <stdio.h>      //sprintf
#include <string.h>     //strlen
#include <intrins.h>    //_nop_ 

#define uint  unsigned int
#define uchar unsigned char


sbit TX   = P3^1;
sbit Trig = P1^0;

int   time;     //计算回响信号脉冲宽度



/******************************  初始化函数 *****************************************/
//外部中断0初始化(P3_2)
void int0_init(void)  
{
    IE0 = 0;  //外部中断0标志位清0
    IT0 = 1;  //外部中断0下降沿触发
    EX0 = 1;  //外部中断0允许         
}
//定时器0初始化
void time0_init(void)  
{
    TMOD |= 0x09;  //0000 1001: GATE门控开,只有 TRx==1 && INTx==1 才可启动T0,T0定时方式1(16位)
    TH0 = 0;  
    TL0 = 0;

    TF0 = 0;  //T0标志位清0 
    ET0 = 1;  //T0中断允许
    TR0 = 1;  //T0工作允许
}
//串口初始化
void uart_init(void)  
{
    SCON = 0x40;    //0100 0000:串行方式1
    TMOD |= 0x20;   //T1定时方式2(8位自动装入)
    TH1 = 0xFD;  TL1 = 0xFD;  //波特率:9600    
    ES = 0;         //串口中断禁止
    TR1 = 1;        //T1启动
}
void init(void)
{
    EA = 0;  //总中断禁止
    Trig = 0;
    uart_init();
    time0_init();
    int0_init();
    EA = 1;  //总中断允许
}
/************************************************************************************/

void delay15us(void)
{
    _nop_();  _nop_();  _nop_();
    _nop_();  _nop_();  _nop_();
    _nop_();  _nop_();  _nop_();
    _nop_();  _nop_();  _nop_();
    _nop_();  _nop_();  _nop_();
}
void delay15ms(void)
{   
    int i;
    for (i = 0; i < 1000; i++)
        delay15us();
}
void uart_send_char(uchar ch)  //串口发送一个Byte
{
    SBUF = ch;
    while (!TI);
    TI = 0;
}
void uart_send_string(uchar str[], uint len)  //串口发送字符串
{
    int i;
    for (i = 0; i < len; i++)
        uart_send_char(str[i]);
}


/* 主函数 */
void main(void)
{
    int i;
    float distance;     //距离
    uchar display[20];  //串口显示距离


    init();

    while (1)
    {
        //建议测量周期60ms以上,以防止发射信号对回响信号的影响
        for (i = 0; i < 4; i++)
            delay15ms();


        //发送触发信号(10us以上TTL脉冲),如果检测到回响,Echo(P3^2)将拉高,则T0开始计时
        Trig = 1;
        delay15us();
        Trig = 0;

        //等待Echo(P3^2)下降沿到来(回响信号脉冲)触发外部中断   
        time = 0;  i = 0;
        while (time==0 && i<=65536)  //直到time被中断计算出时间或者被标记计时溢出或者i超时
            i++;  //防止死循环

        if (i > 65536)  //一直监测不到回响,Echo(P3^2)没有拉高,超时
        {
            uart_send_string("time out", 8);
            uart_send_char(0x0A);  //换行/新行
            uart_send_char(0x0D);  //回车
            continue;
        }

        if (time == -1)  //计时溢出
        {
            uart_send_string("T0 overflow", 11);
            uart_send_char(0x0A);  //换行/新行
            uart_send_char(0x0D);  //回车
        }
        else
        {
            distance = time / 58.0;  //公式:uS / 58 = 厘米
            sprintf(display, "%f CM", distance);
            uart_send_string(display, strlen(display));
            uart_send_char(0x0A);  //换行/新行
            uart_send_char(0x0D);  //回车
        }
    }
}


/***************************  中断处理 ******************************/
// 外部中断0处理 
void int0() interrupt 0
{
    EA = 0;  //总中断禁止
    time = TH0 * 256 + TL0;  //回响时间
    TH0 = 0;  
    TL0 = 0;
    EA = 1;  //总中断允许
}
// 定时器0中断处理 
void time0() interrupt 1
{
    //进入到这里,说明计时溢出
    EA = 0;  //总中断禁止
    TH0 = 0;  
    TL0 = 0;
    time = -1;
    EA = 1;  //总中断允许
}
/********************************************************************/

6. 结果(串口助手之类软件)

这里写图片描述

猜你喜欢

转载自blog.csdn.net/hhye_l/article/details/50262717