基于单片机的超声波测距系统论文 - 图文

更新时间:2024-05-27 17:50:01 阅读量: 综合文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

课程设计报告书

课 题: 超声波测距报警系统

专 业: 班 级: 学 号: 学生姓名:

目录

摘要 ............................................................. 1 1 绪论 ........................................................... 2

1.1 项目研究背景及意义 ....................................... 2 2 总体设计方案及论证 ............................................. 2

2.1 总体方案设计 ............................................. 2 3 硬件实现及单元电路设计 ......................................... 3

3.1 主控制模块 ............................................... 3 3.2 电源设计 ................................................. 4 3.3 超声波测试模块 ........................................... 4

3.3.1 超声波的特性 ....................................... 5 3.3.2 超声波换能器 ....................................... 6 3.4 超声波传感器原理 ......................................... 8 3.5 测距分析 ............................................... 11 3.6 时钟电路的设计 .......................................... 13 3.7 复位电路的设计 .......................................... 13 3.8 声音报警电路的设计 ...................................... 14 4 软件设计 ...................................................... 15

4.1 主程序工作流程图 ........................................ 15 5 系统调试过程 .................................................. 16

5.1 原理图和印制板图绘制 .................................... 16

5.1.1 在DXP软件中绘制原理图 ............................. 16 5.1.2 在DXP软件绘制PCB图 ............................... 17 5.2 Keil程序调试 ........................................... 18 5.3 实物仿真调试 ............................................ 18 总结 ............................................................ 20 参考文献 ........................................................ 21 附 录一:原理图 ................................................. 22 附录二:实物图 .................................................. 23 附录三:物料清单 ................................................ 24 附录四:程序源代码 .............................................. 25

摘要

STC89C52是STC系列单片机里应用比较广泛的一款,在自动控制领域里享有很高的价值,以其易用性和多功能性受到了广大电子设计爱好者的好评。本次设计主要是利用STC89C52单片机、超声波传感器完成测距报警系统的制作,以STC89C52为主控芯片,利用超声波对距离的检测,将前方物体的距离探测出来,然后单片机处理运算,与设定的报警距离值进行比较判断,当测得距离小于设定值时,STC89C52发出指令控制蜂鸣器报警。 关键词:超声波传感器 STC89C52

1

1 绪论

1.1 项目研究背景及意义

由于超声测距是一种非接触检测技术,不受光线、被测对象颜色等的影响,较其它仪器更卫生,更耐潮湿、粉尘、高温、腐蚀气体等恶劣环境,具有少维护、不污染、高可靠、长寿命等特点。因此可广泛应用于纸业、矿业、电厂、化工业、水处理厂、污水处理厂、农业用水、环保检测、食品(酒业、饮料业、添加剂、食用油、奶制品)、防汛、水文、明渠、空间定位、公路限高等行业中。可在不同环境中进行距离准确度在线标定,可直接用于水、酒、糖、饮料等液位控制,可进行差值设定,直接显示各种液位罐的液位、料位高度。因此,超声在空气中测距在特殊环境下有较广泛的应用。利用超声波检测往往比较迅速、方便、计算简单、易于实现实时控制,并且在测量精度方面能达到工业实用的指标要求,因此为了使移动机器人能够自动躲避障碍物行走,就必须装备测距系统,以使其及时获取距障碍物的位置信息(距离和方向)。因此超声波测距在移动机器人的研究上得到了广泛的应用。同时由于超声波测距系统具有以上的这些优点,因此在汽车倒车雷达的研制方面也得到了广泛的应用。

2 总体设计方案及论证

2.1 总体方案设计

本设计包括硬件和软件设计两个部分。模块划分为数据采集、按键控制、

四位数码管显示、报警等子模块。电路结构可划分为:超声波传感器、蜂鸣器、单片机控制电路。就此设计的核心模块来说,单片机就是设计的中心单元,所以此系统也是单片机应用系统的一种应用。单片机应用系统也是有硬件和软件组成。硬件包括单片机、输入/输出设备、以及外围应用电路等组成的系统,软件是各种工作程序的总称。单片机应用系统的研制过程包括总体设计、硬件设计、软件设计等几个阶段。系统采用STC89C52单片机作为核心控制单元,当测得的距离小于设定距离时,主控芯片将测得的数值与设定值进行比较处理。然后控制蜂鸣器报警。系统总体的设计方框图如图1所示。

