USER GUIDE / CONNECTIVITY & NETWORKING / CAN FD / BASIC OPERATION
基本操作
本节将讨论 CAN 控制器的基本功能。下一章将说明 CAN 控制器的高级功能。为了与 CAN-bus 上的其他节点通信,必须按如下说明正确配置 CAN 控制器。
下图为基本通信流程图。

系统配置
以下系统配置必须在复位模式(RSTM=1)下完成。
进入复位模式
某些寄存器只能在复位模式下写入,例如总线时序寄存器和验收滤波寄存器等,因此我们必须在复位模式下写入这些寄存器。然后,CAN 控制器必须在这些寄存器正确配置后退出复位模式,才能使控制器工作。
波特率设置
CAN-bus 中的波特率由两个寄存器 CANBTR0 和 CANBTR1 决定。下面的示例说明如何计算 1Mbps 的波特率:
假设系统时钟为 120MHz,且 CANBTR0=09h、CANBTR1=45h。则 TQ1_CLK = CANCLK/(CANCS[5-0]+1) = 120MHz/10 = 12MHz。因此每个时间量子(TQ1)为 83.33nsec。则仲裁阶段的一个 CAN 位时间(BT)为 (1 + (TSEG1+1) + (TSEG2+1)) x 83.33 nsec = (1 + 5 + 6) x 83.33 nsec = 1usec。因此,CAN 总线仲裁阶段的波特率为 1Mbps。
CAN FD 数据阶段的波特率由 CANFDTR0 和 CANFDTR1 决定。
下面的示例说明如何计算 5MHz 的 FD 数据波特率:
假设系统时钟为 120MHz,且 CANFDTR0=01h、CANFDTR1=36h。则 TQ2_CLK 为 CANCLK/(CANFDCS[5-0]+1) = CANCLK/2 = 60MHz。因此 FD 数据阶段的每个时间量子为 16.67nsec。则 CAN FD 数据阶段的一个位时间为 (1 + (FDTSEG1+1) + (FDTSEG2+1)) x 16.67 nsec = (1 + 4 + 7) x 16.67 nsec = 200nsec。因此 CAN 总线 FD 数据阶段的波特率为 5Mbps。
验收过滤器设置
借助验收滤波器,CAN 控制器只有在接收帧的标识符位与验收滤波寄存器中预定义的位一致时,才能从 CAN-bus 接收正确的帧。验收滤波器由 Acceptance Code Registers(ACR)和 Mask Code Registers(MCR)定义。要接收的帧位模式定义在 Acceptance Code 寄存器中。相应的掩码码寄存器允许将某些位位置定义为“don’t care”。硬件复位后,所有 Acceptance Code 寄存器和 Mask Code 寄存器均被清零。
共有 4 组验收滤波器。必须预先使能至少一组滤波器。每组滤波器都有 4 个 Acceptance Code 位和 4 个 Mask Code 位。Acceptance code 3 寄存器是 Acceptance Code 中的最高字节;Acceptance code 0 寄存器是 Acceptance Code 中的最低字节。Mask code 3 寄存器是 Mask Code 中的最高字节,Mask Code 0 寄存器是 Mask Code 中的最低字节。
当接收消息为标准格式帧时,Acceptance Code 和 Mask Code 的低 11 位有效。当接收消息为扩展格式帧时,低 29bit 的 Acceptance Code 和 Mask Code 有效。


扩展帧:如果接收到扩展格式帧,则完整标识符(包括 RTR 位)用于验收滤波。要成功接收消息,所有单个位比较都必须指示接受。应注意,ACR3 和 MCR3 的最高 3 位未使用。为了与未来产品兼容,应通过将 MCR3.7、MCR3.6 和 MCR3.5 置为逻辑 1,将这些位设为“don’t care”。ACR3 和 MCR3 的最高 3 位未使用。为了与未来产品兼容,应通过将 MCR3.7、MCR3.6 和 MCR3.5 置为逻辑 1,将这些位设为“don’t care”。

