[STM32F4] UART数据采集

[复制链接]
69|10
cutfall 发表于 2026-8-10 17:10 | 显示全部楼层 |阅读模式

我需要通过 FrSky 接收机的 SBUS 总线读取舵机通道数值。FrSky 的 SBUS 电平逻辑和传统 Futaba 标准 SBUS 相反逻辑 0 对应硬件低电平、逻辑 1 对应硬件高电平。
我找到了不少 SBUS 数据帧解析代码,但目前单片机收不到接收机发来的 UART 数据。
我的思路是想让UART 接收中断回调函数每收到一整帧数据就触发一次,触发后会通过另一路串口往 Putty 调试终端打印提示信息。
后续逻辑原本计划拆分 SBUS 帧字节、换算出 18 个通道数值,但现在连数据接收阶段都没能打通。
我的代码

uint16_t failsafe_status;
uint8_t buf[25];
uint16_t CH[18];
int lenght=0;
uint16_t USB_Send_Data[]={0};
char msg[25];
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart1)
{
                        sprintf(msg, "FRAME AQCUIRED\r\n");
                        HAL_UART_Transmit(&huart2, (uint8_t*)msg, strlen(msg), HAL_MAX_DELAY);
        if (buf[0] == 0x0F) {
                CH[0] = (buf[1] >> 0 | (buf[2] << 8)) & 0x07FF;
                CH[1] = (buf[2] >> 3 | (buf[3] << 5)) & 0x07FF;
                CH[2] = (buf[3] >> 6 | (buf[4] << 2) | buf[5] << 10) & 0x07FF;
                CH[3] = (buf[5] >> 1 | (buf[6] << 7)) & 0x07FF;
                CH[4] = (buf[6] >> 4 | (buf[7] << 4)) & 0x07FF;
                CH[5] = (buf[7] >> 7 | (buf[8] << 1) | buf[9] << 9) & 0x07FF;
                CH[6] = (buf[9] >> 2 | (buf[10] << 6)) & 0x07FF;
                CH[7] = (buf[10] >> 5 | (buf[11] << 3)) & 0x07FF;
                CH[8] = (buf[12] << 0 | (buf[13] << 8)) & 0x07FF;
                CH[9] = (buf[13] >> 3 | (buf[14] << 5)) & 0x07FF;
                CH[10] = (buf[14] >> 6 | (buf[15] << 2) | buf[16] << 10) & 0x07FF;
                CH[11] = (buf[16] >> 1 | (buf[17] << 7)) & 0x07FF;
                CH[12] = (buf[17] >> 4 | (buf[18] << 4)) & 0x07FF;
                CH[13] = (buf[18] >> 7 | (buf[19] << 1) | buf[20] << 9) & 0x07FF;
                CH[14] = (buf[20] >> 2 | (buf[21] << 6)) & 0x07FF;
                CH[15] = (buf[21] >> 5 | (buf[22] << 3)) & 0x07FF;
                if (buf[23] & (1 << 0)) {
                        CH[16] = 1;
                } else {
                        CH[16] = 0;
                }
                if (buf[23] & (1 << 1)) {
                        CH[17] = 1;
                } else {
                        CH[17] = 0;
                }
                // Failsafe
                failsafe_status = SBUS_SIGNAL_OK;
                if (buf[23] & (1 << 2)) {
                        failsafe_status = SBUS_SIGNAL_LOST;
                }
                if (buf[23] & (1 << 3)) {
                        failsafe_status = SBUS_SIGNAL_FAILSAFE;
                }
                //        SBUS_footer=buf[24];
        }
}
/* USER CODE END 0 */


这段解析代码并非我原创,我怀疑缺少把串口收到的数据存入 buf 接收缓冲区的逻辑,是这个问题吗?缓冲区接收代码该怎么写?
现阶段为了简化调试,我暂时不想使用 DMA。
主循环逻辑很简单反复把 1~6 通道数值打印到串口调试终端。
828916a79954dbc882.png
串口打印功能本身完好,但既收不到任何通道数据,也不会打印收到帧提示。由此判断故障出在 SBUS 转 UART 接收环节:回调函数根本没有被触发执行。
我试过将串口数据位配置为 8 位、9 位,均无改善。
FrSky 采用反向 SBUS(硬件电平取反),我已经核对过电平极性、接线以及接收机内部参数设置都没问题。

想请教各位缓冲区数据接收逻辑、回调函数无法触发的问题该如何排查解决?

公羊子丹 发表于 2026-8-10 20:14 | 显示全部楼层
先跟你说个关键点,你现在完全没开接收监听,回调肯定不会进!不用DMA就用HAL_UART_Receive_IT,主函数初始化完串口后调用一次,收到一帧25字节才会进回调,缺这行等于白写解析函数。
周半梅 发表于 2026-8-10 20:15 | 显示全部楼层
FrSky反向SBUS坑超多,除了电平取反,串口模式必须是偶校验、停止位2,很多人只改数据位没用,你去CubeMX核对下校验和停止位配置,错一个就收不到信号。
帛灿灿 发表于 2026-8-10 20:16 | 显示全部楼层
我之前踩过一模一样的坑,只写了回调但忘了循环重启接收中断,单次接收完就停了。回调末尾加一句HAL_UART_Receive_IT持续监听,不然只收一次就卡死。
童雨竹 发表于 2026-8-10 20:17 | 显示全部楼层
建议你先做硬件分层测试,把接收机输出直接接示波器,确认有没有25字节完整帧输出,排除接收机没通电、通道未解锁导致无数据输出的情况。
万图 发表于 2026-8-10 20:18 | 显示全部楼层
你现在buf只定义没做数据填充,接收函数才是把数据存进buf的核心,主函数里加上HAL_UART_Receive_IT(&huart1
Wordsworth 发表于 2026-8-10 20:19 | 显示全部楼层
调侃一句,SBUS解析代码抄得完整,偏偏漏了最基础的接收启动语句,相当于买了菜却忘了开火做饭,先把接收中断开启代码补上再调试打印。
Bblythe 发表于 2026-8-10 20:20 | 显示全部楼层
想问下你接线有没有串联电阻?接收机SBUS输出电平是3.3V,要是直接接5V串口引脚会把信号拉垮,就算电平取反也会出现完全收不到数据的现象。
Pulitzer 发表于 2026-8-10 20:21 | 显示全部楼层
给你个简易排查顺序,先短接串口1的TX和RX自发自收测试回调能不能触发,能打印说明串口配置没问题,问题就锁定在接收机线路和SBUS协议参数上。
Uriah 发表于 2026-8-10 20:21 | 显示全部楼层
反向SBUS光硬件取反还不够,软件串口也要开启极性反转,CubeMX里找到UART极性反转选项打开,不然高低电平识别颠倒,单片机会识别不出有效字节。
Clyde011 发表于 2026-8-10 20:22 | 显示全部楼层
你主循环打印通道数值的逻辑现在完全没用,回调没触发buf里全是乱码,先单独写一段测试代码,只做接收和打印原始字节,等能打印数据再去解析通道值。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

193

主题

195

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部
0