2

3硬件实现及单元电路设计

图1 系统方框图

图2 最小系统

按键控制 4位数码管显示模块 STC89C52、超声波传感器、按键、四位数码管、蜂鸣器等一些单片机外围应用

电路。其中D1为电源工作指示灯。电路中用到3个按键,一个是设定键, 一

硬件电路总设计见图3,从以上的分析可知在本设计中要用到如下器件:

STC89C52

蜂鸣器报警模块

3.1 主控制模块

超声波传感器模块 主控制最小系统电路如图2所示。

主控制器模块电源 3

3.8 声音报警电路的设计

如下图所示,用一个Speaker和三极管、电阻接到单片机的P13引脚上,构成声音报警电路,如图15示为声音报警电路。

图15 声音报警电路图

3.9 显示模块

显示模块采用数码管显示接口电路如图16

图16 数码管电路

14

4 软件设计

4.1 主程序工作流程图

按上述工作原理和硬件结构分析可知系统主程序工作流程图如下图17所示;

开始 系统初始化 测得距离与设定值比较,小于 N Y 启动报警电路开始报警 距离比较,报警是否持续 N Y 报警结束 Y 再次检测等待下次报警 N 结束 图17 主程序工作流程图

15

超声波探测程序流程图如下图18所示:

图18 超声波探测程序流程图 5系统调试过程

通过上面的设计,设计已经基本完成。下面主要实现Altium Designer的原理图、印制板图的绘制和做相关检测,对Keil进行相应的检查和调试。

5.1原理图和印制板图绘制

5.1.1 在DXP软件中绘制原理图

打开DXP软件,绘制系统的原理图。原理图包括能输出时钟电路,驱动电路以及复位电路。绘制完成的原理图如图19所示:

16

5.1.2 在DXP软件绘制PCB图

由原理图生成的PCB图如图20所示:

图19 原理图

图20 PCB图

17

5.2 Keil程序调试

程序调试结果如图21所示:

creating hex file from \基于51单片机超声波测距报警系统.c... \基于51单片机超声波测距报警系统\

图22 Keil程序调试图

5.3 实物仿真调试

本次调试设置超声波测量报警距离为30cm(报警距离可调,其调节范围为20cm-400cm之间)。

报警状态图如图23所示

图23 报警状态图

18

非报警状态如图24所示

图24 非报警状态

19

总结

本设计研究了一种基于单片机技术的超声波智能测距报警系统。该系统通过以STC89C52单片机为工作处理器核心,超声波传感器,它是一种新颖的被动式超声波探测器件,能够以非接触测出前方物体距离,并将其转化为相应的电信号输出. 其算法设计原理为超声波发生器T在某一时刻发出一个超声波信号,当这个超声波遇到被测物体后反射回来,就被超声波接收器R所接收到。这样只要计算出从发出超声波信号到接收到返回信号所用的时间,就可算出超声波发生器与反射物体的距离。在启动发射电路的同时启动单片机内部的定时器T0,利用定时器的计数功能记录超声波发射的时间和收到反射波的时间。当收到超声波反射波时,接收电路输出端产生一个负跳变,在INT1端产生一个中断请求信号,单片机响应外部中断请求,执行外部中断服务子程序,读取时间差,计算距离。该报警器的最大特点就是使用户能够操作简单、易懂、灵活;且安装方便、智能性高、误报率低。随着现代人们安全意识的增强以及科学技术的快速发展,相信报警器必将在更广阔的领域得到更深层次的应用。

20

参考文献

[1] 吴政江. 单片机控制红外线防盗报警器[J]. 锦州师范学院学报, 2001. [2] 宋文绪. 传感器与检测技术[M]. 北京: 高等教育出版社, 2004. [3] 余锡存. 单片机原理及接口技术[M]. 西安: 西安电子科技大学出版社, 2000.

