第9周(1)超声波总结记忆

这段代码是蓝桥杯单片机比赛(基于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; // 恢复中断
 }
  • 记忆要点:

    1. EA=0/1:这是保护现场,因为软件延时产生频率如果被中断打断,超声波频率就会偏离40kHz,导致测不到距离。

    2. 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; // 测量失败
     }
 }

## 关键解释与记忆:

  1. 寄存器配置(PCA模块):

    • CMOD = 0x00:设置计数频率。12MHz晶振/12 = 1MHz。意味着计数器每增加1,代表过了1微秒。这极大地简化了后续计算。

    • CR (Control Run):CR=1 开始计时,CR=0 停止计时。

    • CF (Control Flag):溢出标志位。如果太久没收到回波,计数器满了,CF会变1。

  2. Wait Loop (while):

    • while((US_RX==1)&&(CF==0))

      • 蓝桥杯板子(CT107D)上的超声波接收电路(CX20106)特性是:平时为高电平,收到40kHz信号后拉低电平

      • 所以逻辑是:只要 RX 还是高电平(没收到)且 没超时(CF==0),就死等。

  3. 魔法数字 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=0EA=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。

unsigned int time;
不是unsigned char time;