From ef3601f9e8df07133fbaa42f76c91130348dc58d Mon Sep 17 00:00:00 2001 From: admin Date: Mon, 29 Jun 2026 02:29:16 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E4=BA=86=E4=B8=80=E4=BA=9B?= =?UTF-8?q?=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- rx/STC8H-cn.pdf => STC8H-cn.pdf | Bin rx/{src => }/STC8_SDCC.H | 0 rx/config.h | 37 +++- rx/main.c | 6 + rx/{src => }/nrf24.c | 0 rx/{src => }/nrf24.h | 0 rx/src/uart.c | 65 ------- rx/src/uart.h | 27 --- rx/test.ihx | 12 -- rx/uart.c | 250 ++++++++++++++++++++++++++ rx/uart.h | 67 +++++++ rx/操作指南.pdf => 接收机操作指南.pdf | Bin 12 files changed, 354 insertions(+), 110 deletions(-) rename rx/STC8H-cn.pdf => STC8H-cn.pdf (100%) rename rx/{src => }/STC8_SDCC.H (100%) rename rx/{src => }/nrf24.c (100%) rename rx/{src => }/nrf24.h (100%) delete mode 100644 rx/src/uart.c delete mode 100644 rx/src/uart.h delete mode 100644 rx/test.ihx create mode 100644 rx/uart.c create mode 100644 rx/uart.h rename rx/操作指南.pdf => 接收机操作指南.pdf (100%) diff --git a/rx/STC8H-cn.pdf b/STC8H-cn.pdf similarity index 100% rename from rx/STC8H-cn.pdf rename to STC8H-cn.pdf diff --git a/rx/src/STC8_SDCC.H b/rx/STC8_SDCC.H similarity index 100% rename from rx/src/STC8_SDCC.H rename to rx/STC8_SDCC.H diff --git a/rx/config.h b/rx/config.h index c3887a1..35fcc82 100644 --- a/rx/config.h +++ b/rx/config.h @@ -1,5 +1,4 @@ #include "STC8_SDCC.H" -#include /* ======================================================================== * 系统常量 @@ -30,10 +29,41 @@ #define CONNECTED 2 /* 常亮 - 已连接 */ #define NRF_ERROR 4 /* 双闪 - NRF硬件错误 */ +/* UART运行模式 */ +#define UART_UART 0 +#define UART_SBUS 1 +#define UART_CRFS 2 + /* ======================================================================== * 全局变量 * ======================================================================== */ + // 配置信息 +struct CONFIG +{ + // 运行模式 + uint8 runModel; + // nrf24使用的通道 + uint8 nrf_ch; + // nrf24使用的对频短语 + uint8 nrf_bindphr[6]; + // nrf24地址,40位 + uint8 nrf_addr[5]; + // 对频标志 + uint8 tx_magic; + // 记录的发射机地址 + uint8 tx_addr[5]; +} config; + +// nrf24l01接收的数据 +struct RFDATA +{ + // nrf24l01一次性接收32byte数据 + uint8 RefreshRate; + uint16 CH[15]; + uint8 end; +} RF_Data; + // 系统滴答定时器计数 (用于LED闪烁) static uint8 sys_tick = 0; @@ -68,11 +98,6 @@ static uint8_t telem_rate_hz = 2; /* 回传频率 1-10Hz, 默认2Hz */ static uint8_t __xdata crfs_forward_buf[24]; static uint8_t crfs_forward_len = 0; -/* UART 接收缓冲 (放在 xdata) */ -static uint8_t __xdata uart_rx_buf[UART_BUF_SIZE]; -static uint8_t uart_rx_idx = 0; -static volatile uint8_t uart_cmd_ready = 0; - /* 定时器计数 (用于LED闪烁) */ static volatile uint16_t sys_tick = 0; diff --git a/rx/main.c b/rx/main.c index 76e7b7e..b6235a3 100644 --- a/rx/main.c +++ b/rx/main.c @@ -150,6 +150,12 @@ void SystemInit() { SPSTAT = 0xC0; // 3. (可选) 使能SPI中断 // IE2 |= ESPI; + + // ADC_Init() + ADCCFG = ADC_RESFMT; /* 右对齐, 12位结果 */ + ADC_CONTR = ADC_POWER; /* 开启ADC电源 */ + /* 选择通道11 (P3.3) */ + ADC_CONTR = (ADC_CONTR & 0xF0) | 0x0B; } void PWMBInit() { // 1. 使能访问扩展特殊功能寄存器 (XFR) diff --git a/rx/src/nrf24.c b/rx/nrf24.c similarity index 100% rename from rx/src/nrf24.c rename to rx/nrf24.c diff --git a/rx/src/nrf24.h b/rx/nrf24.h similarity index 100% rename from rx/src/nrf24.h rename to rx/nrf24.h diff --git a/rx/src/uart.c b/rx/src/uart.c deleted file mode 100644 index eab87f5..0000000 --- a/rx/src/uart.c +++ /dev/null @@ -1,65 +0,0 @@ -#include "uart.h" - -/* ======================================================================== - * UART1 - 串口通信 (使用Timer2做波特率发生器) - * ======================================================================== */ - -/* UART1 中断服务 */ -void UART1_Interrupt(void) __interrupt(4) { - if (RI) { - RI = 0; - uint8_t dat = SBUF; - - if (out_mode == OUT_MODE_CRFS) { - /* CRFS 模式: 接收飞控发来的 CRSF 帧并缓存转发 */ - if (dat == 0xEE) { - /* CRSF 帧起始 */ - crfs_forward_len = 0; - crfs_forward_buf[crfs_forward_len++] = dat; - } else if (crfs_forward_len > 0 && crfs_forward_len < sizeof(crfs_forward_buf)) { - crfs_forward_buf[crfs_forward_len++] = dat; - /* 如果收到完整帧 (根据长度字段), 标记为待转发 */ - if (crfs_forward_len >= 3) { - uint8_t frame_len = crfs_forward_buf[1] + 2; /* type+payload+crc = length field */ - if (crfs_forward_len >= frame_len) { - /* 完整帧已收到, 保持缓存, 主循环会处理转发 */ - } - } - } - } else { - /* 命令接收: 回车/换行结束 */ - if (dat == '\r' || dat == '\n') { - if (uart_rx_idx > 0) { - uart_rx_buf[uart_rx_idx] = '\0'; - uart_cmd_ready = 1; - } - uart_rx_idx = 0; - } else { - if (uart_rx_idx < UART_BUF_SIZE - 1) { - uart_rx_buf[uart_rx_idx++] = dat; - } - } - } - } - if (TI) { - TI = 0; - } -} - -static void UART1_SendByte(uint8_t dat) { - SBUF = dat; - while (!TI); - TI = 0; -} - -static void UART1_SendString(const char *s) { - while (*s) { - UART1_SendByte((uint8_t)(*s++)); - } -} - -static void UART1_SendStringLen(const char *s, uint8_t len) { - for (uint8_t i = 0; i < len; i++) { - UART1_SendByte((uint8_t)s[i]); - } -} diff --git a/rx/src/uart.h b/rx/src/uart.h deleted file mode 100644 index 935ffd7..0000000 --- a/rx/src/uart.h +++ /dev/null @@ -1,27 +0,0 @@ -# ifndef CONFIG -# define CONFIG -# include "CONFIG.h" -# endif - -/* -uart初始化, -uart发送, -uart接收, -uart命令解析, -uart命令响应, -uart接收缓冲区, -uart发送缓冲区, -uart接收索引, -uart命令就绪标志, -uart中断服务程序, -uart波特率设置 -*/ -void UART1_Init(void); - -void UART1_Interrupt(void) __interrupt(4); - -void UART1_Send(void); -void UART1_Receive(void); -void UART1_ParseCommand(void); -void UART1_Response(void); -void UART1_SetBaudRate(void); \ No newline at end of file diff --git a/rx/test.ihx b/rx/test.ihx deleted file mode 100644 index 31407cb..0000000 --- a/rx/test.ihx +++ /dev/null @@ -1,12 +0,0 @@ -:03000000020006F5 -:03005F0002000399 -:0300030002006296 -:0700620075B20075B1002228 -:06003500E478FFF6D8FD9F -:200013007900E94400601B7A0090006D780175A000E493F2A308B8000205A0D9F4DAF27526 -:02003300A0FF2C -:20003B007800E84400600A790175A000E4F309D8FC7800E84400600C7900900001E4F0A3C3 -:04005B00D8FCD9FAFA -:0D000600758107120069E5826003020003A6 -:04006900758200227A -:00000001FF diff --git a/rx/uart.c b/rx/uart.c new file mode 100644 index 0000000..5bbdf8c --- /dev/null +++ b/rx/uart.c @@ -0,0 +1,250 @@ +#include "uart.h" + +/* ======================================================================== + * UART1 - 串口通信 (使用Timer2做波特率发生器) + * ======================================================================== + +# 串口驱动,需要包含以下内容 + * UART模式,波特率115200 + * 数据解析,命令表: + 模式切换 MODEL(UART | SBUS | CRFS) + 模块地址 ADDR(0x00 00 00 00 00) + 对频短语 PHRASE(xxxxxx) + 切换频道 TUN(40) + 清除信息 DEL(DATA) + * SBUS模式,波特率100000 + * CRFS模式,波特率420000,功能占位,暂不实现 + */ + + +static void Cmd_Parse(void) { + if (!uart_cmd_ready) return; + uart_cmd_ready = 0; + + char *cmd = (char *)uart_rx_buf; + + /* MODEL(SBUS) - 切换到SBUS模式 */ + if (strcmp(cmd, "MODEL(SBUS)") == 0) { + out_mode = OUT_MODE_SBUS; + SBUS_Init(); + Cmd_Respond("OK"); + return; + } + + /* MODEL(PWM) - 切换到PWM模式 */ + if (strcmp(cmd, "MODEL(PWM)") == 0) { + out_mode = OUT_MODE_PWM; + /* 重新初始化UART1为115200 */ + UART1_Init(); + Cmd_Respond("OK"); + return; + } + + /* MODEL(UART) - 切换到UART模式 (占位) */ + if (strcmp(cmd, "MODEL(UART)") == 0) { + out_mode = OUT_MODE_UART; + UART1_Init(); + Cmd_Respond("OK"); + return; + } + + /* MODEL(CRFS) - 切换到CRFS/CRSF输出模式 */ + if (strcmp(cmd, "MODEL(CRFS)") == 0) { + out_mode = OUT_MODE_CRFS; + CRFS_Init(); + Cmd_Respond("OK"); + return; + } + + /* ADDR(0xHH HH HH HH HH) - 切换NRF24L01地址 */ + if (cmd[0] == 'A' && cmd[1] == 'D' && cmd[2] == 'D' && cmd[3] == 'R') { + /* 解析: ADDR(0xHH HH HH HH HH) */ + static uint8_t __xdata new_addr[NRF_ADDR_WIDTH]; + uint8_t ok = 1; + char *p = cmd + 5; /* 跳过 "ADDR(" */ + for (uint8_t i = 0; i < NRF_ADDR_WIDTH; i++) { + /* 跳过 "0x" */ + if (*p == '0' && (*(p+1) == 'x' || *(p+1) == 'X')) p += 2; + /* 跳过空格 */ + while (*p == ' ') p++; + /* 解析两位十六进制 */ + uint8_t hi = 0, lo = 0; + if (*p >= '0' && *p <= '9') hi = *p - '0'; + else if (*p >= 'A' && *p <= 'F') hi = *p - 'A' + 10; + else if (*p >= 'a' && *p <= 'f') hi = *p - 'a' + 10; + else { ok = 0; break; } + p++; + if (*p >= '0' && *p <= '9') lo = *p - '0'; + else if (*p >= 'A' && *p <= 'F') lo = *p - 'A' + 10; + else if (*p >= 'a' && *p <= 'f') lo = *p - 'a' + 10; + else { ok = 0; break; } + p++; + new_addr[i] = (hi << 4) | lo; + } + if (ok) { + for (uint8_t i = 0; i < NRF_ADDR_WIDTH; i++) + tx_addr[i] = new_addr[i]; + NRF24L01_WriteBuf(NRF_TX_ADDR, tx_addr, NRF_ADDR_WIDTH); + NRF24L01_WriteBuf(NRF_RX_ADDR_P0, tx_addr, NRF_ADDR_WIDTH); + Cmd_Respond("OK"); + } else { + Cmd_Respond("ERR_ADDR"); + } + return; + } + + /* TUN(N) - 切换RF频道 */ + if (cmd[0] == 'T' && cmd[1] == 'U' && cmd[2] == 'N') { + uint8_t ch = 0; + char *p = cmd + 4; /* 跳过 "TUN(" */ + while (*p >= '0' && *p <= '9') { + ch = ch * 10 + (*p - '0'); + p++; + } + if (ch <= NRF_MAX_CHANNEL) { + NRF24L01_SetChannel(ch); + Cmd_Respond("OK"); + } else { + Cmd_Respond("ERR_RANGE"); + } + return; + } + + /* DEL(BIND) - 清除对频信息 */ + if (strcmp(cmd, "DEL(BIND)") == 0) { + /* 擦除EEPROM中的对频标志 */ + IAP_EraseSector(0x0000); + IAP_WriteByte(EEPROM_ADDR_BIND_FLAG, 0x00); + rx_state = RX_STATE_BINDING; + NRF_EnterBindMode(); + Cmd_Respond("OK"); + return; + } + + /* PHRASE(xxxxxx) - 设置对频短语, 1~6位字母数字 */ + if (cmd[0] == 'P' && cmd[1] == 'H' && cmd[2] == 'R' && cmd[3] == 'A' + && cmd[4] == 'S' && cmd[5] == 'E') { + uint8_t i; + char *p = cmd + 7; /* 跳过 "PHRASE(" */ + /* 计算短语长度 (直到 ')' 或结束) */ + uint8_t len = 0; + while (p[len] && p[len] != ')' && len < RF_PHRASE_LEN) { + char c = p[len]; + /* 只允许字母和数字 */ + if (!((c >= '0' && c <= '9') || + (c >= 'A' && c <= 'Z') || + (c >= 'a' && c <= 'z'))) { + Cmd_Respond("ERR"); + return; + } + len++; + } + if (len < 1 || len > RF_PHRASE_LEN) { + Cmd_Respond("ERR_RANGE"); + return; + } + /* 复制新短语 */ + for (i = 0; i < len; i++) + bind_phrase[i] = (uint8_t)p[i]; + /* 剩余部分用空格填充 */ + for (i = len; i < RF_PHRASE_LEN; i++) + bind_phrase[i] = ' '; + /* 保存到EEPROM */ + IAP_EraseSector(0x0000); + IAP_WriteByte(EEPROM_ADDR_BIND_FLAG, EEPROM_BIND_MAGIC); + for (i = 0; i < NRF_ADDR_WIDTH; i++) + IAP_WriteByte(EEPROM_ADDR_TX_ADDR + i, tx_addr[i]); + IAP_WriteByte(EEPROM_ADDR_RF_CH, rf_channel); + for (i = 0; i < RF_PHRASE_LEN; i++) + IAP_WriteByte(EEPROM_ADDR_BIND_PHRASE + i, bind_phrase[i]); + /* 重新初始化NRF以使用新短语 */ + NRF24L01_Init(); + NRF24L01_RXMode(); + Cmd_Respond("OK"); + return; + } + + /* TELEM(N) - 设置回传频率 1~10Hz */ + if (cmd[0] == 'T' && cmd[1] == 'E' && cmd[2] == 'L' && cmd[3] == 'E' + && cmd[4] == 'M') { + uint8_t hz = 0; + char *p = cmd + 6; /* 跳过 "TELEM(" */ + while (*p >= '0' && *p <= '9') { + hz = hz * 10 + (*p - '0'); + p++; + } + if (hz >= 1 && hz <= 10) { + telem_rate_hz = hz; + Cmd_Respond("OK"); + } else { + Cmd_Respond("ERR_RANGE"); + } + return; + } + + /* 未知命令 */ + Cmd_Respond("UNK"); +} + + +static void UART1_SendByte(uint8_t dat) { + SBUF = dat; + while (!TI); + TI = 0; +} + +static void UART1_SendString(const char *s) { + while (*s) { + UART1_SendByte((uint8_t)(*s++)); + } +} + +static void UART1_SendStringLen(const char *s, uint8_t len) { + for (uint8_t i = 0; i < len; i++) { + UART1_SendByte((uint8_t)s[i]); + } +} + +static void SBUS_Init(void) { + /* 切换到 SBUS 波特率 100kbps */ + /* 100000 @ 24MHz: T2 reload = 65536 - 60 = 0xFFC4 */ + T2H = 0xFF; + T2L = 0xC4; + AUXR |= T2x12; + AUXR |= T2R; + + /* 8E2: 8数据位, 偶校验, 2停止位 */ + PCON |= SMOD0; /* SMOD0=1, 帧格式由SM2控制 */ + SCON &= ~0x0E; /* 清除SM2, TB8 */ + /* 注意: 对于SBUS, 标准是8E2, 但这里通过三极管反相, + * 所以实际发送的是反相SBUS信号 */ +} + +/* UART1 中断服务 */ +void UART1_Interrupt(void) __interrupt(4) { + if (RI) { + RI = 0; + uint8_t dat = SBUF; + + if (config.runModel == UART_CRFS) { + /* CRFS 模式: 接收飞控发来的 CRSF 帧并缓存转发 */ + // 占位,暂不实现 + } else { + /* 命令接收: 回车/换行结束 */ + if (dat == '\r' || dat == '\n') { + if (uart_rx_idx > 0) { + uart_rx_buf[uart_rx_idx] = '\0'; + uart_cmd_ready = 1; + } + uart_rx_idx = 0; + } else { + if (uart_rx_idx < UART_BUF_SIZE - 1) { + uart_rx_buf[uart_rx_idx++] = dat; + } + } + } + } + if (TI) { + TI = 0; + } +} diff --git a/rx/uart.h b/rx/uart.h new file mode 100644 index 0000000..0df54c8 --- /dev/null +++ b/rx/uart.h @@ -0,0 +1,67 @@ +# ifndef CONFIG +# define CONFIG +# include "config.h" +# endif + +/* UART 接收缓冲 (放在 xdata) */ +static uint8 __xdata uart_rx_buf[UART_BUF_SIZE]; +static uint8 uart_rx_idx = 0; +static bool uart_cmd_ready = 0; + + +/* +uart初始化, +uart发送, +uart接收, +uart命令解析, +uart命令响应, +uart接收缓冲区, +uart发送缓冲区, +uart接收索引, +uart命令就绪标志, +uart中断服务程序, +uart波特率设置 +*/ +void UART1_Init(void); + +void UART1_Interrupt(void) __interrupt(4); + +void UART1_Send(void); +void UART1_Receive(void); +void UART1_ParseCommand(void); +void UART1_Response(void); +void UART1_SetBaudRate(void); + + 0x00, 0xD5, 0x7F, 0xAA, 0xFE, 0x2B, 0x81, 0x54, + 0x29, 0xFC, 0x56, 0x83, 0xD7, 0x02, 0xA8, 0x7D, + 0x52, 0x87, 0x2D, 0xF8, 0xAC, 0x79, 0xD3, 0x06, + 0x7B, 0xAE, 0x04, 0xD1, 0x85, 0x50, 0xFA, 0x2F, + 0xA4, 0x71, 0xDB, 0x0E, 0x5A, 0x8F, 0x25, 0xF0, + 0x8D, 0x58, 0xF2, 0x27, 0x73, 0xA6, 0x0C, 0xD9, + 0xF6, 0x23, 0x89, 0x5C, 0x08, 0xDD, 0x77, 0xA2, + 0xDF, 0x0A, 0xA0, 0x75, 0x21, 0xF4, 0x5E, 0x8B, + 0x9D, 0x48, 0xE2, 0x37, 0x63, 0xB6, 0x1C, 0xC9, + 0xB4, 0x61, 0xCB, 0x1E, 0x4A, 0x9F, 0x35, 0xE0, + 0xCF, 0x1A, 0xB0, 0x65, 0x31, 0xE4, 0x4E, 0x9B, + 0xE6, 0x33, 0x99, 0x4C, 0x18, 0xCD, 0x67, 0xB2, + 0x39, 0xEC, 0x46, 0x93, 0xC7, 0x12, 0xB8, 0x6D, + 0x10, 0xC5, 0x6F, 0xBA, 0xEE, 0x3B, 0x91, 0x44, + 0x6B, 0xBE, 0x14, 0xC1, 0x95, 0x40, 0xEA, 0x3F, + 0x42, 0x97, 0x3D, 0xE8, 0xBC, 0x69, 0xC3, 0x16, + 0xEF, 0x3A, 0x90, 0x45, 0x11, 0xC4, 0x6E, 0xBB, + 0xC6, 0x13, 0xB9, 0x6C, 0x38, 0xED, 0x47, 0x92, + 0xBD, 0x68, 0xC2, 0x17, 0x43, 0x96, 0x3C, 0xE9, + 0x94, 0x41, 0xEB, 0x3E, 0x6A, 0xBF, 0x15, 0xC0, + 0x4B, 0x9E, 0x34, 0xE1, 0xB5, 0x60, 0xCA, 0x1F, + 0x62, 0xB7, 0x1D, 0xC8, 0x9C, 0x49, 0xE3, 0x36, + 0x19, 0xCC, 0x66, 0xB3, 0xE7, 0x32, 0x98, 0x4D, + 0x30, 0xE5, 0x4F, 0x9A, 0xCE, 0x1B, 0xB1, 0x64, + 0x72, 0xA7, 0x0D, 0xD8, 0x8C, 0x59, 0xF3, 0x26, + 0x5B, 0x8E, 0x24, 0xF1, 0xA5, 0x70, 0xDA, 0x0F, + 0x20, 0xF5, 0x5F, 0x8A, 0xDE, 0x0B, 0xA1, 0x74, + 0x09, 0xDC, 0x76, 0xA3, 0xF7, 0x22, 0x88, 0x5D, + 0xD6, 0x03, 0xA9, 0x7C, 0x28, 0xFD, 0x57, 0x82, + 0xFF, 0x2A, 0x80, 0x55, 0x01, 0xD4, 0x7E, 0xAB, + 0x84, 0x51, 0xFB, 0x2E, 0x7A, 0xAF, 0x05, 0xD0, + 0xAD, 0x78, 0xD2, 0x07, 0x53, 0x86, 0x2C, 0xF9 +}; \ No newline at end of file diff --git a/rx/操作指南.pdf b/接收机操作指南.pdf similarity index 100% rename from rx/操作指南.pdf rename to 接收机操作指南.pdf