肿瘤康复网,内容丰富有趣,生活中的好帮手!
肿瘤康复网 > 基于单片机的HC-SR04超声波模块测距仪设计(数码管显示)

基于单片机的HC-SR04超声波模块测距仪设计(数码管显示)

时间:2018-12-06 02:18:12

相关推荐

目录

功能要求一、材料准备工具:可能涉及到的元器件:二、硬件设计1、单片机最小系统电路2、数码管显示电路3、按键电路4、HC-SR04超声波模块电路5、报警电路6、硬件测试三、程序设计1、搭建工程2、数码管显示模块程序设计3、超声波测距模块程序设计4、按键模块程序设计5、报警模块程序设计6、定时器程序设计7、功能实现程序设计四、小结五、附录附录1:整体电路原理图附录2:元件清单附录3:资源分享

功能要求

(1)用单片机实现;

(2)用C语言编程;

(3)硬件电路板布局合理;

(4)用数码管显示器显示;

(5)距离测量范围是:10cm----100cm;

(6)误差小于8%;

(7)超过测距量程并报警;

(8)通过按键调节测距范围。

一、材料准备

工具:

电烙铁、万用表、STC烧写器、5V电源、PC机、Keil uVision5、AltiumDesigner 13.3.4、stc-isp程序烧写软件(可到STC官方网站下载:/index.htm)等。

可能涉及到的元器件:

最小系统:STC89C52RC单片机x1、12MHz有源晶振x1、10uF电解电容x1、22pFx2、10KΩ排阻x1、10KΩx1、数码管显示电路:四位共阴数码管x1、74HC573x1、220Ω电阻x8报警电路:5V有源蜂鸣器x1、S8550三极管x1、1KΩx1测距电路:HC-SR04超声波模块x1键盘输入:轻触开关x3其他原件:100mil插针若干、LEDx1、自锁开关x1

二、硬件设计

1、单片机最小系统电路

如图1所示,是单片机最小系统电路图。学过51单片机的人都知道单片机最小系统包括:晶振电路、复位电路、单片机芯片和电源,这里作大概讲解即可,想了解详细电路原理请另查资料。晶振电路是为单片机提供时钟源;复位电路是为了让单片机从头到尾重新执行一遍程序,为了方便调试笔者采用按键复位方式;单片机芯片采用国产的STC单片机,型号为STC89C52RC(注:可以选择其他型号,譬如STC89、STC90、STC12等等),代码是完全兼容的,不必过多地担心,只是单片机内部资源不同而已;电源电路很简单,采用普通5V供电即可,为了方便调试建议加一个总电源开关,开关类型根据个人喜欢随便选。

图1 单片机最小系统电路图

图1中的J2是程序下载接口,接法很简单,单片机的串口P3.0和P3.1口引出即可;RP1是P0口的上拉排阻。

2、数码管显示电路

如图2所示

图2 数码管显示电路图

3、按键电路

如图3所示

图3 按键电路图

4、HC-SR04超声波模块电路

如图4所示

图4 超声波测距电路图

5、报警电路

如图5所示

图5 报警电路图

6、硬件测试

三、程序设计

1、搭建工程

头文件common.h:

#ifndef __COMMON_H__#define __COMMON_H__//头文件包含#include <reg52.h> //提供单片机寄存器地址#include <intrins.h>//提供_nop_()函数#endif

2、数码管显示模块程序设计

程序如下:

头文件dig.h

#ifndef __DIG_H__#define __DIG_H__//头文件包含#include "common.h"//管脚定义#define digDuan P0 //数码管段控制端口,高电平有效sbit digWei1 = P2^4; //第1位数码管控制端口,低电平有效sbit digWei2 = P2^5; //第2位数码管控制端口,低电平有效sbit digWei3 = P2^6; //第3位数码管控制端口,低电平有效sbit digWei4 = P2^7; //第4位数码管控制端口,低电平有效//函数声明void dig_scan(unsigned int *dat); //数码管扫描#endif

源文件dis.c

#include "dig.h"/* * 数码管扫描* *dat:以数组的方式传值,使用的时候直接填入数组名即可*/ void dig_scan(unsigned int *dat){static unsigned char i = 0; //循环变量/* 数码管扫描处理 */digDuan = 0x00; //消隐digWei1 = 1; digWei2 = 1; digWei3 = 1;digWei4 = 1;switch(i){case 0: {digWei1 = 0; //选通第1位数码管digDuan = dat[0]; //显示第1位数码管的内容break;}case 1:{digWei2 = 0; //选通第2位数码管digDuan = dat[1]; //显示第2位数码管的内容break;}case 2:{digWei3 = 0; //选通第3位数码管digDuan = dat[2] + 0x80; //显示第3位数码管的内容,顺便也显示小数点break;}case 3:{digWei4 = 0; //选通第4位数码管digDuan = dat[3]; //显示第4位数码管的内容break; }default: break;}++i; //数码管位选变量循环if(i >= 4)i = 0;}