标准帧:如果接收到标准格式帧消息,则完整标识符用于验收滤波。要成功接收一帧,所有单个位比较都必须指示接受。注意,ACR3、MCR3、ACR2、MCR2 以及 ACR1 和 MCR1 的最高 5 位未使用。为了与未来产品兼容,这些 Mask Code 寄存器中的未使用位应通过将这些位置为逻辑 1 编程为“don’t care”。
进入工作模式
完成所有系统配置后,必须将 RSTM 置零以进入 Operation Mode。同时,CAN 控制器进入空闲状态,等待发送和接收帧。
发送一帧
必须写入发送缓冲区以向 CAN-bus 发送一帧,然后将发送请求位置为逻辑 1。控制器将等待总线空闲并将该帧发送到总线。例如,
CAN 将向 CAN-bus 发送一个标准格式帧。帧标识符为 0x123,数据长度为 8,数据为 0x11、0x22、0x33、0x44、0x55、0x66、0x77 和 0x88。按以下步骤操作:
- 向 CANTFIR 写入 0x8;
- 向 CANTXID 写入 0x123;
- 向 CANTXDATA0 写入 0x44332211;
- 向 CANTXDATA1 写入 0x88776655;
- 向 CANCMD 写入 0x1;
如果发送成功完成,将置位 Transmit Interrupt (TI)。如果发生任何错误,则将置位 Bus Error Interrupt (BEI),当前帧将在错误帧之后重新发送。用户可检查 CANERR[7:0] 以获取详细错误状态,并可通过设置 Abort Transmitting (AT) 命令中止未成功的发送。
发送帧 DMA
- 配置 pdma 并启动 PDMA 发送传输。
- a) 在 PSRAM 中分配用于 dma 链表描述符的区域,并为 CAN 选择一个空闲 DMA 通道。
- b) 将待发送的帧写入 PSRAM 中的区域
- c) 写入 DMAC.DMAE 寄存器以启动 DMA 传输
- d) 写入 DMAC.DACIDXn = CANTFIR 地址的低 16bit
- e) 将描述符设置为描述符链表,以下是一些主要配置:
- SAI = 0x1
- DAI = 0x0
- SAIW = 0x0
- DAIW = 0x1
- SP = 0x0
- DP = 0x0
- TSZ = 0x7
- STDE = 1
- DACIDX = 0(若使用 can0)或 1(若使用 can1)
- TIE = 0x1
- LINK = 1
- DSA = ddr 中的缓冲区地址。
- DTA = CANTFIR 地址。
- DRT = CANn 传输请求
- DOA = 描述符物理偏移地址
- DTC = (帧的数量<<16) | 此描述符内的最大帧长度(bytes)
- f) 将描述符物理地址写入 DDAn 寄存器。
- g) 写入 DDSn 以设置门铃,使 DMA 控制器获取其第一个描述符。
- h) 写入 DCSn.DES8=1 以使用 8 字描述符。
- i) 写入 DCSn.CTE=1 以使能通道。
- 将 can 控制器配置为 normal 模式
- 写入 RSTM=1 以启动 can transfer。
- 等待 dma 描述符中断。
- 清除 dma 描述符中断。
- 转到步骤 4
接收一帧
只有 ID 通过 Acceptance Filter 的帧才能被控制器接收。当 CAN controller 成功接收到一帧,且 Receive Interrupt Enable (RIE) 被使能时,Receive Interrupt (RI) 位将被置为逻辑 1。
如果 RX DMA mode (DMAEN) 被禁用,MCU 会通过接收中断获知并读出接收缓冲区中的数据,然后释放接收缓冲区。这里请特别注意,必须先读取数据再释放接收缓冲区,因为释放接收缓冲区后,接收缓冲区中的值会发生变化。
如果 RX DMA mode (DMAEN) 被使能,DMA request (dma_req) 将变为有效并启动 DMA protocol。当通过接收 dma_finish 完成 DMA protocol 后,接收缓冲区会被释放,且 RX DMA Complete Interrupt (DMAI) 将被置为逻辑 1。
接收帧 DMA
- 配置 pdma 并启动 PDMA 接收传输。
- k) 在 PSRAM 中为 dma link-描述符分配区域,并为 CAN 选择一个空闲的 DMA 通道。
- l) 写入 DMAC.DMAE 寄存器以启动 DMA 传输
- m) 写入 DMAC.SACIDX = CANRFIR 地址的低 16bit
- n) 将描述符设置为描述符链表,以下是一些主要配置:
- SAI = 0x0
- DAI = 0x1
- SAIW = 0x1
- DAIW = 0x0
- SP = 0x0
- DP = 0x0
- TSZ = 0x8
- SACIDX = 1
- TIE = 0x1
- LINK = 1
- DSA = CANRFIR 地址。
- DTA = PSRAM 中的缓冲区地址。
- DRT = CANn 接收请求
- DOA = 描述符物理偏移地址
- DTC = 接收数据大小
- o) 将描述符物理地址写入 DDAn 寄存器。
- p) 写入 DDSn 以设置门铃,使 DMA 控制器能够获取其第一个描述符。
- q) 写入 DCSn.DES8=1,使用 8 字描述符。
- r) 写入 DCSn.CTE=1 以使能通道。
- 将 can 控制器配置为正常模式,然后写入 DMAIE = 1 以使能 can dma 接收中断。
- 写入 DMAEN = 1 以使能 RX DMA mode。
- 写入 RSTM=1 以启动 can 传输。
- 等待 can 中断,并在 INTC 中屏蔽 can 中断
- 读取 CANINT 寄存器,如果 DMAI 为 1,则读取 DMA DDA 和 DTC,获取当前传输位置。然后根据该位置读出 can 接收数据,并处理数据。
- 在 INTC 中取消屏蔽 can 中断
- 转到步骤 5。
测试模式
自测试模式
在 CANMODE[2] 中使能 STE 位将使能 self-test mode。CAN control 的 self-test mode 与 normal operation mode 相同,不同之处在于所有 ACK 错误都会被忽略。这使软件能够发起“self receive request”命令。收到该命令后,一条消息将被发送到总线,并在不检查 ACK flag 的情况下视为发送成功。如果 ID field 与 acceptance filter 匹配,发送的消息也会被发送该消息的 CAN controller 接收。
自接收请求
使能 CANCMD[4] 中的 SRR 将导致一条消息被同时发送和接收。执行 Self Receive Request 命令时,一条消息会被发送,并且如果 acceptance filter 设置为相应标识符,则会被同时接收。该命令主要用于控制器自测试。如果 STE=1 使能了 Self Test Mode,则即使不存在其他节点,也能成功完成发送和接收。
当发送和接收操作完成后,将同时产生发送和接收中断。软件应从 RX-FIFO 中读取并校验接收到的数据。然后设置 Release Receive Buffer (RRB) 命令以释放该存储空间。
自环测试模式
然后软件可以检查接收消息的正确性并执行 loop-back test。loop-back 可以通过将 CANTX 和 CANRX 短接来完成,也可以通过实际 CAN bus 上的外部 transceiver 来完成。当从总线进行 loop back 时,CAN bus 需要正确终端匹配,以确保正常总线操作所需的正确电平。

