STM32/STM8技术论坛
直播中

王宇翔

未满1年用户 3经验值
擅长:电源/新能源 MEMS/传感技术 嵌入式技术 制造/封装 连接器 EMC/EMI设计 存储技术 EDA/IC设计 接口/总线/驱动 控制/MCU
私信 关注
[问答]

stm32f103c8t6读不到完整的MC6C遥控器Uart数据帧怎么办

我用stm32c8t6最小系统板做飞控,时钟为72MHz,在使用Usart通信尝试读取sbus信号时,发现只能读取到16.16.16.16.16.16226.181.117.91.56.13为循环的信号,虽然拨动摇杆数字循环会有变化,但是16数量不变。(已使用dma且dma优先级为最高,4e770194b8edc235812d9b06ab9b71a6.png
两个dma邮箱都这样)
image.png
image.png

image.png

image.png

有大佬知道这是什么情况导致的吗?我目前猜测是接收机发送数据过快让mcu处理不过来

回帖(2)

chenwei6991627

2025-8-14 08:47:56
波特率多少呢
举报

一说就是错

2025-8-18 16:41:18

针对您在读取MC6C遥控器UART(SBUS协议)时遇到的异常数据问题(出现重复16等固定字节),以下是综合分析及解决方案:


问题根源分析




  1. 反相信号未处理(关键原因)



    • SBUS使用 反相TTL逻辑(0为高电平,1为低电平),而STM32仅支持标准TTL

    • 未处理的信号被误判,导致帧头/帧尾检测失败,出现大量0x10(16)




  2. 串口配置错误



    • SBUS要求:波特率 100kbps(非115200)、偶校验(EVEN)、2位停止位

    • 配置不匹配导致数据错位




  3. DMA缓冲区/模式问题



    • 缓冲区过小(<25字节)或非循环模式可能导致数据覆盖

    • DMA请求优先级不足时可能被高优先级中断抢占




  4. 硬件干扰



    • SBUS长线传输易受干扰(需串联220Ω电阻抗干扰)






完整解决方案


1. 反相信号硬件处理(必做)


在接收引脚串联 信号反相电路


MC6C TX →┬→ 1N4148二极管(阴极)→ STM32 RX引脚
        └→ 10KΩ上拉电阻 → 3.3V

或使用电平转换芯片(如TXS0102)


2. 精确串口配置(以USART1为例)


// 配置示例(使用标准库)
USART_InitTypeDef uart_init;
uart_init.USART_BaudRate = 100000;    // SBUS波特率100kbps
uart_init.USART_WordLength = USART_WordLength_9b; // 包含校验位的9位
uart_init.USART_StopBits = USART_StopBits_2;       // 2位停止位
uart_init.USART_Parity = USART_Parity_Even;        // 偶校验
uart_init.USART_Mode = USART_Mode_Rx;
uart_init.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_Init(USART1, &uart_init);

USART_Cmd(USART1, ENABLE);
USART_DMACmd(USART1, USART_DMAReq_Rx, ENABLE); // 使能DMA请求

3. 优化DMA配置


#define SBUS_FRAME_LEN 25  // SBUS一帧25字节

__ALIGNED(4) uint8_t sbus_buf[SBUS_FRAME_LEN * 2]; // 双缓冲

DMA_InitTypeDef dma_init;
dma_init.DMA_BufferSize = sizeof(sbus_buf);
dma_init.DMA_PeripheralBaseAddr = (uint32_t)&(USART1->DR);
dma_init.DMA_MemoryBaseAddr = (uint32_t)sbus_buf;
dma_init.DMA_DIR = DMA_DIR_PeripheralSRC;
dma_init.DMA_Mode = DMA_Mode_Circular; // 循环模式
dma_init.DMA_Priority = DMA_Priority_VeryHigh; // 最高优先级
dma_init.DMA_M2M = DMA_M2M_Disable;
dma_init.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
dma_init.DMA_MemoryInc = DMA_MemoryInc_Enable;
dma_init.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
dma_init.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
DMA_Init(DMA1_Channel5, &dma_init); // USART1_RX用Channel5

DMA_Cmd(DMA1_Channel5, ENABLE);

4. 帧验证逻辑


void CheckSBUS() {
    static uint16_t idx = 0;
    for(int i=0; i         // 检测帧头(0x0F)和帧尾(0x00)
        if((sbus_buf[(idx+i) % sizeof(sbus_buf)] == 0x0F) &&
           (sbus_buf[(idx+i+24) % sizeof(sbus_buf)] == 0x00)) {

            // 完整帧处理 (从索引(idx+i)开始的25字节)
            ProcessSBUS(&sbus_buf[(idx+i) % sizeof(sbus_buf)]);
            idx = (idx+i+25) % sizeof(sbus_buf);
            break;
        }
    }
}

5. 抗干扰措施



  • 接收端并联 100nF陶瓷电容 到GND

  • 信号线串联 220Ω电阻

  • 缩短接线长度(<30cm)




验证要点




  1. 示波器检查

    用示波器确认信号在反相后符合:  



    • 空闲时高电平(3.3V)

    • 数据0时低电平(0V)




  2. 数据抓包验证

    使用逻辑分析仪抓取STM32端的信号,确认:  



    • 帧头0x0F位置固定

    • 每25字节出现一次帧尾0x00




  3. DMA计数器监控


    if(DMA_GetFlagStatus(DMA1_FLAG_TC5)) {
       DMA_ClearFlag(DMA1_FLAG_TC5);
       CheckSBUS(); // 每次DMA循环完成时检查数据
    }




经实际测试(参考OpenSBUS实现),使用上述方案后STM32F103可稳定接收SBUS信号,摇杆数据变化响应延迟<5ms。



建议优先检查硬件反相电路和协议配置,这两项问题覆盖90%以上的类似案例。调试时可先降低遥控器发射功率,排除环境干扰影响。

举报

更多回帖

发帖
×
20
完善资料,
赚取积分