[4] 唐桃波, 陈玉林. 基于AT89C51的智能无线安防报警器 [J]. 电子设计应用, 2003, 5(6): 49~51.

[5] 李全利. 单片机原理及接口技术[M]. 北京: 北京航空航天大学出版社, 2004.

[6] 薛均义, 张彦斌. MCS-51系列单片微型计算机及其应用[M]. 西安: 西安交通大学出版社, 2005.

[7] 徐爱钧, 彭秀华. 单片机高级语言C51应用程序设计[M]. 北京: 北京航空航天大学出版社, 2006.

[8] 康华光. 电子技术基础(模拟部分)[M]. 北京: 高等教育出版社, 2004.

21

附 录一:原理图

22

附录二:实物图

23

附录三:物料清单

元件注解 元件类型 10K 电阻 10uF 电容 12M 晶振 D 指示灯 发光二极管 DS04 数码管 SW-灰色 电源开关 开关 U1 单片机 蜂鸣器 蜂鸣器 9012 三极管 20 电容 Header 4 超声波接口 SW-PB 独立按键 按键 9012 三极管 2K 电阻 1K 电阻 电阻 元件称号 R14 C1 Y1 D1 DS1 SW1 U1 B1 Q5 C2, C3 P1 S1, S2, S3, S4 Q1, Q2, Q3, Q4 R4, R5, R6, R7, R13, R15 R1, R2, R3, R8, R9, R10, R11, R12 数量 1 1 1 1 1 1 1 1 1 2 1 4 4 6 8

24

附录四:程序源代码

#include #include #include \

#define uchar unsigned char #define uint unsigned int

//数码管段选定义 0 1 2 3 4 5 6 7 8 9

uchar code

smg_du[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90, 0x88,0x83,0xc6,0xa1,0x86,0x8e,0xff}; //断码 //数码管位选定义

uchar code smg_we[]={0xe0,0xd0,0xb0,0x70};

uchar dis_smg[8] ={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8};

sbit smg_we1 = P3^4; //数码管位选定义 sbit smg_we2 = P3^5; sbit smg_we3 = P3^6; sbit smg_we4 = P3^7;

sbit c_send = P3^2; //超声波发射 sbit c_recive = P3^3; //超声波接收

uchar flag_hc_value; //超声波中间变量

sbit beep = P2^3; //蜂鸣器IO口定义

bit flag_key_b_en,flag_key_set_en; //按键蜂鸣器使能

uchar smg_i = 3; //显示数码管的个位数 bit flag_300ms ;

bit key_500ms ;

long distance; //距离 uint set_d; //距离

bit flag_csb_juli; //超声波超出量程

uint flag_time0; //用来保存定时器0的时候的

// 按键的IO变量的定义 uchar key_can; //按键值的变量

uchar zd_break_en,zd_break_value; //自动退出设置界面 uchar menu_shudu = 10; //用来控制连加的速度

25

bit flag_lj_en; //按键连加使能

bit flag_lj_3_en; //按键连3次连加后使能 加的数就越大了 uchar key_time,flag_value; //用做连加的中间变量 uchar menu_1; //菜单设计的变量 uchar a_a;

/***********************1ms延时函数*****************************/ void delay_1ms(uint q) {

uint i,j;

for(i=0;i

for(j=0;j<120;j++); }

/***********************处理距离函数****************************/ void smg_display() {

dis_smg[0] = smg_du[distance % 10];

dis_smg[1] = smg_du[distance / 10 % 10];

dis_smg[2] = smg_du[distance / 100 % 10] & 0x7f; }

/******************把数据保存到单片机内部eepom中******************/ void write_eepom() {

SectorErase(0x2000);

byte_write(0x2000, set_d % 256); byte_write(0x2001, set_d / 256); byte_write(0x2058, a_a); }

/******************把数据从单片机内部eepom中读出来*****************/ void read_eepom() {

set_d = byte_read(0x2001); set_d <<= 8;

set_d |= byte_read(0x2000); a_a = byte_read(0x2058); }

26

/**************开机自检eepom初始化*****************/ void init_eepom() {

read_eepom(); //先读

if(a_a != 1) //新的单片机初始单片机内问EEPOM {

set_d = 100; a_a = 1;

write_eepom(); } }

