超声波测距模块内部电路图
超声波测距模块与51单片机连接电路图
51单片机C语言参考程序
#include //调用单片机头文件
#define uchar unsigned char //无符号字符型宏定义 变量范围0~255
#define uint unsigned int //无符号整型 宏定义 变量范围0~65535
#include
#include eeprom52.h
sbit c_send = P3^3; //超声波发射
sbit c_recive = P3^2; //超声波接收
//这三个引脚参考资料
sbit rs=P1^0; //1602数据/命令选择引脚 H:数据 L:命令
sbit rw=P1^1; //1602读写引脚 H:数据寄存器 L:指令寄存器
sbit e =P1^2; //1602使能引脚 下降沿触发
uchar code table_num[]=0123456789abcdefg;
sbit beep = P1^4; //蜂鸣器IO口定义
bit flag_300ms ;
long distance; //距离
uint set_d; //距离
bit flag_csb_juli; //超声波超出量程
uint flag_time0; //用来保存定时器0的时候的
uchar menu_1; //菜单设计的变量
void delay_1ms(uint q)
{
uint i,j;
for(i=0;i
for(j=0;j
}
void write_eeprom() //保存数据
{
SectorErase(0x2000);
byte_write(0x2000, set_d % 256);
byte_write(0x2001, set_d / 256);
byte_write(0x2058, a_a);
}
void read_eeprom() //读出保存数据
{
set_d = byte_read(0x2001);
set_d
set_d |= byte_read(0x2000);
a_a = byte_read(0x2058);
}
//
void init_eeprom() ////开始初始化保存的数据
{
read_eeprom(); //读出保存数据
if(a_a != 2) //新的单片机初始单片机内问EEPOM
{
set_d = 50;
a_a = 2;
write_eeprom(); //保存数据
}
}
void delay_uint(uint q)
{
while(q--);
}
void write_com(uchar com)
{
e=0;
rs=0;
rw=0;
P0=com;
delay_uint(25);
e=1;
delay_uint(100);
e=0;
}
void write_data(uchar dat)
{
e=0;
rs=1;
rw=0;
P0=dat;
delay_uint(25);
e=1;
delay_uint(100);
e=0;
}
void write_string(uchar hang,uchar add,uchar *p)
{
if(hang==1)
write_com(0x80+add);
else
write_com(0x80+0x40+add);
while(1)
{
if(*p == '\0') break;
write_data(*p);
p++;
}
}
void write_sfm3(uchar hang,uchar add,uint date)
{
if(hang==1)
write_com(0x80+add);
else
write_com(0x80+0x40+add);
write_data(0x30+date/100);
write_data('.');
write_data(0x30+date/10);
write_data(0x30+date);
}
void init_1602() //1602初始化
{
write_com(0x38);
write_com(0x0c);
write_com(0x06);
delay_uint(1000);
write_string(1,0, juli:0.00m );
write_string(2,0, set:0.00m );
}
uchar key_can; //按键值
void key() //独立按键程序
{
static uchar key_new;
key_can = 20; //按键值还原
P3 |= 0xf0;
if((P3 & 0xf0) != 0xf0) //按键按下
{
delay_1ms(1); //按键消抖动
if(((P3 & 0xf0) != 0xf0) && (key_new == 1))
{ //确认是按键按下
key_new = 0;
switch(P3 & 0xf0)
{
case 0xd0: key_can = 3; break; //得到按键值
case 0xb0: key_can = 2; break; //得到按键值
case 0x70: key_can = 1; break; //得到按键值
}
// write_sfm2(1,0,key_can); //显示按键值
}
}
else
{
key_new = 1;
}
}
void delay()
{
_nop_(); //执行一条_nop_()指令就是1us
_nop_();
_nop_();
_nop_();
_nop_();
_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定时
while(!c_recive); //当c_recive为零时等待
TR0=1;
while(c_recive) //当c_recive为1计数并等待
{
flag_time0 = TH0 * 256 + TL0;
if((flag_time0 > 40000)) //当超声波超过测量范围时,显示3个888
{
TR0 = 0;
flag_csb_juli = 2;
distance = 888;
break ;
}
else
{
flag_csb_juli = 1;
}
}
if(flag_csb_juli == 1)
{
TR0=0; //关定时器0定时
distance =flag_time0; //读出定时器0的时间
distance *= 0.017; // 0.017 = 340M / 2 = 170M = 0.017M 算出来是米
if((distance > 500)) //距离 = 速度 * 时间
{
distance = 888; //如果大于3.8m就超出超声波的量程
}
}
}
void time_init()
{
EA = 1; //开总中断
TMOD = 0X11; //定时器0、定时器1工作方式1
ET0 = 0; //关定时器0中断
TR0 = 1; //允许定时器0定时
ET1 = 1; //开定时器1中断
TR1 = 1; //允许定时器1定时
}
void key_with()
{
if(key_can == 1) //设置键
{
menu_1 ++;
if(menu_1 >= 2)
{
menu_1 = 0;
init_1602() ; //1602初始化
write_sfm3(2,7,set_d); //显示设置的距离
}
}
if(menu_1 == 1) //设置距离报警
{
if(key_can == 2)
{
set_d ++ ; //按键按下未松开自动加三次
if(set_d > 400)
set_d = 400;
}
if(key_can == 3)
{
set_d -- ; //按键按下未松开自动加三次
if(set_d
set_d = 1;
}
write_sfm3(2,7,set_d); //显示设置的距离
write_com(0x80+0x40+6); //将光标显示地址
write_com(0x0f); //显示光标并且闪烁
write_eeprom(); //保存数据
}
}
void clock_l() //下限报警函数 距离超近 声音超快
{
static uchar value,value1;
if(distance
{
value ++; //消除实际距离在设定距离左右变化时的干扰
if(value >= 2)
{
value1 ++;
if(value1 >= distance * 2) //这里是控制报警声越来越快
{
value1 = 0;
beep = ~beep; //蜂鸣器报警
}
}
}
else
{
value = 0;
beep = 1;
}
}
void main()
{
init_1602(); //1602初始化
beep = 0; //开机蜂鸣器响一下
delay_1ms(200);
P0 = P1 = P2 = P3 = 0xff; //单片机IO口初始化为1
send_wave(); //测距离函数
time_init();
init_eeprom(); //读eepom数据
write_sfm3(2,7,set_d); //显示设置的距离
send_wave(); //测距离函数
send_wave(); //测距离函数
while(1)
{
if(flag_300ms == 1)
{
flag_300ms = 0;
if(beep == 1)
send_wave(); //测距离函数
if(menu_1 == 0)
write_sfm3(1,7,distance); //显示距离
}
key(); //按键函数
if(key_can
{
key_with(); //按键处理函数
}
}
}
void time1_int() interrupt 3
{
static uchar value; //定时10ms中断一次
TH1 = 0xf8;
TL1 = 0x30; //2ms
value++;
clock_l(); //下限报警函数 距离超近 声音超快
if(value >= 150)
{
value = 0;
flag_300ms = 1;
}
}