15717|10

9

帖子

0

TA的资源

一粒金砂(初级)

楼主
 

HC-SR04如何测距 [复制链接]

怎么使用HC-SR04模块测距呢,网上好多程序都试了,都不行,求教
此帖出自51单片机论坛

最新回复

上网找个1602显示距离的,打吧  详情 回复 发表于 2017-8-8 11:53
点赞 关注
 

回复
举报

4008

帖子

0

TA的资源

版主

沙发
 
时间差折算成距离就是了
此帖出自51单片机论坛

点评

我也是这样,不过还是得不到结果,以下是我的程序,麻烦帮看下有什么问题 #include //包括一个52标准内核的头文件 #include #include "lcd1602.h" //1602LCD的头文件,这个没问题 #define uchar unsigned  详情 回复 发表于 2014-8-11 09:35
 
 
 

回复

9

帖子

0

TA的资源

一粒金砂(初级)

板凳
 
huo_hu 发表于 2014-8-10 22:39
时间差折算成距离就是了

我也是这样,不过还是得不到结果,以下是我的程序,麻烦帮看下有什么问题

#include      //包括一个52标准内核的头文件
#include
#include "lcd1602.h"    //1602LCD的头文件,这个没问题
#define uchar unsigned char //定义一下方便使用
#define uint  unsigned int
#define ulong unsigned long
sbit Trig  = P3^3; //产生脉冲引脚
sbit Echo  = P3^2; //回波引脚
sbit VCC = P1^1;
sbit GND = P1^0;
uchar count = 0;
uchar time = 0;
uint distance[4];  //测距接收缓冲区
uchar ge,shi,bai,temp,flag,outcomeH,outcomeL,i;  //自定义寄存器
bit succeed_flag;  //测量成功标志
//********函数声明
void conversion(uint temp_data);
void delay_20us();
void Init_timer();  //初始化定时器

void main(void)   // 主程序
{  
uint distance_data;
uint t = DELAY;
delay_20us();
Init_timer();
lcd1602_Init();
Trig=0;       //首先拉低脉冲输入引脚
VCC = 1;
GND = 0;

while(1)         //程序循环
{
     TH0=0x3c; //写入定时器0初始值
  TL0=0xb0;
  count = 0;

  Trig=1;
  delay_20us();
  Trig=0;         //产生一个20us的脉冲,在Trig引脚
  while(!Echo);  //等待Echo回波引脚变高电平
  TR0 = 1;
  while(Echo);
  TR0 = 0;     
  
  
  outcomeH =TH0;    //取出定时器的值
  outcomeL =TL0;    //取出定时器的值
  succeed_flag = 1;

     distance_data=outcomeH;                //测量结果的高8位
     distance_data<<=8;                   //放入16位的高8位
     distance_data=distance_data|outcomeL;//与低8位合并成为16位结果数据
     distance_data = count * 50 * 1000 + distance_data - (0x3c << 8) - 0xb0;
     distance_data/=58;                   //微秒的单位除以58等于厘米
            //为什么除以58等于厘米,  Y米=(X秒*344)/2
                                          // X秒=( 2*Y米)/344 ==》X秒=0.0058*Y米 ==》厘米=微秒/58
   

  conversion(distance_data);
  lcd1602_WriteComm(0x80);
  lcd1602_WriteData('0' + bai);
  lcd1602_WriteData('.');
  lcd1602_WriteData('0' + shi);
  lcd1602_WriteData('0' + ge);         
}
}

//****************************************************************
//定时器0中断,用做计数,12M每次定时50ms
void timer0() interrupt 1  // 定时器0中断是1号
{
EA = 0;
TH0=0x3c; //写入定时器0初始值
TL0=0xb0;
count++;
EA = 1;
}

//显示数据转换程序
void conversion(uint temp_data)  
{  
    uchar ge_data,shi_data,bai_data ;
    bai_data=temp_data/100 ;
    temp_data=temp_data%100;   //取余运算
    shi_data=temp_data/10 ;
    temp_data=temp_data%10;   //取余运算
    ge_data=temp_data;
    bai = bai_data;
    shi = shi_data;
    ge  = ge_data ;
}


void delay_20us()
{  
_nop_();_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();nop_();_nop_();_nop_();
}

void Init_timer()
{
TMOD=0x01;   //定时器0,16位工作方式
TH0=0x3c; //写入定时器0初始值
TL0=0xb0;
TR0 = 0;

TF0 = 0;
ET0 = 1;        //打开定时器0中断
EA=1;         //打开总中断0  
}
此帖出自51单片机论坛
 
 
 

回复

5

帖子

0

TA的资源

一粒金砂(初级)

4
 
这个帖子有人顶吗 问题你解决了吗
此帖出自51单片机论坛
 
 
 

回复

1

帖子

0

TA的资源

一粒金砂(初级)

5
 
楼主请问有调试好的测距程序吗?
此帖出自51单片机论坛
 
 
 

回复

932

帖子

3

TA的资源

纯净的硅(中级)

6
 
