#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; } }