3、超声波测距模块程序设计

程序如下:

头文件HC-SR04.h:

#ifndef __HC_SR04_H__#define __HC_SR04_H__#include "common.h"//引脚定义sbit Ttig = P1^3; //触发信号控制端口sbit Echo = P1^4; //回响信号接收端口//函数声明void start_ranging(void);#endif

源程序文件HC-SR04.c:

#include "HC-SR04.h"/* 启动超声波程序 */void start_ranging(void){Ttig = 1;//启动一次模块_nop_();//延时一段时间,至少10us以上 _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_();_nop_(); _nop_(); _nop_(); _nop_();Ttig = 0;}

4、按键模块程序设计

程序如下:

头文件key.c:

#ifndef __KEY_H__#define __KEY_H__//头文件包含#include "common.h"//管脚定义sbit KEY1 = P1^0; //设置键sbit KEY2 = P1^1; //加键sbit KEY3 = P1^2; //减键//函数声明unsigned char key_scan(void); //按键扫描#endif

源程序文件key.c:

#include "key.h"/* 按键延时函数,单位:ms */static void key_delayms(unsigned int ms){unsigned char a,b,c;while(--ms){for(c=1;c>0;c--)for(b=142;b>0;b--)for(a=2;a>0;a--);}}/* 按键扫描 */unsigned char key_scan(void){if(KEY1 == 0) //如果按键1按下{key_delayms(10); //延时10ms,去除按键抖动if(KEY1 == 0) //再判断一次按键按下{return 1; //输出键值1} }if(KEY2 == 0) //如果按键2按下{key_delayms(10); //延时10ms,去除按键抖动if(KEY2 == 0) //再判断一次按键按下{return 2; //输出键值2}}if(KEY3 == 0) //如果按键3按下{key_delayms(10); //延时10ms,去除按键抖动if(KEY3 == 0) //再判断一次按键按下{return 3; //输出键值3}}return 0; //如果没有按键按下,则输出0}

5、报警模块程序设计

程序如下:

头文件

在这里插入代码片

源程序文件

在这里插入代码片

6、定时器程序设计

程序如下:

头文件timer.h

#ifndef __TIMER_H__#define __TIMER_H__//头文件包含#include "common.h"#include "dig.h"//函数声明void InitTimer0(void); //定时器0初始化#endif

源程序文件timer.c:

#include "timer.h"extern unsigned int dis_buf[4];/* 定时器0初始化,定时1ms */void InitTimer0(void){TMOD = 0x11;//配置定时器0为工作方式1,定时器1位工作方式1TH0 = 0;TL0 = 0;TH1 = 0x0EC;//定时5msTL1 = 0x78;EA = 1;//打开总中断ET1 = 1;//打开定时器0中断TR1 = 1;//打开定时器1TR0 = 0;//打开定时器0}/* 定时器0中断服务函数,5ms进一次本中断,用于数码管扫描 */void Timer1Interrupt(void) interrupt 3{TH1 = 0x0EC;//定时5ms,重新赋值TL1 = 0x78;dig_scan(dis_buf);//数码管显示温度}

7、功能实现程序设计

程序如下:

头文件tack.h:

#ifndef __TASK_H__#define __TASK_H__#include "dig.h"//添加数码管显示程序#include "HC-SR04.h"#include "timer.h"#include "key.h"//引脚定义sbit BEEP = P3^7;//蜂鸣器控制端口,低电平有效,无源蜂鸣器//函数声明void delayms(unsigned int ms);//延时,单位:msvoid count(void);//计算距离void dis_distance(void);//显示距离void key_fuction(void);#endif

源程序文件tack.c:

