You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Cube IDE下MINI M4 STM32无法设置CAN波特率为500Kbps问题

STM32F4 CAN波特率高于250kbps时无法发报文排查方案

问题基础信息

  • 运行环境:搭载STM32F4RG15 MCU的MINI M4 STM32开发板,Cube IDE开发环境
  • 故障表现:CAN通信最高仅能在250kbps波特率下正常运行,将波特率配置为500kbps、1Mbps时CAN模块停止工作,无法向总线发送任何报文
  • 已尝试操作:使用两款CAN位时序计算器提供的全量推荐参数配置,均未解决问题
  • 250kbps下正常运行的位时序参数:
    • SJW:1 Tq
    • 分频系数(Prescaler):4
    • TS1:13 Tq
    • TS2:2 Tq
  • 测试使用的核心代码:
HAL_Init();
SystemClock_Config();

MX_GPIO_Init();
MX_CAN1_Init();
MX_ADC2_Init();
CAN_TxHeaderTypeDef header1;
CAN_RxHeaderTypeDef rxheader;
uint8_t rxdata[8];

int a;

HAL_CAN_Start(&hcan1);
uint32_t mailbox1;

while (1) {
    uint8_t txdata[8];


    uint32_t mailbox1;
    header1.StdId = 32;
    header1.ExtId = 2;
    header1.DLC = 8;
    header1.IDE = CAN_ID_STD;
    header1.RTR = CAN_RTR_DATA;
    header1.TransmitGlobalTime = ENABLE;
    uint16_t time= HAL_CAN_GetTxTimestamp(&hcan1,mailbox1);
    txdata[7]=time;

    HAL_CAN_AddTxMessage(&hcan1, &header1, txdata, &mailbox1);

}

故障成因与解决方法

1. 时钟基准配置错误(最高概率原因)

从250kbps正常运行的参数反推,当前CAN外设的实际输入时钟为16MHz(计算逻辑:波特率=CAN时钟/(分频*(1+TS1+TS2)),代入250kbps参数可得CAN时钟=2500004(1+13+2)=16MHz)。
如果配置高波特率时,直接套用计算器默认的42MHz APB1时钟基准计算参数,实际输出的波特率会和目标值偏差2倍以上,完全超出CAN总线允许的时序容差范围,直接导致通信失败。

排查与修复:

  • 打开SystemClock_Config()函数,确认HSE外部晶振参数和开发板实际硬件匹配、APB1总线分频配置正确,拿到CAN外设的实际输入时钟值,所有位时序参数必须以这个实际时钟为基准计算,不能直接套用计算器默认参数。
  • 以16MHz CAN时钟为例,正确参数参考:
    • 500kbps:分频=2,TS1=13Tq,TS2=2Tq,SJW=1Tq
    • 1Mbps:分频=1,TS1=13Tq,TS2=2Tq,SJW=1Tq

2. 物理层硬件问题

  • 收发器性能不足:MINI板载的低价CAN收发器在供电不足、走线过长时,高波特率下信号边沿畸变严重,无法输出符合要求的差分电平。用示波器测量CANH、CANL的差分信号,确认1Mbps下位时间为1us、500kbps下位时间为2us,差分幅值达到1.5V以上,信号边沿无明显过缓、振铃问题。
  • 终端电阻不匹配:CAN总线必须在首尾两端各接1个120Ω终端电阻,总线总等效电阻为60Ω左右,多接、漏接都会导致高波特率下信号反射严重,通信失败。
  • GPIO配置错误:CAN_TX、CAN_RX引脚的复用功能选择错误,或者引脚速度配置为2MHz低速模式,高波特率下引脚翻转速率跟不上。需要将两个引脚配置为复用推挽输出,速度等级设置为50MHz以上,选择正确的CAN复用功能编号。

3. 代码逻辑bug

当前测试代码存在3个会直接导致高波特率下CAN锁死的问题:

  • 重复定义mailbox1变量,且调用HAL_CAN_GetTxTimestamp()时传入的mailbox1是未初始化的野值,高波特率下发送队列填充速度快,野值访问会直接触发CAN错误标志,导致外设进入Bus-Off锁死状态。
  • 未配置CAN接收过滤器,部分HAL库版本下,不配置过滤器会导致CAN收发逻辑异常。
  • 开启了TransmitGlobalTime全局时间戳发送选项,但没有在CAN初始化时开启时间触发通信模式,会导致报文发送异常;同时主循环无间隔连续发送报文,高波特率下会瞬间占满3个发送邮箱,触发发送错误。

修复后的核心代码参考:

// CAN初始化后先配置接收过滤器
CAN_FilterTypeDef sFilterConfig = {0};
sFilterConfig.FilterBank = 0;
sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;
sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;
sFilterConfig.FilterIdHigh = 0x0000;
sFilterConfig.FilterIdLow = 0x0000;
sFilterConfig.FilterMaskIdHigh = 0x0000;
sFilterConfig.FilterMaskIdLow = 0x0000;
sFilterConfig.FilterFIFOAssignment = CAN_RX_FIFO0;
sFilterConfig.FilterActivation = ENABLE;
sFilterConfig.SlaveStartFilterBank = 14;
HAL_CAN_ConfigFilter(&hcan1, &sFilterConfig);

// 开启自动重传,调试阶段避免单次错误锁死总线
hcan1.Init.AutoRetransmission = ENABLE;
HAL_CAN_Start(&hcan1);

uint32_t mailbox1;
CAN_TxHeaderTypeDef header1 = {0};
while (1) {
    uint8_t txdata[8] = {0};
    header1.StdId = 32;
    header1.DLC = 8;
    header1.IDE = CAN_ID_STD;
    header1.RTR = CAN_RTR_DATA;
    header1.TransmitGlobalTime = DISABLE; // 未使用时间戳功能时关闭该选项
    
    HAL_StatusTypeDef tx_ret = HAL_CAN_AddTxMessage(&hcan1, &header1, txdata, &mailbox1);
    if(tx_ret == HAL_OK)
    {
        // 只有发送成功后才读取对应邮箱的时间戳
        uint16_t time = HAL_CAN_GetTxTimestamp(&hcan1, mailbox1);
        txdata[7] = time;
    }
    HAL_Delay(10); // 加适当延时,避免无间隔发报文占满邮箱
}

4. 外设模式配置错误

确认CAN初始化时配置为正常工作模式,不要误设为静默模式、环回模式;高波特率下建议将SJW设置为2Tq,提升总线时序同步的容差能力,降低通信失败概率。


内容的提问来源于stack exchange,提问作者Krishnapal Jadeja

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 10:27:23