自测试示例
步骤一
在 Reset Mode (RSTM=1) 下,解锁 CANSLKEY,然后使能 CAN Self-Loop Test Mode,并设置 CANTXOFF 以旁路外部 CAN Transceiver。
步骤二
使能 Self Test Mode (STE=1) 以忽略所有 ACK 错误。
步骤三
在 Reset Mode (RSTM=1) 下,像正常操作一样配置所有位速率时序寄存器、操作设置寄存器和 RX acceptance filters。为了使 MCU 能够读取并比较 TX/RX 数据,RX DMA Mode (DMAEN) 应被禁用。
步骤四
进入 normal operation mode (RSTM=0),同时使能 Transmit Interrupt (TIE) 和 Receive Interrupt (RIE)。将测试 ID 和 Data 编程到 Transmit Buffers 中,然后使能 Self Receive Request (SRR) 命令以启动发送和接收。
步骤五
当发出 can_irq 时,软件应从 Receive Buffer 中读出接收数据,并与发送数据进行比较。
位时间配置建议
在一般应用中,建议将两个 SJW[1-0] 都配置为非零值,例如 0x1 或 0x2。下表给出了在 120MHz、80MHz 和 16MHz CANCLK 频率下的位时间配置示例。在实际 CAN 系统中,这些设置应结合 transceiver 的时序进行重新调整。
CANCLK = 120MHz
| 位速率 | 正常位时间配置 | 数据位时间配置 | ||||
|---|---|---|---|---|---|---|
| CANCS[5-0] | TSEG2[2-0] | TSEG1[3-0] | CANFDCS[5-0] | FDTSEG2[2-0] | FDTSEG1[3-0] | |
| 10 Mbps | N/A | N/A | N/A | 0 | 3 | 6 |
| 8 Mbps | N/A | N/A | N/A | 0 | 4 | 8 |
| 6 Mbps | N/A | N/A | N/A | 0 | 5 | 12 |
| 5 Mbps | N/A | N/A | N/A | 1 | 3 | 6 |
| 4 Mbps | N/A | N/A | N/A | 1 | 4 | 8 |
| 3 Mbps | N/A | N/A | N/A | 1 | 5 | 12 |
| 2 Mbps | N/A | N/A | N/A | 2 | 5 | 12 |
| 1 Mbps | 5 | 5 | 12 | 5 | 5 | 12 |
| 500 Kbps | 11 | 5 | 12 | 11 | 5 | 12 |
注意:正常位最大位速率为 1Mbps。
CANCLK = 100MHz
| 位速率 | 正常位时间配置 | 数据位时间配置 | ||||
|---|---|---|---|---|---|---|
| CANCS[5-0] | TSEG2[2-0] | TSEG1[3-0] | CANFDCS[5-0] | FDTSEG2[2-0] | FDTSEG1[3-0] | |
| 10 Mbps | N/A | N/A | N/A | 0 | 2 | 5 |
| 8 Mbps | N/A | N/A | N/A | 0 | 3 | 6 |
| 5 Mbps | N/A | N/A | N/A | 0 | 2 | 6 |
| 4 Mbps | N/A | N/A | N/A | 0 | 2 | 8 |
| 2 Mbps | N/A | N/A | N/A | 1 | 2 | 8 |
| 1 Mbps | 9 | 2 | 7 | 9 | 2 | 7 |
| 500 Kbps | 19 | 2 | 7 | 19 | 2 | 7 |
注意:正常位最大位速率为 1Mbps
CANCLK = 80MHz
| 位速率 | 正常位时间配置 | 数据位时间配置 | ||||
|---|---|---|---|---|---|---|
| CANCS[5-0] | TSEG2[2-0] | TSEG1[3-0] | CANFDCS[5-0] | FDTSEG2[2-0] | FDTSEG1[3-0] | |
| 8 Mbps | N/A | N/A | N/A | 0 | 2 | 5 |
| 5 Mbps | N/A | N/A | N/A | 0 | 4 | 9 |
| 4 Mbps | N/A | N/A | N/A | 0 | 5 | 12 |
| 2 Mbps | N/A | N/A | N/A | 1 | 5 | 12 |
| 1 Mbps | 3 | 5 | 12 | 3 | 5 | 12 |
| 500 Kbps | 7 | 5 | 12 | 7 | 5 | 12 |
注意:正常位最大位速率为 1Mbps。
CANCLK = 16MHz
| 位速率 | 正常位时间配置 | 数据位时间配置 | ||||
|---|---|---|---|---|---|---|
| CANCS[5-0] | TSEG2[2-0] | TSEG1[3-0] | CANFDCS[5-0] | FDTSEG2[2-0] | FDTSEG1[3-0] | |
| 1 Mbps | 0 | 4 | 9 | 0 | 4 | 9 |
| 500 Kbps | 1 | 4 | 9 | 1 | 4 | 9 |
注意:正常位最大位速率为 1Mbps。