制作超声波测距仪,是很多学生、单片机爱好者学习单片机动手实践的一个实作项目,这款超声波测距程序,针对目前比较广泛使的HC-SR04超声波模块而设计的,这款1602显示的超声波测距距源程序,单片机是51系列单片机,超声波测距模块先用的是HC-SRO4
超声波测距模块,单片机的晶振是12M,接线:模块TRIG接
P2.5 ECH0
接P3.2,当距离超出测量时,范围显示“-”,显示单位是CM。这款程序由于硬件比较简单,制作时焊接工作量小,几乎是百分之百的成功,也可以用PROTEUS软件直接进行。需要超声波测距仿真配套的爱好者,可百度搜索:电子乐屋,这个网上有很多款超声波测距仿真资料。超声波测距仿真
#include[reg52.h>
//注意请把‘ [ ’换成 "<"
#include [intrins.h> //
#define uint unsigned int
#define uchar unsigned char
sbit
rs=P2^0;
//1602的数据/指令选择控制线
sbit
rw=P2^1;
//1602的读写控制线
sbit
en=P2^2;
//1602的使能控制线
sbit
trig=P2^5;
//超声波测距模块Trig
sbit
echo=P3^2;
//超声波测距模块Echo
bit
flag1;
//触发信号标志位//
uchar
count;
//中断累加变量
long int
distance;
//测量所得距离
unsigned char code table[ ]={"0123456789"}; //定义字符数组显示数字
void delay(uint
n)
{
uint
x,y;
for(x=n;x>0;x--)
for(y=110;y>0;y--);
}
void delayt(uint x)
{
uchar
j;
while(x--
> 0)
{
for(j = 0;j < 125;j++)
{
;
}
}
}
void lcd_wcom(uchar
com)
{
rs=0;
//选择指令寄存器
rw=0;
//选择写
P0=com;
//把命令字送入P0
delay(5);
//延时一小会儿,让1602准备接收数据
en=1;
//使能线电平变化,命令送入1602的8位数据口,这点非常重要
en=0;
}
void lcd_wdat(uchar
dat)
{
rs=1;
//选择数据寄存器
rw=0;
//选择写
P0=dat;
//把要显示的数据送入P0
delay(5);
//延时一小会儿,让1602准备接收数据,也就是检测忙信号,这点非常重要。
en=1;
//使能线电平变化,数据送入1602的8位数据口
en=0;
}
void
lcd_init()
{
lcd_wcom(0x38);
//8位数据,双列,5*7字形
,用到功能设定指令
lcd_wcom(0x0c);
//开启显示屏,关光标,光标不闪烁,用到显示开关控制指令
lcd_wcom(0x06);
//显示地址递增,即写一个数据后,显示位置右移一位,用到了写入模式设置指令
lcd_wcom(0x01);
//清屏,用到了清屏指令
}
void
lcd_xianshi()
{
lcd_wcom(0x80+0x40);
lcd_wdat('D');
lcd_wdat('i');
lcd_wdat('s');
lcd_wdat('t');
lcd_wdat('a');
lcd_wdat('n');
lcd_wdat('c');
lcd_wdat('e');
lcd_wdat(':');
lcd_wcom(0x80+0x4c);
lcd_wdat('.');
lcd_wcom(0x80+0x4e);//单位是厘米//
lcd_wdat('c');
lcd_wdat('m');
}
void init_t0()
{
TMOD=0x01;
TL0=0x66;
TH0=0xfc;
//1ms
ET0=1;
EA=1;
}
void trigger()
{
trig=0;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
trig=1;
}
void init_measuring()
{
trig=1;
echo=1;
count=0;
}
void measuring()
{
uchar l;
uint h,y;
TR0 = 1;
while(echo==1)
{
;
}
TR0 = 0;
l = TL0;
h = TH0;
y = (h << 8) + l;
y = y - 0xfc66;//us部分
distance = y + 1000 * count;//计算总时间,单位是微秒
TL0 = 0x66;
TH0 = 0xfc;
delayt(30);
distance = 3453* distance /
20000;//原始为:(0.34毫米/us)*时间/2//
}
void display(uint x)
{
uchar qian,bai,shi,ge;
qian=x/1000;
bai=(x/100);
shi=(x/10);
ge=x;
lcd_wcom(0x80+0x49);//单位是厘米//
lcd_wdat(table[qian]);
lcd_wdat(table[bai]);
lcd_wdat(table[shi]);
lcd_wcom(0x80+0x4d);
lcd_wdat(table[ge]);
}
void
main()
{
lcd_init();
//液晶初始化
init_t0();
//定时器0初始化
init_measuring(); //超声波相应端口初始化
while(1)
{
lcd_xianshi();
//液晶显示特定字符
trigger();
//触发超声波启动
while(echo==0)
//等待回声
{
;
}
measuring();
//进行距离测量
display(distance);
//对测量结果进行显示
init_measuring();
//超声波相应端口初始化
delayt(600);
//每次测量间隔60ms
}
}
//……………………………………………中断服务函数…………………………………………………//
void T_0()interrupt 1
{
TF0 = 0;
TL0 = 0x66;
TH0 = 0xfc;
count++;
if(count==18)
{
TR0 =0;
TL0 = 0x66;
TH0 = 0xfc;
count = 0;
}
}
加载中,请稍候......