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

STM32F407 CAN1初始化校验、波特率验证及代码修正求助

STM32F407 CAN1发送问题排查与修正

一、波特率验证(当前代码错误)

STM32 CAN波特率计算公式为:

波特率 = APB1时钟频率 / ((TS1 + TS2 + 1) × PRESCALER)

假设你的SysClockConfig()配置系统时钟为168MHz,APB1总线时钟为42MHz(默认预分频系数为4)。代入当前代码参数:

  • PRESCALER=6,TS1=8,TS2=7
  • 计算结果:42000000 / ((8+7+1)×6) = 437500 b/s
    显然与目标500000b/s不符,这是接收端无法接收数据的核心原因之一。

二、初始化代码核心问题

  1. GPIO复用配置错误
    CAN1_RX对应PD0、CAN1_TX对应PD1,这两个引脚属于引脚0-7范围,应使用GPIOD->AFR[0](AFR[0]对应引脚0-7,AFR[1]对应引脚8-15)。当前代码将两个引脚的复用配置都写到AFR[1],导致引脚复用映射失败,CAN信号无法正常输出。

  2. 波特率参数不匹配
    如上述计算,当前参数无法得到500000b/s的波特率,与接收端波特率不匹配导致通信失败。

三、寄存器分步配置说明

1. RCC时钟使能

  • 使能CAN1时钟:RCC->APB1ENR |= (1<<25)(CAN1挂载在APB1总线)
  • 使能GPIOD时钟:RCC->AHB1ENR |= (1<<3)(PD0/PD1属于GPIOD)

2. GPIO引脚配置

PD0(CAN1_RX)和PD1(CAN1_TX)需配置为复用功能模式,并设置复用映射为AF9:

  • PD1(TX):
    • MODER设置为复用模式:GPIOD->MODER |= (2<<(1×2))(引脚1的MODER位为2-3位)
    • AFR[0]设置AF9:GPIOD->AFR[0] |= (9<<(1×4))(引脚1的AFR位为4-7位)
  • PD0(RX):
    • MODER设置为复用模式:GPIOD->MODER |= (2<<(0×2))(引脚0的MODER位为0-1位)
    • AFR[0]设置AF9:GPIOD->AFR[0] |= (9<<(0×4))(引脚0的AFR位为0-3位)

3. CAN控制器初始化

  • 进入初始化模式:CAN1->MCR |= CAN_MCR_INRQ,等待硬件响应:while((CAN1->MSR & CAN_MSR_INAK) != CAN_MSR_INAK)
  • 配置发送FIFO优先级:CAN1->MCR |= CAN_MCR_TXFP(按发送请求顺序排序优先级)
  • 退出初始化模式:CAN1->MCR &= ~CAN_MCR_INRQ,等待进入正常模式:while((CAN1->MSR & CAN_MSR_INAK) == CAN_MSR_INAK)

4. 波特率配置(目标500000b/s)

以APB1时钟42MHz为例,选择参数:

  • PRESCALER=6,TS1=11,TS2=2
  • 验证计算:42000000 / ((11+2+1)×6) = 500000 b/s
    寄存器配置:
  • 重置BTR:CAN1->BTR = 0
  • 设置预分频器:CAN1->BTR |= (PRESCALER - 1)(BRP为0基数值)
  • 设置TS1:CAN1->BTR |= ((TS1 - 1) << 16)(TS1字段占16-19位,0基数值)
  • 设置TS2:CAN1->BTR |= ((TS2 - 1) << 20)(TS2字段占20-22位,0基数值)

5. CAN发送流程

  • 等待空闲发送邮箱:while ((CAN1->TSR & CAN_TSR_TME0) == 0)
  • 配置标准ID:CAN1->sTxMailBox[0].TIR = (CAN_ID << 3)(IDE位默认0,表示标准ID)
  • 配置数据长度:CAN1->sTxMailBox[0].TDTR = CAN_DLC
  • 加载数据到邮箱:直接赋值TDLR寄存器
  • 请求发送:CAN1->sTxMailBox[0].TIR |= CAN_TI0R_TXRQ

四、修正后的完整代码

#include "stm32f407xx.h"
#include "RCCconfig.h"

// 波特率参数(APB1=42MHz时,对应500000b/s)
#define PRESCALER                    6
#define TIME_QUANTA_SEGMENT_1        11
#define TIME_QUANTA_SEGMENT_2        2

// CAN配置
#define CAN_ID 0x123  // 标准ID(11位)
#define CAN_DLC 2     // 数据长度

static uint8_t data[CAN_DLC] = {0};

void CAN1_Init(void)
{
    // 1. 使能时钟
    RCC->APB1ENR |= (1 << 25);  // CAN1时钟使能
    RCC->AHB1ENR |= (1 << 3);   // GPIOD时钟使能

    // 2. 配置GPIO引脚复用
    // CAN1_TX PD1
    GPIOD->MODER |= (2 << (1 * 2));       // 设置为复用功能模式
    GPIOD->AFR[0] |= (9 << (1 * 4));      // 复用为AF9

    // CAN1_RX PD0
    GPIOD->MODER |= (2 << (0 * 2));       // 设置为复用功能模式
    GPIOD->AFR[0] |= (9 << (0 * 4));      // 复用为AF9

    // 3. CAN控制器初始化
    CAN1->MCR |= CAN_MCR_INRQ;            // 请求进入初始化模式
    while((CAN1->MSR & CAN_MSR_INAK) != CAN_MSR_INAK);  // 等待进入初始化模式

    CAN1->MCR |= CAN_MCR_TXFP;            // 发送FIFO按请求顺序优先级
    CAN1->MCR &= ~CAN_MCR_INRQ;           // 请求退出初始化模式
    while((CAN1->MSR & CAN_MSR_INAK) == CAN_MSR_INAK);  // 等待进入正常模式

    // 4. 配置波特率为500000b/s
    CAN1->BTR = 0;                        // 重置BTR寄存器
    CAN1->BTR |= (PRESCALER - 1);         // 设置预分频器(BRP=5)
    CAN1->BTR |= ((TIME_QUANTA_SEGMENT_1 - 1) << 16);  // TS1=10(对应实际11个时间量子)
    CAN1->BTR |= ((TIME_QUANTA_SEGMENT_2 - 1) << 20);  // TS2=1(对应实际2个时间量子)
}

void CAN1_Transmit(uint8_t data[CAN_DLC])
{
    // 等待空闲发送邮箱0
    while ((CAN1->TSR & CAN_TSR_TME0) == 0);

    // 配置ID和数据长度
    CAN1->sTxMailBox[0].TIR = (CAN_ID << 3);  // 标准ID,IDE位默认0
    CAN1->sTxMailBox[0].TDTR = CAN_DLC;

    // 直接加载数据到邮箱
    CAN1->sTxMailBox[0].TDLR = (data[1] << 8) | data[0];

    // 请求发送
    CAN1->sTxMailBox[0].TIR |= CAN_TI0R_TXRQ;
}

int main(void)
{
    SysClockConfig();

    CAN1_Init();

    // 初始化发送数据
    data[0] = 0x65;
    data[1] = 0xAA;

    while (1)
    {
        CAN1_Transmit(data);
        // 可选:添加延时避免频繁发送
        // for(uint32_t i=0; i<1000000; i++);
    }
}

内容的提问来源于stack exchange,提问作者Shubham Samal

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 05:44:57