这段代码是蓝桥杯单片机比赛(基于CT107D竞赛板)中常用的超声波测距底层驱动。它使用了软件延时产生40kHz脉冲,并利用STC15单片机的PCA计数器来测量回波时间。
为了帮你高效记忆和理解,我将这段代码拆解为三个核心模块:延时(频率)、发射(TX)、接收与计算(RX)。
核心模块一:频率产生 (Delay)
超声波的工作频率是 40kHz,周期 T = \frac{1}{40000} = 25\mu s。
为了产生方波,我们需要每半个周期翻转一次电平,即 12.5μs。
C
void Delay12us(void) //@12.000MHz
{
unsigned char data i;
_nop_();
_nop_();
i = 38; // 核心记忆点:38
while (--i);
}
-
记忆口诀: 12M晶振下,12微秒延时,循环变量是 38。
-
作用: 用作产生40kHz方波的半周期延时。
核心模块二:发送波形 (TX)
这一步是手动模拟PWM,发送8个脉冲信号去激励超声波探头。
C
void Ut_Wave_Init()
{
unsigned char i;
EA=0; // 关键:关中断,防止脉冲被打断导致频率不准
for(i=0;i<8;i++) // 核心记忆点:发送8个脉冲
{
US_TX=1;
Delay12us();
US_TX=0;
Delay12us();
}
EA=1; // 恢复中断
}
-
记忆要点:
-
EA=0/1:这是保护现场,因为软件延时产生频率如果被中断打断,超声波频率就会偏离40kHz,导致测不到距离。
-
8次循环:标准超声波模块通常发送8个周期(Cycle)的脉冲。
-
核心模块三:接收与计算 (RX)
这是最复杂的部分,利用了STC15的PCA模块(当作定时器使用)。
C
unsigned char Ut_Wave_Data()
{
unsigned char time;
// 1. 准备定时器 (PCA配置)
CMOD=0x00; // 配置PCA时钟源为系统时钟/12,即1MHz,1us计一次数
CH=CL=0; // 清零计数器
// 2. 发送波形
Ut_Wave_Init();
// 3. 启动计时并等待
CR=1; // 启动PCA计数器 (Control Run)
// 等待接收引脚变低电平 或者 计数器溢出
// CT107D板载电路接收到信号会将RX拉低,所以等待RX==1(未收到)
while((US_RX==1)&&(CF==0));
CR=0; // 停止计数
// 4. 计算距离
if(CF==0) // 如果没有溢出(说明在超时前收到了信号)
{
time=CH<<8|CL; // 读取16位计数值
return (time*0.017); // 核心记忆点:系数0.017
}
else
{
CF=0; // 清除溢出标志
return 0; // 测量失败
}
}
## 关键解释与记忆:
-
寄存器配置(PCA模块):
-
CMOD = 0x00:设置计数频率。12MHz晶振/12 = 1MHz。意味着计数器每增加1,代表过了1微秒。这极大地简化了后续计算。 -
CR(Control Run):CR=1开始计时,CR=0停止计时。 -
CF(Control Flag):溢出标志位。如果太久没收到回波,计数器满了,CF会变1。
-
-
Wait Loop (
while):-
while((US_RX==1)&&(CF==0)):-
蓝桥杯板子(CT107D)上的超声波接收电路(CX20106)特性是:平时为高电平,收到40kHz信号后拉低电平。
-
所以逻辑是:只要 RX 还是高电平(没收到)且 没超时(CF==0),就死等。
-
-
-
魔法数字 0.017 的由来:
-
声速 v \approx 340 m/s = 34000 cm/s = 0.034 cm/\mu s。
-
距离公式:S = \frac{v \times t}{2} (因为是往返路程)。
-
S = t \times \frac{0.034}{2} = t \times 0.017。
-
因为
CMOD=0x00配置下,time的单位刚好是微秒 (\mu s),所以直接乘 0.017 得到的就是 厘米(cm)。
-
总结记忆表 (Cheatsheet)
| 步骤 | 代码关键点 | 含义 |
|---|---|---|
| 1. 延时 | i = 38 |
12MHz下产生约12us延时。 |
| 2. 发送 | EA=0 … EA=1 |
关中断,发8个脉冲,防抖动。 |
| 3. 计时 | CMOD=0x00 |
PCA计数器设为1MHz (1us/跳)。 |
| 4. 等待 | while((US_RX==1)&&(CF==0)) |
等待回波拉低RX脚。 |
| 5. 算数 | return (time*0.017) |
340m/s除以2,换算成cm。 |