#include "task.h"//全局变量定义//段码表,适用于共阴数码管unsigned int code duan_ma[16] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,//0~90x77,0x7c,0x39,0x5e,0x79,0x71//A~F}; unsigned int dis_buf[4];//显示缓存unsigned int S = 0;//距离缓存变量unsigned long time = 0;//时间缓存变量 unsigned int S_H = 400, S_L = 10; //S_H:报警上限值,默认400cm,S_L:报警下限值,默认10cm/** 延时,单位:ms*/void delayms(unsigned int ms){unsigned char a,b,c;while(--ms){for(c=1;c>0;c--)for(b=142;b>0;b--)for(a=2;a>0;a--); }}/** 计算测距*/void count(void){start_ranging();//启动一次超声波while(!Echo);//等待超声波模块输出IO拉高 TR0 = 1;//开启定时器计时while(Echo);//等待超声波模块输出IO拉低TR0 = 0;//关闭定时器计时/* 计算距离 */time = TH0 * 256 + TL0; //得到的时间,专业写法应该是这样:time = TH0 << 8 | TL0TH0 = 0;//定时计数器清零 TL0 = 0;S = (time * 1.7) / 100; //算出来是CM }/** 显示距离*/void dis_distance(void){dis_buf[3] = 0x00;dis_buf[2] = duan_ma[S / 100 %10];//取出百位数,并在数码管的第3位显示,从右往左数dis_buf[1] = duan_ma[S / 10 %10];//取出十位数,并在数码管的第2位显示,从右往左数dis_buf[0] = duan_ma[S % 10];//取出个位数,并在数码管的第1位显示,从右往左数 }/* * 设置报警功能*/void key_fuction(void){unsigned char mode_flag = 1; //模式切换标记位,1:设置上限值,2:设置下限值,3:退出while(1){if(key_scan() == 1)//功能切换键 {BEEP = 0;//按键提示音delayms(50);BEEP = 1;delayms(100);++mode_flag;if(mode_flag >= 3)//如果满3了,则退出break; }if(key_scan() == 2)//如果加键按下{BEEP = 0;//按键提示音delayms(50);BEEP = 1;delayms(100);if(mode_flag == 1)//设置上限值{++S_H;if(S_H > 400)S_H = 2; }if(mode_flag == 2) //设置下限值{++S_L;if(S_L > 400)S_L = 2; }}if(key_scan() == 3) //如果减键按下{BEEP = 0; //按键提示音delayms(50);BEEP = 1;delayms(100);if(mode_flag == 1) //设置上限值{--S_H;if(S_H < 2)S_H = 400; }if(mode_flag == 2) //设置下限值{--S_L;if(S_L < 2)S_L = 400; }}/*------------- 报警设置显示 --------------*/if(mode_flag == 1) //显示设置上限值内容{dis_buf[3] = 0x76;//第4位数码管显示字母 Hdis_buf[2] = duan_ma[S_H / 100 % 10];//显示百位数dis_buf[1] = duan_ma[S_H / 10 % 10];//显示十位数dis_buf[0] = duan_ma[S_H % 10];//显示个位数}if(mode_flag == 2)//显示设置下限值内容{dis_buf[3] = 0x38;//第4位数码管显示字母 Ldis_buf[2] = duan_ma[S_L / 100 % 10];//显示百位数dis_buf[1] = duan_ma[S_L / 10 % 10];//显示十位数dis_buf[0] = duan_ma[S_L % 10];//显示个位数} }}

编写完功能程序之后,在主函数main()中测试功能程序是否成功,内容如下:

源程序文件main.c:

#include "task.h"//全局变量声明extern unsigned int S; //声明距离缓存变量,在文件"task.c"中定义extern unsigned int dis_buf[4]; //声明显示缓存数组,在文件"task.c"中定义extern unsigned int code duan_ma[16];extern unsigned int S_H, S_L; //S_H:报警上限值,默认400cm,S_L:报警下限值,默认10cm/* 主函数 */void main(void){digDuan = 0x40;//显示"----"digWei1 = 0;digWei2 = 0;digWei3 = 0;digWei4 = 0;delayms(1000);//延时大约1s InitTimer0();//定时器0初始化while(1){count();//计算距离if(S>=S_H || S<=S_L) //如果超出设定的范围,则显示"---"{dis_buf[3] = 0x00;dis_buf[2] = 0x40;//显示"---"dis_buf[1] = 0x40;dis_buf[0] = 0x40; BEEP = 0;//蜂鸣器鸣叫}else{BEEP = 1;//关闭蜂鸣器dis_distance();//显示距离}if(key_scan() == 1) //如果按下设置键,则进入设置报警功能{BEEP = 0;//按键提示音delayms(50);BEEP = 1;delayms(100);key_fuction();//进入设置报警功能} }}

四、小结

五、附录

附录1:整体电路原理图

附录2:元件清单

附录3:资源分享

STC89C52RC数据手册

官网下载链接:/index.htm

百度网盘链接:/s/1i_VyxjlJlqFOZImX1WpY0wHC-SR04超声波模块资料

百度网盘链接:/s/1rs0w3pSYESE-ate9bnE65A74HC573芯片数据手册

百度网盘链接:/s/1eMwCgwte-m5yAb1rql1dqw演示视频

优酷网:/v_show/id_XNDM1NzYzMzU0NA==.html?spm=a2h0k.11417342.soresults.dtitle

西瓜视频:/i6735447308093096455/

如果觉得《基于单片机的HC-SR04超声波模块测距仪设计(数码管显示)》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。