基于单片机的超声波测距系统设计实验报告- 重 - 图文 联系客服

发布时间 : 星期一 文章基于单片机的超声波测距系统设计实验报告- 重 - 图文更新完毕开始阅读008fb77fb4daa58da0114af8

附录二:系统软件源代码

/*

*************************************************** *课设名称:基于51单片机的超声波测距系统设计 *硬件平台: 超声波模块+51最小系统 *显示模块:4个数码管 *输入模块:3个按键

*实现的功能:用超声波模块把距离测量出来,用数码管显示,可通过按键设置要报警的距离,低于设置

* 的值则自动报警,一直按住调值的键会越加越快,超出量程(3.8m)则显示888 *接口说明:数码管位P3^4 P3^5 P3^6 P3^7 * 超声波发射=>P3^2 * 超声波接收=>P3^3 按键用的接口是P2口 *待改进的地方:温度补偿,提高精度 *当前的缺陷: 不能测出4m的距离 *测量单位:米(m)

****************************************************/

#include #include #include #include

#define uchar unsigned char #define uint unsigned int

//数码管段选定义 设 0 1 2 3 4 5 6 7 8 9 uchar code smg_duan[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};

//数码管位选

uchar dis_smg[4] ={0,1,2,3};

sbit smg_we1 = P3^4; //数码管位选端口 sbit smg_we2 = P3^5; sbit smg_we3 = P3^6; sbit smg_we4 = P3^7; sbit c_send = P3^1; //超声波发射 sbit c_recive = P3^0; //超声波接收 uchar flag_hc_value; //超声波中间变量

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

18

uchar smg_i = 3; //显示数码管的个数:3 bit flag_300ms ; //主程序300ms处理一次的标识符 bit key_500ms ; //按键程序500ms处理一次的标识符

long distance; //定义测量距离 uint set_d; //定义设定距离 uchar flag_csb_juli; //超声波超出量程 long flag_time0;

//按键的IO变量的定义 uchar key_can; //按键值的变量 uchar zd_break_en,zd_break_value; //自动退出设置界面 uchar menu_ljsd = 10; //用来控制连加的速度 bit flag_lj_en; //按键连加使能

bit flag_lj_3_en; //按键连3次连加后使能 加的数就越大了 uchar key_time; //定时器用,作为连加的中间变量,按键时间 uchar flag_value; //定时器用,作为连加的中间变量 uchar menu_1; //菜单设计的变量 uchar a_a; //设定值写入单片机标志符

/***********************数码管位选函数*****************************/ void smg_we_switch(uchar i) { switch(i) { case 3: smg_we1 = 0; smg_we2 = 1; smg_we3 = 1; smg_we4 = 1; break; case 2: smg_we1 = 1; smg_we2 = 0; smg_we3 = 1; smg_we4 = 1; break; case 1: smg_we1 = 1; smg_we2 = 1; smg_we3 = 0; smg_we4 = 1; break; case 0: smg_we1 = 1; smg_we2 = 1; smg_we3 = 1; smg_we4 = 0; break; } }

/***********************数码管显示函数*****************************/ void display() { static uchar i; i++; if(i >= smg_i) //smg_i=3, i = 0; smg_we_switch(i); //调用位选函数 P1 = dis_smg[i]; //段选 }

19

/******************把数据保存到单片机内部eepom中******************/ void write_eepom() { SectorErase(0x2000); byte_write(0x2000, set_d % 256); //写入set_d值 byte_write(0x2001, set_d / 256); byte_write(0x2058, a_a); //a_a标识符 }

/******************把数据从单片机内部eepom中读出来*****************/ void read_eepom() { set_d = byte_read(0x2001); //读出set_d值 set_d <<= 8; set_d |= byte_read(0x2000); a_a = byte_read(0x2058); }

/******************开机自检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; //key_new、key_old 按键标识符,key_new=0表示有键瞬间按下, //检测确认按键后,key_old=1. key_value按键检测中间变量 if(key_new == 0) //初始有键按下 { if((P2 & 0x07) == 0x07) //松手检测(5次) key_value ++; else key_value = 0; if(key_value >= 5) //确认无键按下

20

}

{ key_value = 0; key_new = 1; //置位key_new,表初始无键按下 flag_lj_en = 0; //关闭连加的使能 flag_lj_3_en = 0; //关闭3秒后连加的使能 flag_value = 0; //连加变量清零 key_time = 0; write_eepom(); //值(set_d)写入单片机 } } else //初始无键按下 { if((P2 & 0x07) != 0x07) //按键检测(5次) key_value ++; else key_value = 0; if(key_value >= 5) //确认按键 { key_value = 0; key_new = 0; flag_lj_en = 1; //连加使能 zd_break_en = 1; //自动退出设置界使能 zd_break_value = 0; //自动退出设置界变量清零,30秒后退出设置界面 } }

key_can = 20;

if(key_500ms == 1) //连按500ms,启动连加 { key_500ms = 0; key_new = 0; key_old = 1; zd_break_value = 0; //自动退出设置界变量清零,30秒后退出设置界面 }

if((key_new == 0) && (key_old == 1)) //确认有键按下 { switch(P2 & 0x07) { case 0x06: key_can = 1; break; //得到k2键值(设定键) case 0x05: key_can = 2; break; //得到k3键值(加) case 0x03: key_can = 3; break; //得到k4键值(减) } } key_old = key_new; //初始化标识符

21