Jzeng123 发表于 2016-4-18 14:30
这个帖子有人顶吗 问题你解决了吗

都快两年了,楼主的问题早就应该解决了。
此帖出自51单片机论坛
 
 
 

回复

932

帖子

3

TA的资源

纯净的硅(中级)

7
 
我也正在做测距的程序,正好可以参考这些代码。
此帖出自51单片机论坛
 
 
 

回复

237

帖子

0

TA的资源

一粒金砂(中级)

8
 
本帖最后由 jinxiang 于 2016-11-24 11:25 编辑

我在贴一个  测试通过来源网络
SMC1602A(16*2)模拟口线接线方式
连接线图:        
       ---------------------------------------------------
       |LCM-----51   |        LCM-----51   |        LCM------51      |
       --------------------------------------------------|
       |DB0-----P0.0 |        DB4-----P0.4 |        RW-------P2.3    |
       |DB1-----P0.1 |        DB5-----P0.5 |        RS------- P2.4    |
       |DB2-----P0.2 |        DB6-----P0.6 |        E--------  P2.2    |
       |DB3-----P0.3 |        DB7-----P0.7 |        VLCD接3K电阻到GND|
       ---------------------------------------------------
接线:模块TRIG接 P3.7  ECH0 接P3.6
=============================================================*/
#include                 //器件配置文件
#include
#define  RX  P3_6
#define  TX  P3_7

#define LCM_RW  P2_3 //定义LCD引脚
#define LCM_RS  P2_4
#define LCM_E   P2_2
#define LCM_Data  P0

#define Busy    0x80 //用于检测LCM状态字中的Busy标识

void LCMInit(void);
void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData);
void DisplayListChar(unsigned char X, unsigned char Y, unsigned char code *DData);
void Delay5Ms(void);
void Delay400Ms(void);
void Decode(unsigned char ScanCode);
void WriteDataLCM(unsigned char WDLCM);
void WriteCommandLCM(unsigned char WCLCM,BuysC);

unsigned char ReadDataLCM(void);
unsigned char ReadStatusLCM(void);
unsigned char code mcustudio[] ={"==Range Finder=="};
unsigned char code email[] =    {"heyaodz@163.com "};
unsigned char code Cls[] =      {"                "};
unsigned char code ASCII[15] =    {'0','1','2','3','4','5','6','7','8','9','.','-','M'};

static unsigned char DisNum = 0; //显示用指针                                 
       unsigned int  time=0;
           unsigned long S=0;
           bit      flag =0;
           unsigned char disbuff[4]           ={ 0,0,0,0,};


//写数据
void WriteDataLCM(unsigned char WDLCM)
{
        ReadStatusLCM(); //检测忙
        LCM_Data = WDLCM;
        LCM_RS = 1;
        LCM_RW = 0;
        LCM_E = 0; //若晶振速度太高可以在这后加小的延时
        LCM_E = 0; //延时
        LCM_E = 1;
}

//写指令
void WriteCommandLCM(unsigned char WCLCM,BuysC) //BuysC为0时忽略忙检测
{
        if (BuysC) ReadStatusLCM(); //根据需要检测忙
        LCM_Data = WCLCM;
        LCM_RS = 0;
        LCM_RW = 0;        
        LCM_E = 0;
        LCM_E = 0;
        LCM_E = 1;        
}

//读数据
unsigned char ReadDataLCM(void)
{
        LCM_RS = 1;
        LCM_RW = 1;
        LCM_E = 0;
        LCM_E = 0;
        LCM_E = 1;
        return(LCM_Data);
}

//读状态
unsigned char ReadStatusLCM(void)
{
        LCM_Data = 0xFF;
        LCM_RS = 0;
        LCM_RW = 1;
        LCM_E = 0;
        LCM_E = 0;
        LCM_E = 1;
        while (LCM_Data & Busy); //检测忙信号
        return(LCM_Data);
}

void LCMInit(void) //LCM初始化
{
        LCM_Data = 0;
        WriteCommandLCM(0x38,0); //三次显示模式设置,不检测忙信号
        Delay5Ms();
        WriteCommandLCM(0x38,0);
        Delay5Ms();
        WriteCommandLCM(0x38,0);
        Delay5Ms();

        WriteCommandLCM(0x38,1); //显示模式设置,开始要求每次检测忙信号
        WriteCommandLCM(0x08,1); //关闭显示
        WriteCommandLCM(0x01,1); //显示清屏
        WriteCommandLCM(0x06,1); // 显示光标移动设置
        WriteCommandLCM(0x0F,1); // 显示开及光标设置
}

//按指定位置显示一个字符
void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData)
{
        Y &= 0x1;
        X &= 0xF; //限制X不能大于15,Y不能大于1
        if (Y) X |= 0x40; //当要显示第二行时地址码+0x40;
        X |= 0x80; //算出指令码
        WriteCommandLCM(X, 1); //发命令字
        WriteDataLCM(DData); //发数据
}

