#include "rf.h" #include "../App/config.h" #include "intrins.h" // ATR5179 射频开关控制脚 sbit RF_TX = P2^0; // V1 控制端 (1: 选通天线到 TX 路径) sbit RF_RX = P3^7; // V2 控制端 (1: 选通天线到 RX 路径) // 射频数据与控制引脚 sbit RF_TX_DAT = P3^6; // LT4455 数据输入 (DIN) sbit RF_RX_DATA = P2^1; // LR690L 数据输出 (DATA) sbit SHUT = P2^2; // LR690L 休眠脚 (0:工作, 1:休眠) // External functions defined in main.c extern void Delay_us(u16 us); extern void Delay_ms(u16 ms); extern u16 GetTimer0_Safe(void); extern void Uart_SendString(char *s); extern void Uart_SendHex4(u8 val); extern void Uart_SendHex8(u8 val); extern void Uart_SendHex16(u16 val); extern void Uart_SendHex20(u32 val); extern void Uart_SendByte(u8 dat); void RF_Init(void) { // P2.0 (RF_TX) 和 P2.2 (SHUT) 配置为推挽输出,P2.1 (RF_RX_DATA) 配置为双向口/输入 P2M1 &= ~((1 << 0) | (1 << 1) | (1 << 2)); P2M0 &= ~(1 << 1); P2M0 |= ((1 << 0) | (1 << 2)); // P3.6 (RF_TX_DAT), P3.7 (RF_RX) 配置为推挽输出 P3M1 &= ~((1 << 6) | (1 << 7)); P3M0 |= ((1 << 6) | (1 << 7)); RF_TX = 0; SHUT = 1; // 默认关闭接收芯片 RF_RX = 0; RF_TX_DAT = 0; } void RF_SetMode(u8 mode) { if (mode == 0) // Sleep/Idle { SHUT = 1; // LR690L Sleep RF_RX = 0; // 断开接收天线 RF_TX = 0; // 断开发射天线 } else if (mode == 1) // Rx Mode { SHUT = 0; // LR690L 工作 RF_RX = 1; // 天线切至接收端 RF_TX = 0; } else if (mode == 2) // Tx Mode { SHUT = 1; // LR690L 睡眠 RF_RX = 0; RF_TX = 1; // 天线切至发射端 } } void EV1527_TxFrame(u32 addr, u8 dat) { u8 i; // 1. 同步脉冲: 1T 高电平 + 31T 低电平 RF_TX_DAT = 1; Delay_us(320); RF_TX_DAT = 0; Delay_us(9920); // 2. 20位地址码 (MSB first) for (i = 0; i < 20; i++) { if ((addr >> (19 - i)) & 1) { // 逻辑 1: 3T 高电平 + 1T 低电平 RF_TX_DAT = 1; Delay_us(960); RF_TX_DAT = 0; Delay_us(320); } else { // 逻辑 0: 1T 高电平 + 3T 低电平 RF_TX_DAT = 1; Delay_us(320); RF_TX_DAT = 0; Delay_us(960); } } // 3. 4位数据码 (MSB first) for (i = 0; i < 4; i++) { if ((dat >> (3 - i)) & 1) { // 逻辑 1: 3T 高电平 + 1T 低电平 RF_TX_DAT = 1; Delay_us(960); RF_TX_DAT = 0; Delay_us(320); } else { // 逻辑 0: 1T 高电平 + 3T 低电平 RF_TX_DAT = 1; Delay_us(320); RF_TX_DAT = 0; Delay_us(960); } } } void EV1527_Transmit(u32 addr, u8 dat) { u8 r; for (r = 0; r < 25; r++) // 增加到 25 帧(约 340ms) { EV1527_TxFrame(addr, dat); } } u16 GetPulseDuration(u8 state, u16 timeout_us) { u16 timeout_ticks = (u16)((u32)timeout_us * (MAIN_Fosc / 1000000UL) / 12UL); TL0 = 0; TH0 = 0; TR0 = 1; // 启动定时器0 while (RF_RX_DATA == state) { if (GetTimer0_Safe() > timeout_ticks) { TR0 = 0; return 0; // 超时 } } TR0 = 0; return (u16)((u32)GetTimer0_Safe() * 12UL / (MAIN_Fosc / 1000000UL)); // 返回微秒数 } bit EV1527_Decode(u32 *out_addr, u8 *out_data) { u16 high_time, low_time; u8 i; u32 addr = 0; u8 dat = 0; u16 T; u16 idata raw_h[24]; u16 idata raw_l[24]; // 1. 同步头捕获: 必须是低电平状态之后变高电平开始 if (RF_RX_DATA == 0) { u16 wait_cnt = 0; while (RF_RX_DATA == 0) { Delay_us(10); wait_cnt++; if (wait_cnt > 3000) // 30ms 超时 return 0; } } // 测量同步头高电平时间 (放宽至 2500us) high_time = GetPulseDuration(1, 2500); if (high_time < 50 || high_time > 2500) return 0; // 测量同步头低电平时间 (放宽至 60000us) low_time = GetPulseDuration(0, 60000); if (low_time < 1500 || low_time > 60000) return 0; // 计算高低电平时间之比。对于标准 EV1527,低电平是高电平的 31 倍。 // 放宽比例范围为 15 到 48,以应对各种不同的遥控器电阻。 { u32 ratio = (u32)low_time / high_time; if (ratio < 15 || ratio > 48) return 0; } // 估算基准脉冲周期 T = low_time / 31 T = low_time / 31; if (T == 0) T = 1; // 2. 连续抓取 24 个数据脉冲 for (i = 0; i < 24; i++) { u16 wait_cnt = 0; // 等待下一个数据脉冲的上升沿 (如果当前是低电平,等待它变高) while (RF_RX_DATA == 0) { Delay_us(5); wait_cnt++; if (wait_cnt > 1000) // 5ms 超时 { return 0; // 解码失败 } } // 测量高电平持续时间和低电平持续时间 raw_h[i] = GetPulseDuration(1, 5000); if (raw_h[i] == 0) return 0; raw_l[i] = GetPulseDuration(0, 5000); if (raw_l[i] == 0) return 0; } // 3. 将抓到的全部 24 位脉冲数据无条件输出到串口 (缩短输出信息以防止阻塞接收) Uart_SendString("Captured: Sync H="); Uart_SendHex16(high_time); Uart_SendString("us, L="); Uart_SendHex16(low_time); Uart_SendString("us, T="); Uart_SendHex16(T); Uart_SendString("us\r\n"); // 4. 组合成 24 位地址与数据,使用自适应阈值:如果高电平时间比低电平时间长,判定为 1,反之为 0 for (i = 0; i < 24; i++) { if (raw_h[i] > raw_l[i]) { if (i < 20) addr = (addr << 1) | 1; else dat = (dat << 1) | 1; } else { if (i < 20) addr = (addr << 1); else dat = (dat << 1); } } *out_addr = addr; *out_data = dat; // 串口打印解码结果方便现场调试 Uart_SendString("Decoded ADDR: 0x"); Uart_SendHex20(addr); Uart_SendString(", DATA: 0x"); Uart_SendHex4(dat); Uart_SendString("\r\n"); return 1; } void Loopback_Test(void) { u16 match_count = 0; u16 i; SHUT = 0; // 使能接收芯片 RF_RX = 1; // 选通天线到接收端 RF_TX = 0; // 发送侧断开 Delay_ms(100); Uart_SendString("Starting RF Loopback Self-Test...\r\n"); for (i = 0; i < 100; i++) { RF_TX_DAT = 1; Delay_us(500); if (RF_RX_DATA == 1) match_count++; RF_TX_DAT = 0; Delay_us(500); if (RF_RX_DATA == 0) match_count++; } Uart_SendString("Loopback Match Count: "); Uart_SendHex16(match_count); Uart_SendString("/200\r\n"); if (match_count > 150) { Uart_SendString("Result: PASS! Transmitter is emitting RF, and Receiver is picking it up!\r\n"); } else { Uart_SendString("Result: FAIL! No RF signal detected. Check hardware.\r\n"); } SHUT = 1; RF_RX = 0; } // Touched to align with doc updates V3