在STC15(STC15W4K58S4)系统版上做的测试,详情见附录文件。超声波测距时声速参数需要根据系统频率调节。
详情可参考网上51单片机测距说明 ,例如:
基于单片机的测距系统设计会在最后附上程序文件。
测试效果图:

工程文件目录

//main.c
#include <stc15.h>
#include "LCD1602.H" //LCD1602显示文件
#include "SRF05.H" //超声波测距文件
#define uchar unsigned char
#define uint unsigned int
unsigned long dis = 0 ; //寄存实际距离
void main(void)
{
T0_init();
SRF05_IO_config();
LCD1602_INIT() ;
LCD1602_WRITE_COMOND(0x80) ; //标题显示
LCD1602_write_String("GetDistance") ;
LCD1602_WRITE_COMOND(0x80+0x40+6) ; //单位显示
LCD1602_WRITE_DATA('m');
LCD1602_WRITE_COMOND(0x80+0x40+7) ;
LCD1602_WRITE_DATA('m');
LCD1602_Delay_ms(200) ;
while(1)
{
dis = getdistance(); //获取距离
LCD1602_WRITE_COMOND(0x80+0x40+2) ; //实时显示距离
LCD1602_WRITE_DATA(dis/1000%10+0x30);
LCD1602_WRITE_COMOND(0x80+0x40+3) ;
LCD1602_WRITE_DATA(dis/100%10+0x30);
LCD1602_WRITE_COMOND(0x80+0x40+4) ;
LCD1602_WRITE_DATA(dis/10%10+0x30);
LCD1602_WRITE_COMOND(0x80+0x40+5) ;
LCD1602_WRITE_DATA(dis%10+0x30);
delayms(80); //80MS延时
}
}
/********************************************************/
void zd0() interrupt 1 //T0计数器溢出,超出单片机测量范围
{
TF0=0; //对定时器0 计数溢出中断复位
}
========================================================================================
//LCD1602.H
#include <stc15.h>
#define uchar unsigned char
#define uint unsigned int
#define MAIN_Fosc 11059200L
#define LCD1602_data_port P4
sbit LCD1602_RS = P5^0 ;
sbit LCD1602_RW = P5^1 ;
sbit LCD1602_RE = P5^2 ;
sbit LCD1602_VO = P5^4 ;
void LCD1602_GPIO_CONFIG(void) ;
void LCD1602_Delay_ms(uchar ms) ;
void LCD1602_WRITE_COMOND(uchar cmd) ;
void LCD1602_WRITE_DATA(uchar dat) ;
void LCD1602_INIT(void) ;
void LCD1602_write_String(uchar *s) ;
void LCD1602_GPIO_CONFIG(void)
{
P4M0 = 0x00; P4M1 = 0x00;
P5M0 = 0x00; P5M1 = 0x00;
P5M0 |= (1<<4);
}
void LCD1602_Delay_ms(uchar ms)
{
uint i;
do{
i = MAIN_Fosc / 13000 ;
while(--i);
}while(--ms);
}
void LCD1602_WRITE_COMOND(uchar cmd)
{
LCD1602_RS = 0;
LCD1602_RE = 1;
LCD1602_data_port = cmd ;
LCD1602_Delay_ms(1);
LCD1602_RE = 0;
}
void LCD1602_WRITE_DATA(uchar dat)
{
LCD1602_RS = 1;
LCD1602_data_port = dat ;
LCD1602_Delay_ms(1);
LCD1602_RE = 1;
LCD1602_Delay_ms(1);
LCD1602_RE = 0;
}
void LCD1602_INIT(void)
{
LCD1602_GPIO_CONFIG();
LCD1602_VO = 1 ;
LCD1602_RE = 1 ;
LCD1602_RW = 0 ;
LCD1602_WRITE_COMOND(0x38);
LCD1602_WRITE_COMOND(0x08);
LCD1602_WRITE_COMOND(0x0c);
LCD1602_WRITE_COMOND(0x06); //写一个字符。指针加1
LCD1602_WRITE_COMOND(0x01); //清屏
}
void LCD1602_write_String(uchar *s)
{
while(*s>0)
{
LCD1602_WRITE_DATA(*s);
s++;
}
}
========================================================================================
//SRF05.H 超声波测距文件
#include <stc15.h>
#include <INTRINS.H>
//#include "LCD1602.h"
#define uchar unsigned char
#define uint unsigned int
sbit RX = P0^1; //echo
sbit TX = P0^0; //trig
uint time=0; //计时
unsigned long S=0; //距离
void SRF05_IO_config(void);
void T0_init(void);
unsigned long getdistance(void);
void SRF05_IO_config(void)
{
P0M0 &= 0; //P0口设为准双向
P0M1 &= 0;
}
/********************************************************/
void StartModule() //
{
char i = 12 ;
TX=1; //延时12us
do{
_nop_(); _nop_(); _nop_(); _nop_();_nop_();
_nop_(); _nop_(); _nop_(); _nop_();_nop_();
_nop_(); _nop_(); _nop_(); _nop_();_nop_();
_nop_(); _nop_(); _nop_(); _nop_();_nop_();
}while(i--);
TX=0;
}
/********************************************************/
void delayms(unsigned int ms)
{
unsigned char i=100,j;
for(;ms;ms--)
{
while(--i)
{
j=10;
while(--j);
}
}
}
void T0_init(void)
{
TMOD=0x01; //
TH0=0;
TL0=0;
ET0=1; //
EA=1; //
}
/********************************************************/
unsigned long getdistance(void)
{
StartModule();
while(!RX); //等 高点平到来(接收端等待返回信号)
TR0=1; //收到返回信号,立马开启计数
while(RX); //等待电平拉低,持续计数
TR0=0; //接收端变为低电平,立马停止计数
time=TH0*256+TL0;
TH0=0;
TL0=0;
S=(time*1.7)/10; //获取距离
if(S>=2000) //超声波模块测距范围限制
{
S = 9999;//显示9999作为超限报警用
}
return S ;
}