//按指定位置显示一串字符
void DisplayListChar(unsigned char X, unsigned char Y, unsigned char code *DData)
{
        unsigned char ListLength;

  ListLength = 0;
        Y &= 0x1;
        X &= 0xF; //限制X不能大于15,Y不能大于1
        while (DData[ListLength]>0x19) //若到达字串尾则退出
                {
                        if (X <= 0xF) //X坐标应小于0xF
                                {
                                        DisplayOneChar(X, Y, DData[ListLength]); //显示单个字符
                                        ListLength++;
                                        X++;
                                }
                }
}

//5ms延时
void Delay5Ms(void)
{
        unsigned int TempCyc = 5552;
        while(TempCyc--);
}

//400ms延时
void Delay400Ms(void)
{
        unsigned char TempCycA = 5;
        unsigned int TempCycB;
        while(TempCycA--)
                {
                        TempCycB=7269;
                        while(TempCycB--);
                };
}
/********************************************************/
    void Conut(void)
        {
         time=TH0*256+TL0;
         TH0=0;
         TL0=0;
        
         S=(time*1.8)/10;     //算出来是MM
         if((S>=7000)||flag==1) //超出测量范围显示“-”
         {         
          flag=0;
         
          DisplayOneChar(0, 1, ASCII[11]);
          DisplayOneChar(1, 1, ASCII[10]);        //显示点
          DisplayOneChar(2, 1, ASCII[11]);
          DisplayOneChar(3, 1, ASCII[11]);
          DisplayOneChar(4, 1, ASCII[11]);
          DisplayOneChar(5, 1, ASCII[12]);        //显示M
         }
         else
         {
          disbuff[0]=S/1000;
          disbuff[1]=S/100%10;
          disbuff[2]=S/10%10;
          disbuff[3]=S%10;
          DisplayOneChar(0, 1, ASCII[disbuff[0]]);
          DisplayOneChar(1, 1, ASCII[10]);        //显示点
          DisplayOneChar(2, 1, ASCII[disbuff[1]]);
          DisplayOneChar(3, 1, ASCII[disbuff[2]]);
          DisplayOneChar(4, 1, ASCII[disbuff[3]]);
          DisplayOneChar(5, 1, ASCII[12]);        //显示M
         }
        }
/********************************************************/
     void zd0() interrupt 1                  //T0中断用来计数器溢出,超过测距范围
  {
    flag=1;                                                         //中断溢出标志
        RX=0;
  }
/********************************************************/
     void  StartModule()                          //启动模块
  {
          TX=1;                                             //启动一次模块
          _nop_();
          _nop_();
          _nop_();
          _nop_();
          _nop_();
          _nop_();
          _nop_();
          _nop_();
          _nop_();
          _nop_();
          _nop_();
          _nop_();
          _nop_();
          _nop_();
          _nop_();
          _nop_();
          _nop_();
          _nop_();
          _nop_();
          _nop_();
          _nop_();
          TX=0;
  }
void Timer_Count(void)
{
                 TR0=1;                            //开启计数
             while(RX);                        //当RX为1计数并等待
             TR0=0;                                //关闭计数
         Conut();                        //计算

}

/********************************************************/
void delayms(unsigned int ms)
{
        unsigned char i=100,j;
        for(;ms;ms--)
        {
                while(--i)
                {
                        j=10;
                        while(--j);
                }
        }
}
/*********************************************************/
void main(void)
{
    unsigned int valA;
        unsigned char TempCyc;
        Delay400Ms(); //启动等待,等LCM讲入工作状态
        LCMInit(); //LCM初始化
        Delay5Ms(); //延时片刻(可不要)
        DisplayListChar(0, 0, mcustudio);
        DisplayListChar(0, 1, email);
        ReadDataLCM();//测试用句无意义
        for (TempCyc=0; TempCyc<10; TempCyc++)
        Delay400Ms(); //延时
        DisplayListChar(0, 1, Cls);        
         TMOD=0x01;                   //设T0为方式1,GATE=1;
         TH0=0;
         TL0=0;                                                                                                                       
         ET0=1;             //允许T0中断
         EA=1;                           //开启总中断                        
        
         while(1)
          {
               
                delayms(60);
                RX=1;
            StartModule();
        for(valA=7510;valA>0;valA--)
            {
                  
               if(RX==1)
                   {
           Timer_Count();
                   }
             }
          }
}



               
此帖出自51单片机论坛
 
 
 

回复

62

帖子

0

TA的资源

一粒金砂(中级)

9
 
我有50对40kHz超声传感器,谁要,可联系zzlls@126.com
此帖出自51单片机论坛
 
 
 

回复

5

帖子

0

TA的资源

一粒金砂(初级)

10
 
hujj 发表于 2016-7-13 10:54
都快两年了,楼主的问题早就应该解决了。

有道理哈,不过我现在不搞单片机啦~~~
此帖出自51单片机论坛
 
 
 

回复

15

帖子

0

TA的资源

一粒金砂(初级)

11
 
上网找个1602显示距离的,打吧
此帖出自51单片机论坛
 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/7 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表