zoukankan      html  css  js  c++  java
  • 基于51单片机的超声波模块HC-SR04的使用

    超声波模块工作原理:

         (1)采用IO触发测距,给至少10us的高电平信号;

           (2)模块自动发送8个40khz的方波,自动检测是否有信号返回;

        (3)有信号返回,通过IO输出一高电平,高电平持续的时间就是

              超声波从发射到返回的时间.测试距离=(高电平时间*声速(340M/S))/2; 

    定时器初始化:

    考虑到原理(3)有信号返回时输出一个高电平,所以TMOD设置为0x09,GATE=1(需要TR0和中断0(INT0)口都=0,中断才会启动),然后用杜邦线将中断0的引脚和超声波模块的I0口(echo口)连接,这样当超神波返回时,echo=1,INT0=1,中断启动。

    我试过将初始设置为10us和100us两种,10us时,s=vt,100us时,s=vt/2,按照公式s=vt/2才是正确的,但是我10us时,值相差也不大,不知道什么原因,但是这个不对,所以下面代码中,用的是100us这个。

    ------------------------------------------------分割线----------------------------------------------------------------

     

    #include "reg52.h"
    
    typedef unsigned char uchar;
    typedef unsigned int uint;
    
    sbit trig=P2^0;
    sbit echo=P2^1;
    sbit beep=P1^5;
    
    sbit LSA=P2^2;
    sbit LSB=P2^3;
    sbit LSC=P2^4;
    
    uint num=0;           //计时
    float distance;       //距离
    float cm_per_num=3.40; //按照我的定时器初始化设定,1个num是100us
    uchar DisplayData[6];
    uchar code smgduan[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
                        0x7f,0x6f};//显示0~9的值
    
    void delay1ms(uchar xms)   
    {
        uchar a,b,c;
        for(c=xms;c>0;c--)
            for(b=142;b>0;b--)
                for(a=2;a>0;a--);
    }
    
     /*
    设置工作方式为方式1,GATE=1,当中断0口输入1且TR0=1 时定时器工作
    因为超声波模块的工作原理就是在接收回波时,从开始到结束,ech0=1
    所以在单片机上用杜邦线将ech0的P21口和 中断0口 P32口链接
    使得在回波期间,定时器工作,计算回波的时间,进而s=vt算出距离 
     */
    void TimerInit()      //初始化,定时10us
    {
        TMOD = 0x09;     
        TH0 = 0xFF;
        TL0 = 0x9C;
        EA = 1;
        ET0 = 1;
        TR0 = 1;
    }
    
    void Timer0() interrupt 1      //中断 每过100us,num+1
    {
        TH0 = 0xFF;
        TL0 = 0x9C;
        num++;
    }
    
    void value_distance()
    {
        trig=0;
        echo=0;
        delay1ms(1);
        trig=1;
        delay1ms(11); //给trig一个10us以上的高电平信号
        trig=0;
        if(echo==1)       //如果有反射回的超声波,echo脚会在这期间持续输入高电平
        {
            delay1ms(300);        //接收超声波期间不做任何动作。
        }
        distance=num*cm_per_num/2;   //计算距离,单位CM
        num=0;
            
    }
    
    void datapros()             //对取得的距离进行处理
    {
        float a= distance*100;    
        DisplayData[0]=smgduan[(int)a%10];
        DisplayData[1]=smgduan[(int)a%100/10];
        DisplayData[2]=smgduan[(int)a%1000/100]+0x80;     //数字+小数点
        DisplayData[3]=smgduan[(int)a%10000/1000];
        DisplayData[4]=smgduan[(int)a/10000];    
            
    }
    
    void DigDisplay()               //数码管显示
    {
        uchar i;
        for(i=0;i<6;i++)
        {
            switch(i)     //位选,选择点亮的数码管,
            {
                case(0):
                    LSA=0;LSB=0;LSC=0; break;//显示第0位
                case(1):
                    LSA=1;LSB=0;LSC=0; break;//显示第1位
                case(2):
                    LSA=0;LSB=1;LSC=0; break;//显示第2位
                case(3):
                    LSA=1;LSB=1;LSC=0; break;//显示第3位
                case(4):
                    LSA=0;LSB=0;LSC=1; break;//显示第4位
                case(5):
                    LSA=1;LSB=0;LSC=1; break;//显示第5位
            }
            P0=DisplayData[i];//发送段码
            delay1ms(1); //间隔一段时间扫描    
            P0=0x00;//消隐
        }
    }
    
    void main()
    {
        while(1)
        {
            TimerInit();
            value_distance();
            datapros();
            DigDisplay();
        }
    }

     

     

     

     

     

     

     

  • 相关阅读:
    《深入了解 Linq to SQL》之对象的标识 —— 麦叔叔呕心呖血之作
    闲聊吉日与水军
    谈谈需求的变更
    ALinq BUG & 版本发布
    Linq to SQL (ALinq) 也来AOP —— ALinq Inject 博客园首发
    使用Orachard与Bootstrap建站心得
    一位软件作者的吐嘈——读《Google Reader猝死启示录:互联网无法永远免费》有感
    被神化的架构和被夸大的CTRL+C、CTRL+V
    我对程序员技能的一些认识
    又见ORM跑分 —— 对ORM跑分的吐嘈
  • 原文地址:https://www.cnblogs.com/hexia7935/p/13983123.html
Copyright © 2011-2022 走看看