ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

基于STC15F104W的433MHz学习型遥控解码与发射方案

基于STC15F104W的433MHz学习型遥控解码与发射方案 简介面向STC15F104W/STC11F104W单片机开发者这份学习型无线遥控解码资料包完整覆盖315-433MHz频段常用遥控芯片1527、2262、2264、2260、SC5211、HS2240等的解码实现解决学习型遥控器自适应振荡电阻、免人工地址编码等典型问题。包内共48个文件以C源程序、AD09原理图/SchDoc、PCB工程文件和DOC说明文档为主附带Hex烧录文件、Keil工程备份及预览截图整体仅337KB结构清晰便于对照学习。目前已有190人学习浏览适合刚接触遥控解码或需要参考STC15F104W实际应用方案的电子爱好者与嵌入式入门者。资料不仅提供了完整解码源程序和电路图还配有下载烧录说明、学习遥控器芯片设置文档及433MHz无线模块说明可帮助读者快速理解从硬件搭建到程序烧录的全过程同时利用片内EEPROM实现多地址编码学习与存储默认使用内部11.0592MHz晶振无需外部晶振即可工作。1. 学习型433遥控解码不是录波形是录键值很多人以为学习型无线遥控是把射频波形完整录下来再原样重放实际做过433项目就会明白这条路走不通。STC15F104W这颗SOP8小封装单片机做的是另一件事用外部中断捕捉接收模块输出的脉冲宽度把433M频段常见的EV1527/PT2262编码帧实时解析成同步码、ID、键值和校验位再把键值写进EEPROM。下次按下按键时单片机按同一套时间参数翻转IO口驱动发射模块接收端看到的就是一颗“原装遥控器”。STC15F104W的1T 8051内核主频最高能跑到35MHz内部RC振荡器可以省掉外部晶振8个引脚里只要3个IO就能打通接收、发射、学习按键三个功能。这篇文章把原理图怎么连、解码程序怎么写、时间参数怎么定、以及上电后怎么验证讲清楚适合正在做遥控器拷贝、无线门铃改造或者433透传网关的工程师。2. 原理图与硬件接线STC15F104W的引脚分配和433模块接口2.1 为什么选STC15F104W做学习型解码学习型遥控解码选单片机时核心要求只有三个能用IO口模拟时序、有内置EEPROM、供货稳定且封装小。STC15F104W属于STC 15系列里的精简型号SOP8封装内置1KB SRAM和1KB EEPROM工作电压2.4V到5.5V最关键的是它不需要外部晶振和复位电路内部高精度RC振荡器在25℃下误差小于1%433解码的时间测量靠的是定时器计数振荡器稳定性直接决定解码成功率。相比STM32F103C8T6这种M3内核STC15F104W没有硬件捕获通道只能用外部中断加定时器来做脉冲测量但对EV1527这种低速编码单个脉冲低电平只有350us级别来说1T 8051在12MHz下完全扛得住。另一个细节是引脚功能复用。STC15F104W的P3端口每个引脚都有第二功能其中P3.2对应INT0外部中断P3.4对应T0定时器外部计数输入这两个引脚在原理图里要优先分配。解码输入接INT0是为了用下降沿触发中断来测量高电平宽度而P3.4如果接发射模块可以在发射时用T0的硬件翻转功能省掉一部分软件延时不过我一般还是用普通IO加软件延时逻辑更直观调试也方便。2.2 原理图关键节点接收模块、学习键、LED的接线433接收模块推荐用超外差式的比如常见的WTR-0500S或者RXB6这类模块数据输出端是TTL电平空闲时输出高电平收到载波后根据编码信号翻转。超再生模块便宜但波形边缘抖动大做学习解码时容易误判时间参数不建议用在学习型方案里。接收模块的DATA引脚串联一个330欧姆到1K欧姆电阻后接STC15F104W的P3.2/INT0串电阻是为了在模块输出异常时限制流入单片机引脚的电流。发射模块用常见的FSST-02A或者WLT-433SDATA引脚接P3.1这个引脚在复位期间是高电平发射模块在上电瞬间会短暂发射一段载波解决办法是在P3.1到发射模块DATA之间串一个10K欧姆电阻然后对地接一个4.7K欧姆下拉电阻让复位期间的默认状态可靠置低。学习按键接P3.4按键另一端直接接地P3.4内部上拉使能不需要外部上拉电阻。LED指示接P3.3串220欧姆电阻到VCC低电平点亮。2.2.1 SOP8引脚分配表与电源设计STC15F104W的SOP8封装引脚定义如下表原理图绘制时按这个映射连接引脚号引脚名第二功能本方案用途外部连接1P3.0RxD预留/调试可接串口工具2P3.1TxD433发射输出经10K4.7K分压接发射模块DATA3P3.2INT0433接收输入经1K电阻接接收模块DATA4P3.3INT1LED指示输出经220R接LED到VCC5P3.4T0学习按键输入按键到GND内部上拉6P3.5T1预留悬空或接测试点7VCC-电源3.3V~5V10uF0.1uF去耦8GND-地与模块共地电源部分是原理图里最容易翻车的。433发射模块在数据为高电平的瞬间峰值电流可以达到100mA以上如果单片机供电线和模块供电线共用同一条细走线发射时VCC电压会被拉低重发过程中单片机可能复位甚至EEPROM写入被打断导致键值丢失。正确做法是单片机VCC和模块VCC在原理图上分开标注PCB上分别走线在模块供电入口单独放一个100uF电解电容和0.1uF瓷片电容。天线方面433MHz的1/4波长自由空间长度约17.3厘米接收模块ANT引脚焊一根垂直导线即可PCB上如果走蛇形天线至少需要两层板空间对小模块方案不划算。2.3 硬件初始化代码与IO规划STC15F104W的P1和P3端口都是准双向口初始化时把用到的引脚设为标准双向口即可下面是硬件初始化代码sfr P3M1 0xB1; sfr P3M0 0xB2; sbit RF_RX P3^2; // 433接收数据输入接INT0 sbit RF_TX P3^1; // 433发射数据输出 sbit KEY_LEARN P3^4; // 学习按键低电平有效 sbit LED_IND P3^3; // 指示灯低电平点亮 void GPIO_Init(void) { P3M0 0x00; // P3全部设为准双向口 P3M1 0x00; P3 | 0x10; // P3.4按键引脚内部上拉 RF_TX 0; // 发射默认低电平防止误发射 LED_IND 1; // LED默认熄灭 }P3M0和P3M1是STC15系列的端口模式寄存器两位置0代表准双向口这种模式下IO口内置弱上拉适合按键输入和高电平驱动。需要特别注意的是发射引脚RF_TX在初始化阶段必须保持低电平否则433发射模块会一直输出载波干扰同区域其他无线设备的通信这在产品做认证时是必查项。3. 解码433时序同步码、键值码与时间参数3.1 EV1527编码格式为什么不能说“引导码加键值”网上搜433遥控解码经常看到“引导码加键值”这种说法这个描述只对了前面一半。以最常见的EV1527编码为例完整一帧的格式是同步码低电平350us 高电平1050us左右加20位数据码。这20位里前12位是厂家ID后8位是按键值其中后4位是按键编码前4位是反向校验码。也就是说物理遥控器上的每一个按键对应的是ID加键值的组合同一个遥控器的不同按键ID相同、键值不同不同品牌遥控器的ID或时间参数可能完全不一样。学习型解码要做的就是把这一帧的ID和键值全部学下来发射时重放相同的帧。对比PT2272硬解码芯片软件解码的灵活性在于能兼容不同厂家的时间参数不限制在某个固定频率。PT2272对应的解码芯片只能解出三态地址如果遥控器用了不同厂家的编码芯片硬解码方案就要换芯片而STC15F104W只要脉冲宽度落在可识别的时间窗口内就能把数据提取出来。这也是为什么“用单片机软件解码取代专用解码芯片”在拷贝类产品里是主流做法。3.2 用外部中断测量脉冲宽度捕捉解码的核心手段433接收模块输出的信号是反向的也就是说发射端发高电平时接收模块输出低电平。所以单片机看到的是同步码对应一个低电平350us加高电平1050us数据位0对应低350us加高350us数据位1对应低350us加高1050us。定时器测量时从下降沿进入中断开始计时下一次下降沿到来时读取定时器的值得到的就是高电平持续宽度。高电平宽度小于700us判为数据0介于700us到1400us判为数据1大于1400us判为同步码或无效信号。unsigned int high_time; // 高电平宽度单位us unsigned char bit_count; // 当前接收位数 unsigned char frame_bits; // 帧数据缓冲区 void Timer0_Init(void) { TMOD 0x01; // 定时器0工作在16位模式 TH0 0; TL0 0; ET0 0; // 不使用定时器中断 TR0 1; // 启动定时器 } void INT0_Isr(void) interrupt 0 { unsigned int current_time; static unsigned char last_flag; TR0 0; // 先停定时器 current_time (TH0 8) | TL0; // 读取当前计数值 TH0 0; TL0 0; TR0 1; // 重新开始计时 high_time current_time / (SYSCLK / 1000000); // 换算为微秒 // 后续按high_time判断同步码、数据0、数据1 }这段代码的测量逻辑是每次下降沿到来时定时器里累计的值就是上一次下降沿到本次下降沿之间高电平的时间。之所以叫下降沿中断是因为接收模块空闲时输出高电平收到数据后每个高电平结束时产生下降沿。值得注意的是current_time必须用16位变量读取TH0和TL0如果单片机主频在12MHz下16位定时器最大计数65535对应约5.46ms而EV1527的最大高电平宽度不会超过1.5ms不会溢出。3.3 时间参数表哪些值决定了解码成功率参数名称典型值范围判定条件说明同步码高电平850us~1400us大于700us判为同步部分遥控器同步码高电平达到1600us数据0高电平250us~500us小于700us判为0部分芯片时间参数偏慢数据1高电平700us~1400us700~1400us判为1以同步码时间为基准动态调整帧间隔4ms~20ms超过2ms视为结束有些遥控器每帧间隔只有1ms时间参数不能写死最稳妥的做法是以同步码的高电平为基准做动态阈值。比如收到同步码高电平为1050us那么数据1的判定上限就是同步码的130%数据0的判定下限就是同步码的40%这样即使遥控器电池电量低导致脉冲宽度整体变宽解码逻辑依然能正确分类。这个动态阈值思路在第三节的代码里体现为每收到一次同步码就更新阈值变量后续数据位用新阈值判断。4. 程序实现学习、存储与发射4.1 学习模式的程序状态机与EEPROM映射学习型遥控器的程序逻辑是一个状态机空闲状态、学习状态、发射状态。空闲状态时如果收到有效解码帧直接进入发射状态把刚才收到的帧重发如果检测到学习按键被按下超过2秒进入学习状态。学习状态下的核心流程是等待接收模块捕获一帧完整数据校验通过后把帧数据按位存到EEPROMLED闪烁两次提示学习成功。enum State { IDLE, LEARN, TRANSMIT } current_state; void State_Machine(void) { switch (current_state) { case IDLE: if (KEY_LEARN 0) { delay_ms(20); if (KEY_LEARN 0) { current_state LEARN; LED_IND 0; // 进入学习状态LED点亮 } } if (frame_received_valid) { current_state TRANSMIT; } break; case LEARN: if (frame_received_valid) { EEPROM_Write(0x0000, frame_id_low); EEPROM_Write(0x0001, frame_id_high); EEPROM_Write(0x0002, frame_key); EEPROM_Write(0x0003, 0xAA); // 标志位表示已学习 LED_IND 0; delay_ms(100); LED_IND 1; delay_ms(100); LED_IND 0; delay_ms(100); LED_IND 1; current_state IDLE; } break; case TRANSMIT: RF_Send_Frame(); current_state IDLE; break; } }这里EEPROM地址0x0000到0x0003存储学习到的帧内容其中0x0003存储固定标志0xAA用于上电时判断是否已经学习过键值。STC15F104W的EEPROM按扇区擦除写之前要读出来比较如果目标地址已经写过值需要先擦除整个扇区否则写入无效。很多初学者在这里踩坑第二次学习时直接调用EEPROM_Write却不先擦除数据一直是FF表现为“学习不生效”。4.2 433发射用IO翻转复现脉冲序列发射的逻辑比解码简单按学习到的ID和键值逐位拼出帧格式然后根据时间参数控制发射引脚翻转。EV1527的帧格式是同步码加20位数据发射时先发送同步码的低350us和高1050us然后依次发送每一位数据数据0发送350us低加350us高数据1发送350us低加1050us高。完整帧发送完后需要等待一段延时再发下一帧一般连续发4帧帧间延时大于10ms接收端才能稳定识别。void RF_Send_Frame(void) { unsigned char i; unsigned char frame_data[3]; // 从EEPROM读取学习到的帧 frame_data[0] EEPROM_Read(0x0000); frame_data[1] EEPROM_Read(0x0001); frame_data[2] EEPROM_Read(0x0002); for (i 0; i 4; i) { // 连续发射4帧 RF_Send_Sync(); // 发送同步码 RF_Send_Bit(frame_data[0] 0x80); // 逐位发送20位数据 RF_Send_Bit(frame_data[0] 0x40); // ... 后续位按位发送 RF_Send_Bit(frame_data[2] 0x01); delay_ms(10); // 帧间间隔 } } void RF_Send_Sync(void) { RF_TX 0; delay_us(350); RF_TX 1; delay_us(1050); }发射函数的时间精度决定了接收端能否正确识别而STC15F104W的delay_us函数误差主要来自调用开销。如果发射引脚在350us延时结束后再置高实际低电平时间可能是360us这个误差在接收端的容忍范围内。但有一种情况必须避免发射过程中关闭定时器中断或其他中断否则中断嵌套会导致某个脉冲宽度偏差超过200us接收端会直接丢弃这一帧。4.3 学习加发射的完整流程与参数设置状态机加上上拉电阻的消抖逻辑后整个程序可以归纳为初始化IO和定时器进入主循环轮询按键和接收标志位。接收标志位由外部中断服务函数置1主循环里判断标志位后再进入状态机处理可以避免在中断里做复杂操作。定时器0在解码时只能用16位模式且不能开中断发射阶段定时器停止转而用软件延时。两个阶段共用一个定时器外设不需要切换只要保证不同时使用即可。关于时间参数表学习型遥控产品建议在EEPROM里额外保存一组“时间参数覆盖值”因为有些老款遥控器发射脉冲偏宽直接按标准阈值解码会失败。参数适配的做法是第一次学习时连续捕获同一条数据帧两次如果两次的同步码宽度差异小于10%就认为信号质量可靠把第一次测量到的同步码宽度作为该遥控器的专属同步码保存发射时也用这个值覆盖默认的1050us。这样同一个设备就能兼容不同厂家的遥控器拷贝成功率从90%提升到接近99%。5. 上电验证与排错技巧用逻辑分析仪校准时间参数板子焊好之后第一步不是烧程序而是先验证接收模块的供电和输出波形。用示波器或逻辑分析仪夹在接收模块DATA引脚和GND之间按住原装遥控器上的按键观察波形是否符合预期同步码高电平应该在800us到1600us之间数据位的脉冲宽度应当有稳定的两档分布。如果看到的是一团杂乱脉冲或者完全没有信号问题多半不是程序而是接收模块的供电质量或天线没有接好。常见的坑有三个。第一个是发射模块和接收模块共地问题发射瞬间地电位被拉高解码中断误触发表现为学习时LED乱闪。排查方式是在发射模块VCC入口串一个10欧姆电阻断开发射供电后再学习一次波形立刻变干净。第二个是软件延时函数的时间误差在12MHz主频下简单的for循环延时函数每循环一次约8个时钟周期如果编译器优化等级不同同一个延时函数实际延时可以差30%所以要固定优化等级用逻辑分析仪实际测量延时时间再调整循环次数。第三个是EEPROM扇区擦除的时序STC15F104W的EEPROM擦除操作可能持续几毫秒此时如果接收到新的RF信号中断只能挂起等待如果恰好这时数据来到了同步码阶段后续帧数据会全部丢失所以EEPROM写操作完成后要重新初始化接收状态机丢弃当前正在接收的半帧数据。最后给一个可复现的验证步骤烧录程序后按住原装遥控器距离接收模块1米左右发射观察LED闪烁两下表示学习成功。随后按学习按键进入发射模式把STC15F104W的发射模块靠近另一个同频接收端正常应该能触发接收端动作。如果学习成功但发射无效用逻辑分析仪对比发射引脚波形和原装遥控器的DATA波形重点看同步码宽度和帧间隔是否一致波形一致还不能接收检查发射模块的ASK调制对象是否接在了P3.1上部分发射模块需要高电平使能而STC15F104W的P3.1第二功能是TxD程序复位期间会被拉高一小段时间导致上电瞬间发出噪声帧干扰接收端的学习状态。在发射引脚对地并一个4.7K欧姆电阻能缓解这个问题这也是我在2.2节强调分压电阻的原因。本文还有配套的精品资源点击获取
返回列表