STM32H7入门指南:第91节——深入理解STM32H7的FDCAN总线及其HAL库接口
完整教程下载地址:http://www.armbbs.cn/forum.php?mod=viewthread&tid=86980
第91章 STM32H7的FDCAN总线基础知识和HAL库API
本章节为大家讲解FDCAN的基础知识和对应的HAL库API。CAN FD中的FD含义就是flexible data,灵活数据通信,且波特率可以和仲裁阶段波特率不同
91.1 初学者重要提示
91.2 FDCAN基础知识
91.3 FDCAN的HAL库用法
91.4 FDCAN源文件stm32h7xx_hal_fdcan.c
91.5 总结
91.1 初学者重要提示
- FDCAN基础知识点可以看第90章,已经进行了详细说明
- 特别推荐瑞萨的CAN入门中英文手册,做的非常好:http://www.armbbs.cn/forum.php?mod=viewthread&tid=14546
91.2 FDCAN基础知识
FDCAN的基础知识在本教程的第90章进行了非常详细的说明。我们这里将本章用到的几个知识点再做个说明,详情推荐看第90章。
91.2.1 CAN FD协议介绍
STM32H7的CAN FD符合ISO 11898-12015标准。STM32器件上的FDCAN的功能如下所示:
(1)符合CAN协议2.0版A,B和ISO 11898-1:2015,-4。
(2)可访问的10 KB RAM内存,最多可分配2560个字。
(3)改进了接收过滤。
(4)两个可配置的接收FIFO。
(5)多达64个专用接收缓冲区。
(6)接收高优先级消息时的单独信令。
(7)多达32个专用发送缓冲区。
(8)可配置的发送FIFO和发送队列。
(9)可配置的发送事件FIFO。
(10)时钟校准单元。
(11)收发器延迟补偿。
下图说明了FDCAN框图。
通过这个框图要了解到以下信息:
(1)CANFD1和CANFD2共用一个RAM空间。
(2)每个CANFD都有自己的内核。
(3)CAN内核实现协议控制和收发移位寄存器。
(4)Tx handler控制消息从CAN消息RAM到CAN内核。
(5)Rx handler控制CAN内核到CAN消息RAM。
91.2.2 CAN FD特性
(1)兼容经典CAN,可以遵循ISO 11898-1做数据收发。
(2)提升错误检测,支持高达CRC 21位的校验和。
(3)消息优先级。
(4)保证延迟时间。
(5)配置灵活性。
(6)具有时间同步的组播接收。
(7)系统范围内的数据一致性,每条消息最多64个字节。
(8)多主机。
(9)错误检测和信号。
(10)区分节点的临时错误和永久性故障以及自动关闭缺陷节点。
91.2.3 CAN FD格式
第一个仲裁阶段(The first arbitration phase)是一条消息,其中包含:
(1)帧开始(SOF)。
(2)ID号和其他位,指示消息的目的(提供或请求数据),以及速度和格式配置(CAN或CAN-FD)。
数据传输阶段(The data transmission phase)包括:
(1)数据长度代码(DLC),指示消息包含多少数据字节。
(2)用户希望发送的数据。
(3)检查循环冗余序列(CRC)。
(4)显性位。
第二个仲裁阶段(The second arbitration phase)包含:
(1)总线上其他节点发送的确认(ACK)的接收器(如果至少有一个接收器成功收到消息)
(2)帧尾(EOF),在IFS期间不传输任何消息:目标是将当前帧与下一帧分开。
注意:对于29bit标识符帧,当添加18bit标识到第1个仲裁阶段的IDE bit之后与标准CAN FD是类似的。
91.2.4 CAN FD相比CAN2.0的提升
CAN-FD的开发可以满足需要更高带宽的通信网络需求。每帧最多具有64个字节的CAN-FD以及将比特率提高到最大的可能性,使数据阶段要快8倍,在第二个仲裁阶段要恢复到正常的比特率。通过以下方式确保数据传输的完整性:
(1)17级多项式对最大16字节的有效载荷进行CRC。
(2)21级多项式对16到64字节之间的有效载荷进行校验。
标准帧和CAN FD的区别:
标识符后,CAN 2.0和CAN-FD具有不同的作用:
(1)CAN 2.0发送RTR位以精确确定帧类型:数据帧(RTR为主要)或远程帧(RTR)是隐性的)。
(2)由于CAN-FD仅支持数据帧,因此始终发送占优势的RRS(保留)。
IDE位保持在相同位置,并以相同的动作来区分基本格式(11位标识符)。请注意,在扩展格式的情况下,IDE位以显性或隐性方式传输(29位标识符)。
与CAN 2.0相比,在CAN-FD帧中,在控制字段中添加了三个新位:
(1)扩展数据长度(EDL)位:隐性表示帧为CAN-FD,否则该位为显性(称为R0)在CAN 2.0帧中。
(2)比特率切换(BRS):指示是否启用两个比特率(例如,当数据阶段位以不同的比特率传输到仲裁阶段)。
(3)错误状态指示器(ESI):指示节点处于错误活动模式还是错误被动模式。
控制字段的最后一部分是数据长度代码(DLC),它具有相同的位置和相同的长度(4位),用于CAN 2.0和CAN-FD。 DLC功能在CAN-FD和CAN 2.0中相同,但CAN-FD有很小变化(下表中的详细信息)。 CAN-FD扩展帧允许单个消息中发送64个数据字节,而CAN 2.0有效负载数据最多可以发送8个字节。
通过增加有效载荷数据的数据字段来改善网络带宽,因为需要更少的包处理。 同时,通过为CRC添加更多位来增强消息完整性:
(1)如果有效载荷数据最多为16个字节,则CRC以17位编码。
(2)如果有效载荷数据大于20(16)个字节,则CRC以21位编码。
另外,为了确保CAN-FD帧的鲁棒性,填充位机制支持CRC字段。下表总结了CAN-FD和CAN 2.0之间的主要区别。 提供的主要功能与CAN 2.0相比,CAN FD的改进之处在于数据有效负载的增加和速度的提高由CAN-FD中可用的BRS,EDL和ESI位来确保。
91.3 FDCAN总线的HAL库用法
91.3.1 FDCAN总线结构体FDCAN_GlobalTypeDef
FD CAN总线相关的寄存器是通过HAL库中的结构体FDCAN_GlobalTypeDef定义,在stm32h743xx.h中可以找到这个类型定义:
typedef struct { __IO uint32_t CREL; __IO uint32_t ENDN; __IO uint32_t RESERVED1; __IO uint32_t DBTP; __IO uint32_t TEST; __IO uint32_t RWD; __IO uint32_t CCCR; __IO uint32_t NBTP; __IO uint32_t TSCC; __IO uint32_t TSCV; __IO uint32_t TOCC; __IO uint32_t TOCV; __IO uint32_t RESERVED2[4]; __IO uint32_t ECR; __IO uint32_t PSR; __IO uint32_t TDCR; __IO uint32_t RESERVED3; __IO uint32_t IR; __IO uint32_t IE; __IO uint32_t ILS; __IO uint32_t ILE; __IO uint32_t RESERVED4[8]; __IO uint32_t GFC; __IO uint32_t SIDFC; __IO uint32_t XIDFC; __IO uint32_t RESERVED5; __IO uint32_t XIDAM; __IO uint32_t HPMS; __IO uint32_t NDAT1; __IO uint32_t NDAT2; __IO uint32_t RXF0C; __IO uint32_t RXF0S; __IO uint32_t RXF0A; __IO uint32_t RXBC; __IO uint32_t RXF1C; __IO uint32_t RXF1S; __IO uint32_t RXF1A; __IO uint32_t RXESC; __IO uint32_t TXBC; __IO uint32_t TXFQS; __IO uint32_t TXESC; __IO uint32_t TXBRP; __IO uint32_t TXBAR; __IO uint32_t TXBCR; __IO uint32_t TXBTO; __IO uint32_t TXBCF; __IO uint32_t TXBTIE; __IO uint32_t TXBCIE; __IO uint32_t RESERVED6[2]; __IO uint32_t TXEFC; __IO uint32_t TXEFS; __IO uint32_t TXEFA; __IO uint32_t RESERVED7; } FDCAN_GlobalTypeDef;
这个结构体的成员名称和排列次序和CPU的寄存器是一 一对应的。
__IO表示volatile, 这是标准C语言中的一个修饰字,表示这个变量是非易失性的,编译器不要将其优化掉。core_m7.h 文件定义了这个宏:
#define __O volatile /*!< Defines 'write only' permissions */ #define __IO volatile /*!< Defines 'read / write' permissions */
下面我们看下FDCAN的定义,在stm32h743xx.h文件。
#define PERIPH_BASE (0x40000000UL) #define D2_APB1PERIPH_BASE PERIPH_BASE #define FDCAN1_BASE (D2_APB1PERIPH_BASE + 0xA000UL) #define FDCAN2_BASE (D2_APB1PERIPH_BASE + 0xA400UL) #define FDCAN_CCU_BASE (D2_APB1PERIPH_BASE + 0xA800UL) #define FDCAN1 ((FDCAN_GlobalTypeDef *) FDCAN1_BASE) <----- 展开这个宏,(FDCAN_GlobalTypeDef *)0x4000A000 #define FDCAN2 ((FDCAN_GlobalTypeDef *) FDCAN2_BASE) #define FDCAN_CCU ((FDCAN_ClockCalibrationUnit_TypeDef *) FDCAN_CCU_BASE)
我们访问FDCAN1的CCCR寄存器可以采用这种形式:FDCAN1->CCCR = 0。
91.3.2 FDCAN总线时间触发结构体TTCAN_TypeDef
FDCAN总线时间触发相关的寄存器是通过HAL库中的结构体TTCAN_TypeDef定义,在stm32h743xx.h中可以找到这个类型定义:
typedef struct { __IO uint32_t TTTMC; /*!< TT Trigger Memory Configuration register, Address offset: 0x100 */ __IO uint32_t TTRMC; /*!< TT Reference Message Configuration register, Address offset: 0x104 */ __IO uint32_t TTOCF; /*!< TT Operation Configuration register, Address offset: 0x108 */ __IO uint32_t TTMLM; /*!< TT Matrix Limits register, Address offset: 0x10C */ __IO uint32_t TURCF; /*!< TUR Configuration register, Address offset: 0x110 */ __IO uint32_t TTOCN; /*!< TT Operation Control register, Address offset: 0x114 */ __IO uint32_t TTGTP; /*!< TT Global Time Preset register, Address offset: 0x118 */ __IO uint32_t TTTMK; /*!< TT Time Mark register, Address offset: 0x11C */ __IO uint32_t TTIR; /*!< TT Interrupt register, Address offset: 0x120 */ __IO uint32_t TTIE; /*!< TT Interrupt Enable register, Address offset: 0x124 */ __IO uint32_t TTILS; /*!< TT Interrupt Line Select register, Address offset: 0x128 */ __IO uint32_t TTOST; /*!< TT Operation Status register, Address offset: 0x12C */ __IO uint32_t TURNA; /*!< TT TUR Numerator Actual register, Address offset: 0x130 */ __IO uint32_t TTLGT; /*!< TT Local and Global Time register, Address offset: 0x134 */ __IO uint32_t TTCTC; /*!< TT Cycle Time and Count register, Address offset: 0x138 */ __IO uint32_t TTCPT; /*!< TT Capture Time register, Address offset: 0x13C */ __IO uint32_t TTCSM; /*!< TT Cycle Sync Mark register, Address offset: 0x140 */ __IO uint32_t RESERVED1[111]; /*!< Reserved, 0x144 - 0x2FC */ __IO uint32_t TTTS; /*!< TT Trigger Select register, Address offset: 0x300 */ } TTCAN_TypeDef;
91.3.3 FDCAN总线初始化结构体FDCAN_InitTypeDef
下面是FDCAN总线的初始化结构体:
typedef struct { uint32_t FrameFormat; /*!< Specifies the FDCAN frame format. This parameter can be a value of @ref FDCAN_frame_format */ uint32_t Mode; /*!< Specifies the FDCAN mode. This parameter can be a value of @ref FDCAN_operating_mode */ FunctionalState AutoRetransmission; /*!< Enable or disable the automatic retransmission mode. This parameter can be set to ENABLE or DISABLE */ FunctionalState TransmitPause; /*!< Enable or disable the Transmit Pause feature. This parameter can be set to ENABLE or DISABLE */ FunctionalState ProtocolException; /*!< Enable or disable the Protocol Exception Handling. This parameter can be set to ENABLE or DISABLE */ uint32_t NominalPrescaler; /*!< Specifies the value by which the oscillator frequency is divided for generating the nominal bit time quanta. This parameter must be a number between 1 and 512 */ uint32_t NominalSyncJumpWidth; /*!< Specifies the maximum number of time quanta the FDCAN hardware is allowed to lengthen or shorten a bit to perform resynchronization. This parameter must be a number between 1 and 128 */ uint32_t NominalTimeSeg1; /*!< Specifies the number of time quanta in Bit Segment 1. This parameter must be a number between 2 and 256 */ uint32_t NominalTimeSeg2; /*!< Specifies the number of time quanta in Bit Segment 2. This parameter must be a number between 2 and 128 */ uint32_t DataPrescaler; /*!< Specifies the value by which the oscillator frequency is divided for generating the data bit time quanta. This parameter must be a number between 1 and 32 */ uint32_t DataSyncJumpWidth; /*!< Specifies the maximum number of time quanta the FDCAN hardware is allowed to lengthen or shorten a data bit to perform resynchronization. This parameter must be a number between 1 and 16 */ uint32_t DataTimeSeg1; /*!< Specifies the number of time quanta in Data Bit Segment 1. This parameter must be a number between 1 and 32 */ uint32_t DataTimeSeg2; /*!< Specifies the number of time quanta in Data Bit Segment 2. This parameter must be a number between 1 and 16 */ uint32_t MessageRAMOffset; /*!< Specifies the message RAM start address. This parameter must be a number between 0 and 2560 */ uint32_t StdFiltersNbr; /*!< Specifies the number of standard Message ID filters. This parameter must be a number between 0 and 128 */ uint32_t ExtFiltersNbr; /*!< Specifies the number of extended Message ID filters. This parameter must be a number between 0 and 64 */ uint32_t RxFifo0ElmtsNbr; /*!< Specifies the number of Rx FIFO0 Elements. This parameter must be a number between 0 and 64 */ uint32_t RxFifo0ElmtSize; /*!< Specifies the Data Field Size in an Rx FIFO 0 element. This parameter can be a value of @ref FDCAN_data_field_size */ uint32_t RxFifo1ElmtsNbr; /*!< Specifies the number of Rx FIFO 1 Elements. This parameter must be a number between 0 and 64 */ uint32_t RxFifo1ElmtSize; /*!< Specifies the Data Field Size in an Rx FIFO 1 element. This parameter can be a value of @ref FDCAN_data_field_size */ uint32_t RxBuffersNbr; /*!< Specifies the number of Dedicated Rx Buffer elements. This parameter must be a number between 0 and 64 */ uint32_t RxBufferSize; /*!< Specifies the Data Field Size in an Rx Buffer element. This parameter can be a value of @ref FDCAN_data_field_size */ uint32_t TxEventsNbr; /*!< Specifies the number of Tx Event FIFO elements. This parameter must be a number between 0 and 32 */ uint32_t TxBuffersNbr; /*!< Specifies the number of Dedicated Tx Buffers. This parameter must be a number between 0 and 32 */ uint32_t TxFifoQueueElmtsNbr; /*!< Specifies the number of Tx Buffers used for Tx FIFO/Queue. This parameter must be a number between 0 and 32 */ uint32_t TxFifoQueueMode; /*!< Tx FIFO/Queue Mode selection. This parameter can be a value of @ref FDCAN_txFifoQueue_Mode */ uint32_t TxElmtSize; /*!< Specifies the Data Field Size in a Tx Element. This parameter can be a value of @ref FDCAN_data_field_size */ } FDCAN_InitTypeDef;
下面将结构体成员逐一做个说明:
- FrameFormat
用于设置CAN帧格式。
#define FDCAN_FRAME_CLASSIC ((uint32_t)0x00000000U) /* 经典CAN模式 */ #define FDCAN_FRAME_FD_NO_BRS ((uint32_t)FDCAN_CCCR_FDOE) /* FD CAN不带可变波特率 */ #define FDCAN_FRAME_FD_BRS ((uint32_t)(FDCAN_CCCR_FDOE | FDCAN_CCCR_BRSE)) /* FD CAN带可变波特率 */
- Mode
用于设置CAN操作模式。
#define FDCAN_MODE_NORMAL ((uint32_t)0x00000000U) /*!< 正常模式 */ #define FDCAN_MODE_RESTRICTED_OPERATION ((uint32_t)0x00000001U) /*!< 有限制的操作模式 */ #define FDCAN_MODE_BUS_MONITORING ((uint32_t)0x00000002U) /*!< 总线监测模式 */ #define FDCAN_MODE_INTERNAL_LOOPBACK ((uint32_t)0x00000003U) /*!< 内部环回模式 */ #define FDCAN_MODE_EXTERNAL_LOOPBACK ((uint32_t)0x00000004U) /*!< 外部环回模式 */
- AutoRetransmission
使能自动重传模式。
使能ENABLE或者禁止DISABLE。
- TransmitPause
使能或者禁止传输暂停特性。ENABLE使能或者DISABLE禁止。
- ProtocolException
使能或者禁止协议异常管理。ENABLE表示使能,DISABLE表示禁止。
- NominalPrescaler
用于CAN FD仲裁阶段分频设置,产生标称位时间量,参数范围1-512。
- NominalSyncJumpWidth
设置FD CAN仲裁阶段最大支持的时间量来加长或者缩短一个bit来实现再同步,参数范围1-128。
- NominalTimeSeg1
设置仲裁阶段Bit Segment 1的时间量,范围2 – 256。
- NominalTimeSeg2
设置仲裁阶段Bit Segment 2的时间量,范围2 – 128。
- DataPrescaler
用于CAN FD数据阶段分频设置,范围1-32。
- DataSyncJumpWidth
设置FD CAN数据阶段最大支持的时间量来加长或者缩短一个bit来实现数据再同步,参数范围1-16。
- DataTimeSeg1
设置数据阶段Data Bit Segment 1的时间量,范围1 – 32。
- DataTimeSeg2
设置数据阶段Data Bit Segment 2的时间量,范围1 – 16。
- MessageRAMOffset
设置消息RAM起始地址,范围0到2560。
- StdFiltersNbr
标准ID过滤个数,范围0到128。
- ExtFiltersNbr
扩展ID过滤个数,范围0到64。
- RxFifo0ElmtsNbr
RX FIFO0元素个数,范围0到64。
- RxFifo0ElmtSize
RX FIFO0每个元素中数据大小,支持参数如下:
#define FDCAN_DATA_BYTES_8 ((uint32_t)0x00000004U) /*!< 8 bytes data field */ #define FDCAN_DATA_BYTES_12 ((uint32_t)0x00000005U) /*!< 12 bytes data field */ #define FDCAN_DATA_BYTES_16 ((uint32_t)0x00000006U) /*!< 16 bytes data field */ #define FDCAN_DATA_BYTES_20 ((uint32_t)0x00000007U) /*!< 20 bytes data field */ #define FDCAN_DATA_BYTES_24 ((uint32_t)0x00000008U) /*!< 24 bytes data field */ #define FDCAN_DATA_BYTES_32 ((uint32_t)0x0000000AU) /*!< 32 bytes data field */ #define FDCAN_DATA_BYTES_48 ((uint32_t)0x0000000EU) /*!< 48 bytes data field */ #define FDCAN_DATA_BYTES_64 ((uint32_t)0x00000012U) /*!< 64 bytes data field */
- RxFifo1ElmtsNbr
RX FIFO1个数,范围0到64。
- RxFifo1ElmtSize
RX FIFO1每个元素中数据大小,支持参数如下:
#define FDCAN_DATA_BYTES_8 ((uint32_t)0x00000004U) /*!< 8 bytes data field */ #define FDCAN_DATA_BYTES_12 ((uint32_t)0x00000005U) /*!< 12 bytes data field */ #define FDCAN_DATA_BYTES_16 ((uint32_t)0x00000006U) /*!< 16 bytes data field */ #define FDCAN_DATA_BYTES_20 ((uint32_t)0x00000007U) /*!< 20 bytes data field */ #define FDCAN_DATA_BYTES_24 ((uint32_t)0x00000008U) /*!< 24 bytes data field */ #define FDCAN_DATA_BYTES_32 ((uint32_t)0x0000000AU) /*!< 32 bytes data field */ #define FDCAN_DATA_BYTES_48 ((uint32_t)0x0000000EU) /*!< 48 bytes data field */ #define FDCAN_DATA_BYTES_64 ((uint32_t)0x00000012U) /*!< 64 bytes data field */
- RxBuffersNbr
设置Rx Buffer元素个数,范围0 - 64:
- RxBuffersSize
设置Rx Buffer元素中每个数据大小,范围0 - 64:
#define FDCAN_DATA_BYTES_8 ((uint32_t)0x00000004U) /*!< 8 bytes data field */ #define FDCAN_DATA_BYTES_12 ((uint32_t)0x00000005U) /*!< 12 bytes data field */ #define FDCAN_DATA_BYTES_16 ((uint32_t)0x00000006U) /*!< 16 bytes data field */ #define FDCAN_DATA_BYTES_20 ((uint32_t)0x00000007U) /*!< 20 bytes data field */ #define FDCAN_DATA_BYTES_24 ((uint32_t)0x00000008U) /*!< 24 bytes data field */ #define FDCAN_DATA_BYTES_32 ((uint32_t)0x0000000AU) /*!< 32 bytes data field */ #define FDCAN_DATA_BYTES_48 ((uint32_t)0x0000000EU) /*!< 48 bytes data field */ #define FDCAN_DATA_BYTES_64 ((uint32_t)0x00000012U) /*!< 64 bytes data field */
- TxEventsNbr
Tx Event FIFO元素个数,范围0到32。
- TxBuffersNbr
设置专用的Tx Buffer元素个数,范围0到32。
- TxFifoQueueElmtsNbr
设置用于Tx FIFO/Queue的Tx Buffers个数。范围0到32。
- TxFifoQueueMode
设置FIFO模式或者QUEUE队列模式。
#define FDCAN_TX_FIFO_OPERATION ((uint32_t)0x00000000U) /*!< FIFO mode */ #define FDCAN_TX_QUEUE_OPERATION ((uint32_t)FDCAN_TXBC_TFQM) /*!< Queue mode */
- TxElmtSize
设置Tx Element中的数据域大小。支持参数如下:
#define FDCAN_DATA_BYTES_8 ((uint32_t)0x00000004U) /*!< 8 bytes data field */ #define FDCAN_DATA_BYTES_12 ((uint32_t)0x00000005U) /*!< 12 bytes data field */ #define FDCAN_DATA_BYTES_16 ((uint32_t)0x00000006U) /*!< 16 bytes data field */ #define FDCAN_DATA_BYTES_20 ((uint32_t)0x00000007U) /*!< 20 bytes data field */ #define FDCAN_DATA_BYTES_24 ((uint32_t)0x00000008U) /*!< 24 bytes data field */ #define FDCAN_DATA_BYTES_32 ((uint32_t)0x0000000AU) /*!< 32 bytes data field */ #define FDCAN_DATA_BYTES_48 ((uint32_t)0x0000000EU) /*!< 48 bytes data field */ #define FDCAN_DATA_BYTES_64 ((uint32_t)0x00000012U) /*!< 64 bytes data field */
91.3.4 FDCAN总线消息RAM地址FDCAN_MsgRamAddressTypeDef
下面是消息RAM结构体:
typedef struct { uint32_t StandardFilterSA; /*!< Specifies the Standard Filter List Start Address. This parameter must be a 32-bit word address */ uint32_t ExtendedFilterSA; /*!< Specifies the Extended Filter List Start Address. This parameter must be a 32-bit word address */ uint32_t RxFIFO0SA; /*!< Specifies the Rx FIFO 0 Start Address. This parameter must be a 32-bit word address */ uint32_t RxFIFO1SA; /*!< Specifies the Rx FIFO 1 Start Address. This parameter must be a 32-bit word address */ uint32_t RxBufferSA; /*!< Specifies the Rx Buffer Start Address. This parameter must be a 32-bit word address */ uint32_t TxEventFIFOSA; /*!< Specifies the Tx Event FIFO Start Address. This parameter must be a 32-bit word address */ uint32_t TxBufferSA; /*!< Specifies the Tx Buffers Start Address. This parameter must be a 32-bit word address */ uint32_t TxFIFOQSA; /*!< Specifies the Tx FIFO/Queue Start Address. This parameter must be a 32-bit word address */ uint32_t TTMemorySA; /*!< Specifies the Trigger Memory Start Address. This parameter must be a 32-bit word address */ uint32_t EndAddress; /*!< Specifies the End Address of the allocated RAM. This parameter must be a 32-bit word address */ } FDCAN_MsgRamAddressTypeDef;
下面将结构体成员逐一做个说明:
- StandardFilterSA
设置标准过滤器起始地址,必须是32bit地址。
- ExtendedFilterSA
设置扩展过滤器起始地址,必须是32bit地址。
- RxFIFO0SA
设置RX FIFO 0起始地址,必须是32bit地址。
- RxFIFO1SA
设置RX FIFO 1起始地址,必须是32bit地址。
- RxBufferSA
设置RX Buffer起始地址,必须是32bit地址。
- TxEventFIFOSA
设置Tx Event FIFO起始地址,必须是32bit地址。
- TTMemorySA
设置触发内存起始地址,必须是32bit地址。
- EndAddress
设置申请RAM空间的结束地址,必须是32bit地址。
91.3.5 FDCAN总线过滤结构体FDCAN_FilterTypeDef
下面是过滤结构体:
typedef struct { uint32_t IdType; /*!< Specifies the identifier type. This parameter can be a value of @ref FDCAN_id_type */ uint32_t FilterIndex; /*!< Specifies the filter which will be initialized. This parameter must be a number between: - 0 and 127, if IdType is FDCAN_STANDARD_ID - 0 and 63, if IdType is FDCAN_EXTENDED_ID */ uint32_t FilterType; /*!< Specifies the filter type. This parameter can be a value of @ref FDCAN_filter_type. The value FDCAN_EXT_FILTER_RANGE_NO_EIDM is permitted only when IdType is FDCAN_EXTENDED_ID. This parameter is ignored if FilterConfig is set to FDCAN_FILTER_TO_RXBUFFER */ uint32_t FilterConfig; /*!< Specifies the filter configuration. This parameter can be a value of @ref FDCAN_filter_config */ uint32_t FilterID1; /*!< Specifies the filter identification 1. This parameter must be a number between: - 0 and 0x7FF, if IdType is FDCAN_STANDARD_ID - 0 and 0x1FFFFFFF, if IdType is FDCAN_EXTENDED_ID */ uint32_t FilterID2; /*!< Specifies the filter identification 2. This parameter is ignored if FilterConfig is set to FDCAN_FILTER_TO_RXBUFFER. This parameter must be a number between: - 0 and 0x7FF, if IdType is FDCAN_STANDARD_ID - 0 and 0x1FFFFFFF, if IdType is FDCAN_EXTENDED_ID */ uint32_t RxBufferIndex; /*!< Contains the index of the Rx buffer in which the matching message will be stored. This parameter must be a number between 0 and 63. This parameter is ignored if FilterConfig is different from FDCAN_FILTER_TO_RXBUFFER */ uint32_t IsCalibrationMsg; /*!< Specifies whether the filter is configured for calibration messages. This parameter is ignored if FilterConfig is different from FDCAN_FILTER_TO_RXBUFFER. This parameter can be: - 0 : ordinary message - 1 : calibration message */ } FDCAN_FilterTypeDef;
- IdType
用于设置标准ID和扩展ID。
#define FDCAN_STANDARD_ID ((uint32_t)0x00000000U) /*!< 标准ID */ #define FDCAN_EXTENDED_ID ((uint32_t)0x40000000U) /*!< 扩展ID */
- FilterIndex
用于过滤索引,如果是标准ID,范围0到127。如果是扩展ID,范围0到64。
- FilterType
用于设置过滤类型。如果成员FilterConfig设置为FDCAN_FILTER_TO_RXBUFFER,本参数将不起作用。
#define FDCAN_FILTER_RANGE ((uint32_t)0x00000000U) /*!< 范围过滤从FilterID1 到 FilterID2 */ #define FDCAN_FILTER_DUAL ((uint32_t)0x00000001U) /*!< 专用ID过滤,FilterID1 或者FilterID2 */ /*!< 精度屏蔽过滤,FilterID1 = filter, FilterID2 = mask */ #define FDCAN_FILTER_MASK ((uint32_t)0x00000002U) /*!< 仅ID扩展模式支持此参数,范围从FilterID1 到 FilterID2, EIDM mask not applied */ #define FDCAN_FILTER_RANGE_NO_EIDM ((uint32_t)0x00000003U)
- FilterConfig
用于设置过滤类型。
#define FDCAN_FILTER_DISABLE ((uint32_t)0x00000000U) 禁止过滤 #define FDCAN_FILTER_TO_RXFIFO0 ((uint32_t)0x00000001U) 如果过滤匹配,将数据保存到Rx FIFO 0 #define FDCAN_FILTER_TO_RXFIFO1 ((uint32_t)0x00000002U) 如果过滤匹配,将数据保存到Rx FIFO 1 #define FDCAN_FILTER_REJECT ((uint32_t)0x00000003U) 如果过滤匹配,拒绝此ID #define FDCAN_FILTER_HP ((uint32_t)0x00000004U) 如果过滤匹配,设置高优先级 #define FDCAN_FILTER_TO_RXFIFO0_HP ((uint32_t)0x00000005U) 如果过滤匹配,设置高优先级并保存到FIFO 0 #define FDCAN_FILTER_TO_RXFIFO1_HP ((uint32_t)0x00000006U) 如果过滤匹配,设置高优先级并保存到FIFO 1 #define FDCAN_FILTER_TO_RXBUFFER ((uint32_t)0x00000007U) 如果过滤匹配,保存到Rx Buffer,并忽略FilterType 配置
- FilterID1
用于设置过滤ID1。如果ID类型是FDCAN_STANDARD_ID,范围0到0x7FF。如果ID类型是FDCAN_EXTENDED_ID,范围是0 到0x1FFFFFFF。
- FilterID2
用于设置过滤ID2。如果FilterConfig设置为FDCAN_FILTER_TO_RXBUFFER,此参数不起作用。如果ID类型是FDCAN_STANDARD_ID,范围0到0x7FF。如果ID类型是FDCAN_EXTENDED_ID,范围是0 到0x1FFFFFFF。
- RxBufferIndex
匹配消息存储到Rx buffer中的索引。参数范围0到63。如果FilterConfig设置为FDCAN_FILTER_TO_RXBUFFER,此参数不起作用。
- IsCalibrationMsg
用于设置是否配置校准消息。如果FilterConfig设置为FDCAN_FILTER_TO_RXBUFFER,此参数不起作用。
0 : 表示正常消息。
1 : 标志校准消息。
91.3.6 FDCAN总线消息发送结构体FDCAN_TxHeaderTypeDef
下面是CAN FD发送消息结构体:
typedef struct { uint32_t Identifier; /*!< Specifies the identifier. This parameter must be a number between: - 0 and 0x7FF, if IdType is FDCAN_STANDARD_ID - 0 and 0x1FFFFFFF, if IdType is FDCAN_EXTENDED_ID */ uint32_t IdType; /*!< Specifies the identifier type for the message that will be transmitted. This parameter can be a value of @ref FDCAN_id_type */ uint32_t TxFrameType; /*!< Specifies the frame type of the message that will be transmitted. This parameter can be a value of @ref FDCAN_frame_type */ uint32_t DataLength; /*!< Specifies the length of the frame that will be transmitted. This parameter can be a value of @ref FDCAN_data_length_code */ uint32_t ErrorStateIndicator; /*!< Specifies the error state indicator. This parameter can be a value of @ref FDCAN_error_state_indicator */ uint32_t BitRateSwitch; /*!< Specifies whether the Tx frame will be transmitted with or without bit rate switching. This parameter can be a value of @ref FDCAN_bit_rate_switching */ uint32_t FDFormat; /*!< Specifies whether the Tx frame will be transmitted in classic or FD format. This parameter can be a value of @ref FDCAN_format */ uint32_t TxEventFifoControl; /*!< Specifies the event FIFO control. This parameter can be a value of @ref FDCAN_EFC */ uint32_t MessageMarker; /*!< Specifies the message marker to be copied into Tx Event FIFO element for identification of Tx message status. This parameter must be a number between 0 and 0xFF */ } FDCAN_TxHeaderTypeDef;
- Identifier
用于设置ID,如果IdType是标准FDCAN_STANDARD_ID,范围0到0x7FF,如果IdType是FDCAN_EXTENDED_ID扩展ID,范围0到0x1FFFFFFF。
- IdType
用于设置标准ID或者扩展ID。
#define FDCAN_STANDARD_ID ((uint32_t)0x00000000U) /*!< 标准ID */ #define FDCAN_EXTENDED_ID ((uint32_t)0x40000000U) /*!< 扩展ID */
- TxFrameType
用于设置帧类型,数据帧或遥控帧。
#define FDCAN_DATA_FRAME ((uint32_t)0x00000000U) /*!< 数据帧 */ #define FDCAN_REMOTE_FRAME ((uint32_t)0x20000000U) /*!< 遥控帧 */
- DataLength
用于设置数据长度。
#define FDCAN_DLC_BYTES_0 ((uint32_t)0x00000000U) /*!< 0 bytes data field */ #define FDCAN_DLC_BYTES_1 ((uint32_t)0x00010000U) /*!< 1 bytes data field */ #define FDCAN_DLC_BYTES_2 ((uint32_t)0x00020000U) /*!< 2 bytes data field */ #define FDCAN_DLC_BYTES_3 ((uint32_t)0x00030000U) /*!< 3 bytes data field */ #define FDCAN_DLC_BYTES_4 ((uint32_t)0x00040000U) /*!< 4 bytes data field */ #define FDCAN_DLC_BYTES_5 ((uint32_t)0x00050000U) /*!< 5 bytes data field */ #define FDCAN_DLC_BYTES_6 ((uint32_t)0x00060000U) /*!< 6 bytes data field */ #define FDCAN_DLC_BYTES_7 ((uint32_t)0x00070000U) /*!< 7 bytes data field */ #define FDCAN_DLC_BYTES_8 ((uint32_t)0x00080000U) /*!< 8 bytes data field */ #define FDCAN_DLC_BYTES_12 ((uint32_t)0x00090000U) /*!< 12 bytes data field */ #define FDCAN_DLC_BYTES_16 ((uint32_t)0x000A0000U) /*!< 16 bytes data field */ #define FDCAN_DLC_BYTES_20 ((uint32_t)0x000B0000U) /*!< 20 bytes data field */ #define FDCAN_DLC_BYTES_24 ((uint32_t)0x000C0000U) /*!< 24 bytes data field */ #define FDCAN_DLC_BYTES_32 ((uint32_t)0x000D0000U) /*!< 32 bytes data field */ #define FDCAN_DLC_BYTES_48 ((uint32_t)0x000E0000U) /*!< 48 bytes data field */ #define FDCAN_DLC_BYTES_64 ((uint32_t)0x000F0000U) /*!< 64 bytes data field */
- ErrorStateIndicator
用于设置错误状态指示:
#define FDCAN_ESI_ACTIVE ((uint32_t)0x00000000U) /*!< 传输节点 error active */ #define FDCAN_ESI_PASSIVE ((uint32_t)0x80000000U) /*!< 传输节点error passive */
- BitRateSwitch
用于设置发送是否波特率可变。
#define FDCAN_BRS_OFF ((uint32_t)0x00000000U) /*!< FDCAN帧发送/接收不带波特率可变 */ #define FDCAN_BRS_ON ((uint32_t)0x00100000U) /*!< FDCAN帧发送/接收带波特率可变 */
- FDFormat
用于设置发送帧是经典格式还是CANFD格式。
#define FDCAN_CLASSIC_CAN ((uint32_t)0x00000000U) /*!< 帧发送/接收使用经典CAN */ #define FDCAN_FD_CAN ((uint32_t)0x00200000U) /*!< 帧发送/接收使用FDCAN格式 */
- TxEventFifoControl
用于设置发送事件FIFO控制。
#define FDCAN_NO_TX_EVENTS ((uint32_t)0x00000000U) /*!< 不存储 Tx events */ #define FDCAN_STORE_TX_EVENTS ((uint32_t)0x00800000U) /*!< 存储Tx events */
- MessageMarker
用于设置复制到TX EVENT FIFO的消息Maker,来识别消息状态,范围0到0xFF。
91.3.7 FDCAN总线消息接收结构体FDCAN_RxHeaderTypeDef
下面是CAN FD接收消息结构体:
typedef struct { uint32_t Identifier; /*!< Specifies the identifier. This parameter must be a number between: - 0 and 0x7FF, if IdType is FDCAN_STANDARD_ID - 0 and 0x1FFFFFFF, if IdType is FDCAN_EXTENDED_ID */ uint32_t IdType; /*!< Specifies the identifier type of the received message. This parameter can be a value of @ref FDCAN_id_type */ uint32_t RxFrameType; /*!< Specifies the the received message frame type. This parameter can be a value of @ref FDCAN_frame_type */ uint32_t DataLength; /*!< Specifies the received frame length. This parameter can be a value of @ref FDCAN_data_length_code */ uint32_t ErrorStateIndicator; /*!< Specifies the error state indicator. This parameter can be a value of @ref FDCAN_error_state_indicator */ uint32_t BitRateSwitch; /*!< Specifies whether the Rx frame is received with or without bit rate switching. This parameter can be a value of @ref FDCAN_bit_rate_switching */ uint32_t FDFormat; /*!< Specifies whether the Rx frame is received in classic or FD format. This parameter can be a value of @ref FDCAN_format */ uint32_t RxTimestamp; /*!< Specifies the timestamp counter value captured on start of frame reception. This parameter must be a number between 0 and 0xFFFF */ uint32_t FilterIndex; /*!< Specifies the index of matching Rx acceptance filter element. This parameter must be a number between: - 0 and 127, if IdType is FDCAN_STANDARD_ID - 0 and 63, if IdType is FDCAN_EXTENDED_ID */ uint32_t IsFilterMatchingFrame; /*!< Specifies whether the accepted frame did not match any Rx filter. Acceptance of non-matching frames may be enabled via HAL_FDCAN_ConfigGlobalFilter(). This parameter can be 0 or 1 */ } FDCAN_RxHeaderTypeDef;
- Identifier
用于设置ID,如果IdType是标准FDCAN_STANDARD_ID,范围0到0x7FF,如果IdType是FDCAN_EXTENDED_ID扩展ID,范围0到0x1FFFFFFF。
- IdType
用于设置标志ID或者扩展ID。
#define FDCAN_STANDARD_ID ((uint32_t)0x00000000U) /*!< 标准ID */ #define FDCAN_EXTENDED_ID ((uint32_t)0x40000000U) /*!< 扩展ID */
- RxFrameType
用于设置接收帧类型,数据帧或遥控帧
#define FDCAN_DATA_FRAME ((uint32_t)0x00000000U) /*!< 数据帧 */ #define FDCAN_REMOTE_FRAME ((uint32_t)0x20000000U) /*!< 遥控帧 */
- DataLength
用于设置数据长度。
#define FDCAN_DLC_BYTES_0 ((uint32_t)0x00000000U) /*!< 0 bytes data field */ #define FDCAN_DLC_BYTES_1 ((uint32_t)0x00010000U) /*!< 1 bytes data field */ #define FDCAN_DLC_BYTES_2 ((uint32_t)0x00020000U) /*!< 2 bytes data field */ #define FDCAN_DLC_BYTES_3 ((uint32_t)0x00030000U) /*!< 3 bytes data field */ #define FDCAN_DLC_BYTES_4 ((uint32_t)0x00040000U) /*!<