系统描述
基于51单片机超声波测距和报警,采用HC-SR04测距,数码管显示测量距离。按键设置报警上下限,超限报警。
源码下载地址:51单片机超声波测距和报警+Proteus仿真
硬件设计
仿真图1:
仿真图2:
程序设计
部分程序
#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; //蜂鸣器鸣叫delayms(1000);}else{BEEP = 1; //关闭蜂鸣器dis_distance(); //显示距离}if(key_scan() == 1) //如果按下设置键,则进入设置报警功能{BEEP = 0; //按键提示音delayms(50);BEEP = 1;delayms(100);key_fuction(); //进入设置报警功能} }
}
key.h
#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
}
task.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--); }
}
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); //数码管显示温度
}