5. 51单片机使用超声波模块(HC-SR04)

基本工作原理

  1. 采用IO口TRIG触发测距,给至少10us的高电平信号
  2. 模块自动发送8个40khz的方波,自动检测是否有信号返回
  3. 有信号返回,通过IO口ECHO输出一个高电平,高电平持续的时间就是超声波从发射到返回的时间
  4. 测试距离 = (高电平时间 * 声速(340M/S)) / 2

硬件配置

名称 型号
主控 STC89C52RC
晶震 11.0592MHz
超声波模块 HC-SR04

空气中的音速在1个标准大气压和15℃的条件下约为340m/s(0.34m/ms) 51单片机定时器工模式1最大定时时间为65535 * 12 * 1 / 11.0592=71.11ms HC-SR04最大探测距离位4m,声音在上面的条件下传播4m需要的时间约为11.76ms 所以我们只需要读取定时器THTL的值就可以了

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
#include <mcs51/8051.h>
#include <stdio.h>
#define __nop__ __asm nop __endasm

#define TRIG P0_0
#define ECHO P0_1

__bit isOverstep = 0;
// 返回时间
int time, distance;

void calculate()
{
// 读取定时器的值
time = TH0 * 256 + TL0;
// 重置定时器初值
TH0 = 0;
TL0 = 0;
time *= 1.085;
// 音速 = 340m/s = 0.34m/ms = 0.00034m/us = 0.034cm/us
// 距离 = 高电平时间 * 音速 / 2
distance = (time * 0.017);
if(isOverstep)
{
isOverstep = 0;
printf("overstep\n");
} else {
printf("distance = %dcm\n", distance);
}
}

void trigger()
{
TRIG = 1;
// 高点平持续10us以上
__nop__; __nop__; __nop__; __nop__; __nop__;
__nop__; __nop__; __nop__; __nop__; __nop__;
__nop__; __nop__; __nop__; __nop__; __nop__;
__nop__; __nop__; __nop__; __nop__; __nop__;
TRIG = 0;
}

void setup()
{
// 定时器工作模式设置
// 定时器0为工作模式1 用于计时
// 定时器1为工作模式2 用于串口
TMOD = 0x21;
// 设置串口为模式1
// SM0 0
// SM1 1
SCON |= 0x50;
// 设置定时器1初值和自动装载值
// 波特率 9600
TH1 = 0XFD;
TL1 = 0XFD;
// 设置定时器0初值
TH0=0;
TL0=0;
// 定时器T0中断允许
ET0=1;
// 启动定时器1
TR1=1;
//中断允许
EA=1;
}

void loop()
{
// 出发超声波模块
trigger();
// 等待回响
while(!ECHO);
// 启动定时器0
TR0 = 1;
// 等待回响结束
while(ECHO);
// 停止定时器0
TR0=0;
// 计算并输出
calculate();
}

void timer0() __interrupt 1
{
isOverstep = 1;
}

void main()
{
setup();
while(1) loop();
}

void putchar(char c)
{
SBUF = c;
while(!TI);
TI = 0;
}

串口输出