MC68HC11长波无线电数据解码器:从BBC信号中提取精准时间的嵌入式系统设计 1. 项目概述如果你对上世纪90年代的嵌入式无线电技术感兴趣那么基于MC68HC11的长波LW无线电数据解码器绝对是一个值得深入研究的经典项目。这不仅仅是一个简单的“收音机”而是一个完整的、能够从BBC Radio 4的198kHz长波信号中精准提取并解码出时间、日期乃至其他商业数据的嵌入式系统。在那个GPS尚未普及、网络授时遥不可及的年代这种通过无线电波获取国家级标准时间的技术是许多工业控制、科学实验和高端消费电子设备实现高精度时间同步的核心方案。整个系统围绕摩托罗拉现恩智浦的MC68HC11微控制器构建配合MC3371 FM解调芯片将模拟的无线电信号转化为数字比特流再通过精心设计的软件算法从嘈杂的电磁环境中恢复出可靠的数据。最终一个16字符的LCD屏会清晰地显示出协调世界时UTC、经过本地时区调整后的时间、日期甚至电池电压和信号强度。今天我们就来彻底拆解这个项目的硬件设计、软件逻辑以及那些在数据手册里找不到的调试技巧。2. 系统整体架构与设计思路2.1 核心需求与方案选型这个解码器的核心目标非常明确从BBC长波广播中稳定、准确地解调出25Hz速率的低速数据流并从中提取出时间码Type 0数据块将其转换为可读的日期和时间信息进行显示。同时系统还需具备闹钟、睡眠定时等附加功能并能够显示其他类型的数据块Type 1-15的原始十六进制内容。为什么选择MC68HC11和MC3371这套组合这背后是典型的90年代嵌入式设计哲学在有限的资源下实现最高的性价比和可靠性。MC68HC11系列是当时工业控制领域的明星它集成了RAM、ROM、EEPROM、定时器、串口和A/D转换器是一个真正的“片上系统”。对于本项目而言其内置的定时器输入捕捉和外部中断IRQ功能对于精确测量数据比特边沿间隔至关重要。虽然原始文档提到使用IRQ引脚因为调试硬件占用了定时器输入但理解其定时器模块的能力对于方案评估和后续优化是基础。射频前端选择MC3371则是一个巧妙且务实的选择。这是一款为VHF对讲机设计的FM中频解调芯片内部集成了混频器、限幅中放和鉴频器。虽然198kHz的长波频率远低于其典型工作频段但其FM解调的核心功能依然适用。关键在于利用其标准的455kHz中频我们可以直接使用市面上大量存在的高Q值455kHz陶瓷滤波器和中周避免了为198kHz定制高选择性滤波器的成本和难度。这种“降频处理”的思路是射频设计中应对非标频率的常用技巧。2.2 信号链路与数据格式解析要理解硬件设计必须先吃透信号本身。BBC长波数据并非独立的副载波而是采用线性相位调制直接加载在主载波上。这种调制方式对音频节目的干扰极小。数据速率仅为25Hz每个比特周期长达40毫秒。为了提高抗干扰和同步能力数据采用了双相编码。双相编码Bi-phase Coding实战解析这是本项目解码算法的核心。双相编码的规则是在每个比特周期的开始信号电平必然发生一次跳变从高到低或从低到高。对于数据‘0’在比特周期中点还有一次额外的跳变对于数据‘1’则没有这次额外的跳变。 因此解码的关键在于测量两次边沿下降沿之间的时间间隔如果间隔约为20ms半个比特周期则代表连续收到了两个相同的数据位如0后跟0或1后跟1。如果间隔约为30ms一个半比特周期则代表数据从0变为1或从1变为0。如果间隔约为40ms一个完整比特周期则代表收到了一个“非法”状态解码器应据此纠正对前一个比特状态的猜测。 软件中的SDATA中断服务程序正是通过测量TCNT定时器的差值并依据上述规则和上一个比特的状态存储在STAT1的位7来判决出当前收到的比特值。数据被组织成连续的50比特块每块结构如下比特1前缀固定为1主要用于同步和错误检测。比特2-5应用码4比特表示数据块类型0x0为时间码0x1-0xF为用户数据。比特6-37数据域32比特承载有效信息。对于时间码块这里包含了闰年周期、年起始日、周数、星期、UTC时、分、本地时区偏移等。比特38-50CRC校验域13比特由(49,13)缩短循环码生成生成多项式为八进制的36365。这13个比特是前36比特应用码数据域除以生成多项式后得到的余数。接收端用同样的多项式对收到的49比特忽略固定前缀进行计算结果应为0否则说明传输有误。这个CRC不仅用于检错更是实现块同步的关键解码器需要不断滑动窗口对每新进来一个比特后的49比特序列进行CRC计算直到找到余数为0的位置才算成功锁定数据块的边界。3. 硬件电路设计与核心器件剖析3.1 射频接收与解调板模拟板详解图2所示的模拟板是整个系统的“耳朵”其设计充满了模拟电路的智慧。天线与前端调谐 信号接收始于一个磁棒天线。文档建议使用0.25英寸的磁棒用36号标准线规SWG的漆包线绕制大约190匝。更实用的方法是先绕210匝约4.25英寸长在纸筒上然后套在磁棒上滑动同时用一台调谐到198kHz的收音机最好带场强表靠近。当磁棒天线谐振时会对收音机信号产生明显的吸收或增强。找到谐振点后将线圈慢慢全部推上磁棒并通过拆减匝数来维持谐振最后用并联的330pF固定电容和一个微调电容进行精细调谐。我个人的经验是使用从旧收音机上拆下的利兹线绕制的磁棒天线其方向性敏感度更低接收效果更稳定。射频放大与晶体滤波 天线信号经一个20匝的次级线圈耦合至BF199晶体管的基极进行放大。BF199是一个经典的高频小信号放大管。其集电极负载是一个并联的LC谐振回路由Toko CAN1A350EK长波射频线圈和220pF电容组成需要调谐至198kHz以获得最大增益。这里的一个关键设计是加入了一个198kHz的晶体滤波器。这个晶体可从AEL Crystals等供应商处获得提供了极其尖锐的带通特性能极大抑制带外干扰如中波广播。文档明确指出没有这个晶体系统灵敏度和对干扰的容忍度会大幅下降。在强信号地区或许能工作但在城市电磁环境复杂的今天强烈建议保留此晶体。本振与混频 MC3371需要本振信号进行混频。标准做法是使用653kHz晶体但这并非标品。设计者巧妙地采用了“整数分频”方案使用一个10.5MHz或20.945MHz的标准晶体通过MC74HC4060振荡器分频器芯片分别进行16分频得到656.25kHz或32分频得到654.53kHz。虽然频率有微小偏差但后续的455kHz陶瓷滤波器Murata CFU455D2具有约20kHz的带宽足以容纳这个误差。这是工程上“用易得器件解决非标需求”的典范。中频处理与数据切片 混频产生的455kHz中频信号经过陶瓷滤波器后送入MC3371内部的限幅放大器和鉴频器。鉴频输出的核心是一个高Q值的455kHz中周Toko RHCS45328AC2。调整这个中周是硬件调试中最精细的一步。文档给出了一个非常实用的技巧监测BC377晶体管用于缓冲鉴频输出的集电极电压。当调谐准确时该电压会从约1.4V跳变到接近5V。我们应该将其调整到2.5V的中间值这样既能获得最大的解调输出幅度约9mVpp又能为后续运放提供稳定的直流工作点。这个直流点被用来偏置两级LM358运放。第一级运放构成一个低通滤波器滤除455kHz残余载波增益约110倍将信号放大到约1Vpp。第二级运放构成一个积分器进一步整形波形。由于积分器输出直流电平不确定所以通过一个电容耦合到MC3371内部未使用的运算放大器连接成比较器将模拟信号转化为干净的数字方波最终送入MC68HC11的IRQ引脚。3.2 数字控制与显示板数字板详解图3所示的数字板是系统的“大脑”。微控制器与电源管理 核心是MC68HC811E2也可用711E9或E20。其PD5引脚被用作控制线通过一个MC34160低压差稳压器为模拟板提供独立的5V电源。这种设计允许软件在待机模式Standby下关闭模拟板的供电以节省功耗而数字板和LCD屏则由另一个MC78L05稳压器持续供电。MC34160的使能端CE由PD5控制实现了软件可控的电源开关。电池电压和信号强度RSSI通过分压电阻接入MC68HC11的A/D转换器PE4和PE5用于监控系统状态。人机交互 一个4键键盘ON/OFF, SLEEP, ALARM, DISPLAY和一块16字符x1行的LCD模块构成了人机界面。LCD模块基于HD44780控制器可能带有HD44100扩展芯片以驱动更多段码。软件中通过条件汇编来适配不同驱动的LCDLCD16子程序被注释用于纯HD44780驱动、1/16占空比的模块。键盘扫描程序每16ms执行一次采用防抖逻辑连续3次扫描到同一按键才确认确保可靠性。编程与调试接口 MODB引脚上的跳线用于选择引导加载模式Bootstrap Mode方便通过串口下载程序。如果使用8MHz晶体可以直接使用PCbug11的9600波特率进行下载。文档提醒如果晶体是可插拔的临时换成8MHz来下载程序会更方便。4. 软件流程与关键算法实现4.1 主程序框架与实时时钟系统上电后START例程完成初始化设置堆栈、开启实时中断RTI约133ms一次、配置IRQ为下降沿触发、初始化LCD、清空RAM并进入“开机”模式。主循环IDLE以64Hz的频率运行主要任务包括键盘扫描与处理调用KBD例程根据当前模式正常、待机、闹钟设置等执行不同的按键功能详见表3。显示更新由RTI中断每266ms设置标志主循环检查到标志后调用MOD显示例程仅当显示内容发生变化时才刷新LCD以减少干扰。闹钟检查比较当前时间显示时间加1分钟以提前2秒触发与设定的闹钟时间。若匹配则拉低PD5开启模拟板电源或外部设备并启动睡眠定时器。睡眠定时器递减如果睡眠定时器正在运行则每分钟递减。计时结束后拉高PD5关闭模拟板电源返回待机模式。RTI中断服务程序TINTB负责维护软件实时时钟。由于使用的2.0MHz晶体并非精确的2.097152MHz直接计时会有误差。软件采用了动态补偿算法每9分钟为一个周期其中8分钟按228个“1/8秒”计数第9分钟按226个计数。这样平均每分钟的计数为(8*228 226)/9 227.555...个1/8秒。结合RTI的131.072ms周期实际每分钟时长为227.555... * 0.131072 ≈ 59.998秒误差极小。这个细节体现了在资源受限环境下实现高精度计时的巧思。4.2 数据解码与同步算法这是整个项目的软件核心在SDATA中断服务程序中实现。边沿间隔测量与比特判决 每次IRQ触发数据信号下降沿程序读取自由运行定时器TCNT的值计算与上一次边沿的时间差W3。根据W3的大小和上一个比特的状态STAT1.7参照表5的规则判决出1个或2个新的数据比特并调用BITIN或BITIN1例程。CRC校验与块同步BITIN例程将新比特移入一个7字节的移位寄存器DAT到DAT6。关键操作是CRC计算。它没有使用传统的多项式除法循环而是利用了一个预先计算好的13x49位二进制矩阵表2。这个矩阵乘法等价于多项式除法。每移入一个比特程序就将49比特的窗口数据与这个矩阵进行按位异或运算结果是一个13位的余数存储在累加器A和B中。这个过程在MULT循环中完成。同步过程分为两个阶段搜索阶段STAT1.10每收到一个比特就计算一次49比特窗口的CRC。如果余数为0则认为找到了一个有效的块边界将STAT1.1置1并进入锁定阶段。同时置信度计数器CONF加1。锁定阶段STAT1.11每收满50个比特一个完整块才计算一次CRC。如果CRC正确则处理数据如果错误则CONF减1。当CONF减到0或连续多次CRC错误时系统认为失步将STAT1.1清零重新进入搜索阶段。这种“置信度”机制有效避免了因偶然干扰导致的同步丢失。时间码处理与日期计算 当收到一个类型为0且数据域首位为0的块时判定为时间码块。程序会提取出UTC的时、分、星期、周数、闰年周期、年起始日、本地时区偏移等信息。时区转换本地时区偏移以30分钟为步长的二进制补码形式存储。软件根据其正负对UTC时间进行加减并处理跨日、跨周的情况。日期计算这是软件中最精妙的部分之一。广播数据中不直接包含月和日而是提供了“年起始日”1月1日是星期几和“周数”。软件首先根据年类型闰年周期和年起始日查表YRTAB确定当前年份在28年周期1995-2022中的偏移加上1995得到当前年份。然后以“星期”为基准结合周数和当前星期几反推出一年中的第几天最后通过查月份天数表MTAB对闰年有单独的表转换为具体的月和日。这种方法完全遵循了ISO周历的规则确保了日期计算的正确性。4.3 显示与功能逻辑显示模块MOD根据STAT2中的各种标志位决定显示何种内容。主要显示模式包括正常模式ON显示数据块类型‘t’表示时间码、4字节十六进制数据、以及当前时间如t 7D65 37C2 20:31。待机模式OFF显示星期、日期和当前时间如Tue 30 May 20:31。如果闹钟启用则显示闹钟时间。交替显示1显示数据、置信度CONF最高F和秒。交替显示2显示年类型如3/7、推算出的年份如1995和周数如W:22。交替显示3显示电池电压和信号强度RSSI电压。闹钟和睡眠功能通过状态机管理。在闹钟设置模式ON/OFF键用于切换设置小时/分钟SLEEP和DISPLAY键用于增减数值。这种简洁的交互设计用最少的按键实现了完整的功能。5. 构建、调试与问题排查实录5.1 元器件选型与电路搭建要点MCU选择首选MC68HC811E2因为它内置了EEPROM便于程序开发。MC68HC711E9或E20也可用但需使用OTP或掩膜ROM。务必确认芯片的封装和引脚与你设计的PCB匹配。晶体选择数字板的定时基准使用2.0MHz晶体而非更常见的2.097152MHz或4MHz这是为了配合软件中的时钟补偿算法。不要随意更换。电感与滤波器Toko的CAN1A350EK198kHz和RHCS45328AC2455kHz是特定型号。如果找不到可以尝试用相近电感值的可调中周配合微调电容替代但需要借助扫频仪或频谱分析仪进行精确调谐过程会复杂很多。LCD模块确保你的LCD模块是5V供电并确认其驱动芯片是HD447801/16占空比还是HD44780HD441001/8占空比。这决定了是否需要启用软件中的LCD16子程序以及初始化指令$30vs$38。5.2 调试流程与常见问题上电无显示检查MC68HC11的/RESET引脚上电时序确保有正确的复位脉冲。用示波器检查EXTAL引脚是否有2.0MHz正弦波。如果没有检查晶体、两个负载电容47pF以及芯片的电源。检查LCD的对比度调节电压通常是一个可调电阻分压产生对比度不对会看不到任何字符。如果使用自制PCB仔细检查LCD数据线和控制线RS, R/W, E是否与MCU端口连接正确特别是/R/W读/写引脚如果悬空可能导致总线冲突。有显示但无数据始终显示– 0000 0000 0:00这表示MCU没有成功解码到任何有效数据块。首先检查模拟板供电PD5引脚是否为低电平。用示波器探测MC3371第9脚鉴频输出。当调谐准确时应该能看到幅度约9mVpp、频率极低几十Hz的模拟波形。如果没有从前往后查 a. 测量磁棒天线线圈两端在198kHz附近应有谐振峰。 b. 测量BF199集电极应有放大后的198kHz信号。 c. 测量MC3371第1脚混频输出应有455kHz中频信号。如果没有检查本振MC74HC4060第9脚是否有约656kHz或654kHz的方波。 d. 调整455kHz中周Toko RHCS45328AC2同时用万用表监测BC377集电极电压目标2.5V。如果模拟波形正常检查该信号是否送到了MC68HC11的IRQ引脚PE5。用示波器看应该是一个0-5V的方波。能收到数据但时间不对或频繁失步检查软件中的置信度CONF显示交替显示1。在信号良好的情况下它应该能稳步上升到F。如果一直在低位徘徊说明CRC校验经常失败。重点检查MC68HC11的IRQ中断响应时间。SDATA中断服务程序必须在下一个边沿到来前最长40ms完成所有处理。虽然对于25Hz的数据率来说时间充裕但如果中断被意外关闭或程序跑飞就会丢失边沿。可以在中断入口处设置一个IO口翻转用示波器观察中断是否被稳定触发。检查TCNT定时器的预分频设置TMSK2寄存器确保它工作在最高速率不分频以获得最精确的边沿间隔测量。双相解码逻辑依赖于精确的20ms/30ms/40ms阈值。这些阈值在代码中与常量QBP20相关它对应10ms。确保你的2.0MHz晶体频率准确否则会影响TCNT的计时导致阈值判断错误。日期计算错误如果时间正确但日期不对首先检查交替显示2中的“年类型”和“年起始日”是否正确。这来自于时间码块的数据域。确认软件中的YRTAB和MTAB表格数据是否正确烧录。日期计算逻辑复杂表格错误会导致完全混乱的结果。理解“周数”是基于ISO标准的一年的第一周是包含第一个星期四的那一周。这与某些地区的习惯不同。5.3 软件移植与优化建议这份代码是为MC68HC11汇编语言编写的虽然直接可用但从中我们可以学到很多优化思路CRC计算优化代码使用循环进行49x13的矩阵乘法因为25Hz的数据率足够慢。如果数据率提高必须将此循环展开成内联代码如文档中提到的RDS解码器项目所做的那样。中断服务程序ISR优化SDATAISR中进行了多次内存访问和条件判断。在更高速的应用中应将其拆分为一个超快的中断只记录时间戳将复杂的比特判决和CRC计算放到主循环或低优先级中断中。资源节省代码大量使用了位操作和状态标志STAT1,STAT2来管理复杂的状态机正常、待机、闹钟、睡眠、交替显示等这是RAM稀缺时代的经典做法。移植到现代MCU如果想用STM32或Arduino重新实现核心算法双相解码、CRC矩阵校验、日期计算完全可以直接移植。射频前端可以简化比如使用现成的Si473x系列DSP收音机芯片其I2C接口可直接输出数字化的中频信号甚至解调后的数据能省去绝大部分模拟调谐电路。这个基于MC68HC11的长波无线电数据解码器项目堪称是嵌入式软硬件协同设计的教科书式案例。它涉及了射频电路设计、模拟信号处理、数字逻辑、实时操作系统雏形、数据通信协议解码以及精密的软件算法。即便在今天其设计思想——如何在严苛的资源限制和信道条件下可靠地提取并解释低速数据流——依然具有极高的学习价值。成功调试出这个系统看到LCD上显示出从数百公里外的发射塔发送而来的精准时间的那一刻那种跨越空间的连接感和工程实现的成就感是单纯购买一个RTC模块所无法比拟的。