<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[can0 fd 模式无法发送数据]]></title><description><![CDATA[<p dir="auto">我在原来 can 模式基础上添加了 fd 发送支持，目前发现无法正常发送数据。具体关键代码如下：</p>
<pre><code class="language-c">
#define YTM_CANFD_MODE_ENABLE

int board_can_init(uint32_t baudrate)
{
    // 使能 CAN0 时钟
    REG32(IPC_FLEXCAN0) |= 0X01;
    // 修改为 ALT5 模式 PTE4 can0 rx/PTE5 can0 tx
    REG32(PCTRLE_4) &amp;= ~(0XF &lt;&lt; 8);
    REG32(PCTRLE_4) |= 0X5 &lt;&lt; 8;
    REG32(PCTRLE_5) &amp;= ~(0XF &lt;&lt; 8);
    REG32(PCTRLE_5) |= 0X5 &lt;&lt; 8;
    REG32(CAN0_MCR) &amp;= ~CAN0_MCR_MDIS_MASK;
    REG32(CAN0_MCR) |= (CAN0_MCR_FRZ_MASK | CAN0_MCR_HALT_MASK);

    while ((REG32(CAN0_MCR) &amp; CAN0_MCR_FRZACK_MASK) == 0X0);

#ifdef YTM_CANFD_MODE_ENABLE
    // 修改 maxmailbox counts
    REG32(CAN0_MCR) &amp;= ~CAN0_MCR_MAXMB_MASK;
    REG32(CAN0_MCR) |= 0X6;

    REG32(CAN0_MCR) |= CAN0_MCR_FDEN_MASK;
    // TODO 修改 CAN0_FDCTRL
#endif

    // 使用晶振 24MHz 时钟源
    REG32(CAN0_CTRL1) &amp;= ~CAN0_CTRL1_CLKSRC_MASK;
    REG32(CAN0_CTRL1) &amp;= 0X0000FFF8;
#ifndef YTM_CANFD_MODE_ENABLE
    //              PRESDIV       RJW     PSEG1     PSEG2   PROPSEG
    REG32(CAN0_CTRL1) |= (1 &lt;&lt; 24 | 3 &lt;&lt; 22 | 7 &lt;&lt; 19 | 7 &lt;&lt; 16 | 6);
#else
    // EPRESDIV ERJW EPROPSEG EPSEG1 EPSEG2
    REG32(CAN0_CBT) |= 1 &lt;&lt; 31 | (2 &lt;&lt; 21 | 1 &lt;&lt; 16 | 4 &lt;&lt; 10 | 7 &lt;&lt; 5 | 1);
    // FRESDIV FRJW FPROPSEG FPSEG1 FPSEG2
    // 按需修改 CAN0_FDCBT
    REG32(CAN0_FDCBT) = (0 &lt;&lt; 20 | 1 &lt;&lt; 16 | 6 &lt;&lt; 10 | 2 &lt;&lt; 5 | 1);

    REG32(CAN0_ERFCR) |= CAN0_ERFCR_ERFEN_MASK ;

    // 复位 FIFO 引擎
    REG32(CAN_ERFSR) |= (1&lt;&lt;27);

    // TODO 配置 ERFCR 寄存器 NFE 和 NEXIF

    // TODO 配置滤波器表 0X3000 偏移处
#endif
    // 清零 RAM 区
    for (int i = 0; i &lt; 0X200; i++)
    {
        REG32(CAN0_MB0_HEAD0 + i * 4) = 0X0;
    }

    REG32(CAN0_RXMGMASK) = 0XFFFFFFFF;
    REG32(CAN0_RX14MASK) = 0XFFFFFFFF;
    REG32(CAN0_RX15MASK) = 0XFFFFFFFF;
    REG32(CAN0_RXFGMASK) = 0XFFFFFFFF;
    // 配置 RAM
    REG32(CAN0_CTRL2) |= CAN0_CTRL2_WRMFRZ_MASK;

#ifdef YTM_CANFD_MODE_ENABLE
    // TODO 修改 CAN0_FDCTRL 为 64 bytes
    REG32(CAN0_FDCTRL) |= (CAN0_FDCTRL_MBDSR0_MASK | \
                           CAN0_FDCTRL_MBDSR1_MASK | \
                           CAN0_FDCTRL_MBDSR2_MASK | \
                           CAN0_FDCTRL_MBDSR3_MASK);
    REG32(CAN0_FDCTRL) |= (CAN0_FDCTRL_TDCEN_MASK);
#else
    REG32(CAN0_FDCTRL) &amp;= ~(CAN0_FDCTRL_MBDSR0_MASK | \
                            CAN0_FDCTRL_MBDSR1_MASK | \
                            CAN0_FDCTRL_MBDSR2_MASK | \
                            CAN0_FDCTRL_MBDSR3_MASK);
    // 设置 8 字节/ message buffer
    REG32(CAN0_FDCTRL) = 0X00;
#endif
    // 关闭 Self Reception
    REG32(CAN0_MCR) |= 1 &lt;&lt; 17;

    /* REG32(CAN0_CTRL1) |=  1 &lt;&lt; 3; */
    REG32(CAN0_MCR) &amp;= ~(CAN0_MCR_HALT_MASK | CAN0_MCR_FRZ_MASK);

    return 0;
}

int board_can_send(const struct bl_can_msg *msg)
{
    int ret = 0;

    if (!msg)
    {
        return -RT_EINVAL;
    }

    //1. 检查相关的中断 bit 是否置位并清零
    //2. 如果 MB 是激活态，写 ABORT（1001）-&gt; CODE /C/S，等待 IFLAG 置位，然后读回 CODE filed 并清除对应的中断寄存器 flag
    //3. 写 ID word
    //4. 写要发送的数据
    //5. 设置 ide, 设置 rtr, 设置 dlc， 激活 MB
    REG32(CAN0_IFLAG1) |= (1 &lt;&lt; 0);
    REG32(CAN0_MB0_HEAD1) = msg-&gt;id &lt;&lt; 18;
    REG32(CAN0_MB0_DATA(0)) = msg-&gt;data[0] &lt;&lt; 24 | msg-&gt;data[1] &lt;&lt; 16 | msg-&gt;data[2]
                              &lt;&lt; 8 | msg-&gt;data[3];
    REG32(CAN0_MB0_DATA(1)) = msg-&gt;data[4] &lt;&lt; 24 | msg-&gt;data[5] &lt;&lt; 16 | msg-&gt;data[6]
                              &lt;&lt; 8 | msg-&gt;data[7];
    REG32(CAN0_MB0_HEAD0) = msg-&gt;dlc &lt;&lt; 16 | msg-&gt;rtr &lt;&lt; 20 | msg-&gt;ide &lt;&lt; 21;
#ifdef YTM_CANFD_MODE_ENABLE
    // canfd 帧
    REG32(CAN0_MB0_HEAD0) |= 0xC0000000;
#endif
    REG32(CAN0_MB0_HEAD0) |= 0xC &lt;&lt; 24;
    return ret;
}
</code></pre>
<p dir="auto">相比原来的 can ，主要增加了修改 <strong>CAN0_FDCBT</strong> 和 <strong>CAN0_CBT（之前用的 CAN0_CTRL1）</strong>，以及寄存器<strong>CAN0_FDCTRL</strong>和<strong>CAN0_MCR</strong>开启canfd。<br />
canfd报文发送时，追加了 <strong>EG32(CAN0_MB0_HEAD0) |= 0xC0000000;</strong>。<br />
请问是不是还有哪些遗漏项目没有修改？</p>
]]></description><link>https://forum.ytmicro.com/topic/2040/can0-fd-模式无法发送数据</link><generator>RSS for Node</generator><lastBuildDate>Sun, 14 Jun 2026 19:40:34 GMT</lastBuildDate><atom:link href="https://forum.ytmicro.com/topic/2040.rss" rel="self" type="application/rss+xml"/><pubDate>Sun, 14 Jun 2026 10:28:28 GMT</pubDate><ttl>60</ttl></channel></rss>