简介:面向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-433S,DATA引脚接P3.1,这个引脚在复位期间是高电平,发射模块在上电瞬间会短暂发射一段载波,解决办法是在P3.1到发射模块DATA之间串一个10K欧姆电阻,然后对地接一个4.7K欧姆下拉电阻,让复位期间的默认状态可靠置低。学习按键接P3.4,按键另一端直接接地,P3.4内部上拉使能,不需要外部上拉电阻。LED指示接P3.3,串220欧姆电阻到VCC,低电平点亮。
2.2.1 SOP8引脚分配表与电源设计
STC15F104W的SOP8封装引脚定义如下表,原理图绘制时按这个映射连接:
| 引脚号 | 引脚名 | 第二功能 | 本方案用途 | 外部连接 |
|---|---|---|---|---|
| 1 | P3.0 | RxD | 预留/调试 | 可接串口工具 |
| 2 | P3.1 | TxD | 433发射输出 | 经10K+4.7K分压接发射模块DATA |
| 3 | P3.2 | INT0 | 433接收输入 | 经1K电阻接接收模块DATA |
| 4 | P3.3 | INT1 | LED指示输出 | 经220R接LED到VCC |
| 5 | P3.4 | T0 | 学习按键输入 | 按键到GND,内部上拉 |
| 6 | P3.5 | T1 | 预留 | 悬空或接测试点 |
| 7 | VCC | - | 电源 | 3.3V~5V,10uF+0.1uF去耦 |
| 8 | GND | - | 地 | 与模块共地 |
电源部分是原理图里最容易翻车的。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~1400us | 700~1400us判为1 | 以同步码时间为基准动态调整 |
| 帧间隔 | 4ms~20ms | 超过2ms视为结束 | 有些遥控器每帧间隔只有1ms |
时间参数不能写死,最稳妥的做法是以同步码的高电平为基准做动态阈值。比如收到同步码高电平为1050us,那么数据1的判定上限就是同步码的130%,数据0的判定下限就是同步码的40%,这样即使遥控器电池电量低导致脉冲宽度整体变宽,解码逻辑依然能正确分类。这个动态阈值思路在第三节的代码里体现为:每收到一次同步码就更新阈值变量,后续数据位用新阈值判断。
4. 程序实现:学习、存储与发射
4.1 学习模式的程序状态机与EEPROM映射
学习型遥控器的程序逻辑是一个状态机:空闲状态、学习状态、发射状态。空闲状态时如果收到有效解码帧,直接进入发射状态把刚才收到的帧重发;如果检测到学习按键被按下超过2秒,进入学习状态。学习状态下的核心流程是:等待接收模块捕获一帧完整数据,校验通过后把帧数据按位存到EEPROM,LED闪烁两次提示学习成功。
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节强调分压电阻的原因。
本文还有配套的精品资源,点击获取