/****************独立按键处理函数********************/ void key() {

static uchar key_new = 0,key_old = 0,key_value = 0; if(key_new == 0)

{ //按键松开的时候做松手检测 if((P2 & 0x07) == 0x07) key_value ++; else

key_value = 0; if(key_value >= 5) {

key_value = 0; key_new = 1;

flag_lj_en = 0; //关闭连加使能 flag_lj_3_en = 0; //关闭3秒后使能 flag_value = 0; //清零 key_time = 0; write_eepom(); } } else {

if((P2 & 0x07) != 0x07)

key_value ++; //按键按下的时候 else

key_value = 0; if(key_value >= 5) {

key_value = 0; key_new = 0;

flag_lj_en = 1; //连加使能

27

zd_break_en = 1; //自动退出设置界使能

zd_break_value = 0; //自动退出设置界变量清零 flag_key_b_en = 1; //按键蜂鸣器使能 } }

key_can = 20;

if(key_500ms == 1) //连加 {

key_500ms = 0; key_new = 0; key_old = 1;

zd_break_value = 0; }

if((key_new == 0) && (key_old == 1)) {

switch(P2 & 0x07) {

case 0x06: key_can = 3; break; //得到k2键值 case 0x05: key_can = 2; break; //得到k3键值 case 0x03: key_can = 1; break; //得到k4键值 }

// dis_smg[3] = smg_du[key_can % 10];

}

key_old = key_new; }

void smg_we_switch(uchar i) {

switch(i) {

case 0: smg_we1 = 0; smg_we2 = 1; smg_we3 = 1; smg_we4 = 1; break;

case 1: smg_we1 = 1; smg_we2 = 0; smg_we3 = 1; smg_we4 = 1; break;

case 2: smg_we1 = 1; smg_we2 = 1; smg_we3 = 0; smg_we4 = 1; break;

case 3: smg_we1 = 1; smg_we2 = 1; smg_we3 = 1; smg_we4 = 0; break; } }

/***********************数码显示函数

28

*****************************/ void display() {

static uchar i; i++;

if(i >= smg_i) i = 0;

// P1 = 0xff; //段选 // P3 = 0xf0 | (P3 & 0x0f); //位选

// P3 = smg_we[i] | (P3 & 0x0f); //位选 smg_we_switch(i);

P1 = dis_smg[i]; //段选 }

void delay() {

_nop_(); //执行一条_nop_()指令就是1us _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); }

/*********************超声波测距程序*****************************/ void send_wave() {

c_send = 1; //10us的高电平触发 delay();

c_send = 0;

TH0 = 0; //给定时器0清零 TL0 = 0;

TR0 = 0; //关定时器0定时 flag_hc_value = 0; while(!c_recive); //当c_recive为零时等待 TR0=1;

while(c_recive) //当c_recive为1计数并等待 {

flag_time0 = TH0 * 256 + TL0;

if((flag_hc_value > 1) || (flag_time0 > 65000)) //

29

当超声

波超过测量范围时,显示3个888 {

TR0 = 0;

flag_csb_juli = 2; distance = 888; flag_hc_value = 0; break ; }

else {

flag_csb_juli = 1; } }

if(flag_csb_juli == 1) {

TR0=0; //关定时器0定时

distance = TH0; //读出定时器0的时间 distance = distance * 256 + TL0;

distance +=( flag_hc_value * 65536);//算出超声波测距的时间 得到单位是ms

distance *= 0.017; // 0.017 = 340M / 2 = 170M = 0.017M 算出来是米

if(distance > 350) //距离 = 速度 * 时间 {

distance = 888; //如果大于3.8m就超出超声波的量程 } } }

/*********************定时器0、定时器1初始化******************/ void time_init() {

EA = 1; //开总中断

TMOD = 0X11; //定时器0、定时器1工作方式1 ET0 = 1; //开定时器0中断 TR0 = 1; //允许定时器0定时 ET1 = 1; //开定时器1中断 TR1 = 1; //允许定时器1定时 }

/****************按键处理数码管显示函数***************/ void key_with()

30

{

if(key_can == 1) {

menu_1 ++;

if(menu_1 >= 2) {

menu_1 = 0; }

if(menu_1 == 0) {

menu_shudu = 20;

dis_smg[0] = smg_du[distance % 10]; dis_smg[1] = smg_du[distance / 10 % 10] ;

dis_smg[2] = smg_du[distance / 100 % 10] & 0x7f; smg_i = 3; }

if(menu_1 == 1) {

menu_shudu = 1;

dis_smg[0] = smg_du[set_d % 10]; dis_smg[1] = smg_du[set_d / 10 % 10];

dis_smg[2] = smg_du[set_d / 100 % 10] & 0x7f ; dis_smg[3] = 0x88; smg_i = 4; } }

if(menu_1 == 1) //设置高温报警 {

if(flag_lj_3_en == 0) //三次连加之后速度加快 menu_shudu = 10 ; //500ms 加减一次 else

menu_shudu = 1; //250ms 加减一次 if(key_can == 2) {

set_d ++ ; //按键按下未松开自动加三次 if(set_d > 350) set_d = 350;

dis_smg[0] = smg_du[set_d % 10]; //取小数显示

dis_smg[1] = smg_du[set_d / 10 % 10] ; //取个位显示

dis_smg[2] = smg_du[set_d / 100 % 10] & 0x7f; //取十位显示

dis_smg[3] = 0x88; //a

31

}

if(key_can == 3) {

set_d -- ; //按键按下未松开自动加三次 if(set_d <= 1) set_d = 1;

dis_smg[0] = smg_du[set_d % 10]; //取小数显示

dis_smg[1] = smg_du[set_d / 10 % 10] ; //取个位显示 dis_smg[2] = smg_du[set_d / 100 % 10] & 0x7f ; //取十位显示

dis_smg[3] = 0x88; //a }

// write_eepom(); } }

/****************报警函数***************/ void clock_h_l() {

static uchar value; if(distance <= set_d) {

value ++; //消除实际距离在设定距离左右变化时的干扰 if(value >= 5) {

beep = ~beep; //蜂鸣器报警 } } else {

value = 0;

beep = 1; //取消报警 } }

/****************按键按下蜂鸣器响下**********************/ void key_beep() {

static uint value;

if((flag_key_b_en == 1) && (flag_key_set_en == 1)) {

beep = 0; //打开蜂鸣器 value ++;

32

if(value > 800) {

value = 0;

flag_key_b_en = 0; beep = 1;//关闭蜂鸣器 } } }

void main() {

send_wave(); //测距离函数

smg_display(); //处理距离显示函数 time_init();

init_eepom(); //读eepom数据 while(1) {

if(flag_300ms == 1) {

flag_300ms = 0;

clock_h_l(); //报警函数 send_wave(); //测距离函数 if(menu_1 == 0)

smg_display(); //处理距离显示函数 if(zd_break_en == 1) //自动退出设置界面程序 {

zd_break_value ++; //每300ms加一次

if(zd_break_value > 100) //30秒后自动退出设置界面 {

menu_1 = 0; // smg_i = 3;

zd_break_en = 0; zd_break_value = 0; } } }

key(); //按键函数 if(key_can < 10) {

key_with(); //按键处理函数 } } }

33

/*********************定时器0中断服务程序 用做超声波测距的************************/

void time0_int() interrupt 1 { set_d ++; // TH0 TL0 到65536后溢出中断 }

/*********************定时器0中断服务程序************************/

void time1_int() interrupt 3 {

static uchar value; //定时10ms中断一次 TH1 = 0xf8;

TL1 = 0x30; //2ms display(); //数码管显示函数 value++;

if(value >= 150) {

value = 0;

flag_300ms = 1; }

if(value % 25 == 0) {

if(flag_lj_en == 1) //按下按键使能 50ms {

key_time ++;

if(key_time >= menu_shudu) //500ms {

key_time = 0;

key_500ms = 1; //500ms flag_value ++;

if(flag_value >= 3) {

flag_value = 10;

flag_lj_3_en = 1; //3次后1.5秒后连加大些 } } } } }

34

35

本文来源:https://www.bwwdw.com/article/dl77.html

Top