分享STM32H7的CAN寄存器配置方法,不使用中断,采用查询的方式实现H7的CAN收发配置,仿ST的标准库,将CAN的配置封装了一下。
以下是头文件的CAN1的RAM空间分配宏定义:
#define CAN_WAIT_INIT_TIME 1000
#define CAN_WAIT_TRANSMIT_OVER_TIME 10000
#define CAN_WAIT_RECEIVE_OVER_TIME 1000/*由于STM32H7的CAN消息是存放在RAM中的,因此需要知道RAM起始地址才好定义各个元素的大小及区域,这里可能不同型号的芯片的RAM地址不同,需要区翻阅数据手册*/
#define CAN_MESSAGE_RAM_BASE 0x4000AC00
#define CAN1_STANDARD_FILTER_START_ADDRESS 0
#define CAN1_STANDARD_FLITER_ELEMENTS_NUM 128
#define CAN1_EXPAND_ID_FILTER_START_ADDRESS (CAN1_STANDARD_FILTER_START_ADDRESS + (CAN1_STANDARD_FLITER_ELEMENTS_NUM * 4))
#define CAN1_EXPAND_ID_FILTER_ELEMENTS_NUM 64
#define CAN1_RX_FIFO0_START_ADDRESS (CAN1_EXPAND_ID_FILTER_START_ADDRESS + (CAN1_EXPAND_ID_FILTER_ELEMENTS_NUM * 4))
#define CAN1_RX_FIFO0_ELEMENTS_NUM 64
#define CAN1_RX_FIFO0_ELEMENTS_SIZE 4
#define CAN1_RX_FIFO1_START_ADDRESS (CAN1_RX_FIFO0_START_ADDRESS + (CAN1_RX_FIFO0_ELEMENTS_NUM * CAN1_RX_FIFO0_ELEMENTS_SIZE))#define CAN1_RX_FIFO1_ELEMENTS_NUM 0
#define CAN1_RX_FIFO1_ELEMENTS_SIZE 0
#define CAN1_RX_BUFFER_START_ADDRESS (CAN1_RX_FIFO1_START_ADDRESS + (CAN1_RX_FIFO1_ELEMENTS_NUM * CAN1_RX_FIFO1_ELEMENTS_SIZE))#define CAN1_RX_BUFFER_ELEMENTS_NUM 0
#define CAN1_RX_BUFFER_ELEMENTS_SIZE 0
#define CAN1_TX_EVENT_FIFO_START_ADDRESS (CAN1_RX_BUFFER_START_ADDRESS + (CAN1_RX_BUFFER_ELEMENTS_NUM * CAN1_RX_BUFFER_ELEMENTS_SIZE))#define CAN1_TX_EVENT_FIFO_ELEMENTS_NUM 0
#define CAN1_TX_EVENT_FIFO_ELEMENTS_SIZE 0
#define CAN1_TX_BUFFER_START_ADDRESS (CAN1_TX_EVENT_FIFO_START_ADDRESS + (CAN1_TX_EVENT_FIFO_ELEMENTS_NUM * CAN1_TX_EVENT_FIFO_ELEMENTS_SIZE))#define CAN1_TX_BUFFER_ELEMENTS_NUM 0
#define CAN1_TX_BUFFER_ELEMENTS_SIZE 0
#define CAN1_TX_FIFO_START_ADDRESS (CAN1_TX_BUFFER_START_ADDRESS + (CAN1_TX_BUFFER_ELEMENTS_NUM * CAN1_TX_BUFFER_ELEMENTS_SIZE))#define CAN1_TX_FIFO_ELEMENTS_NUM 32
#define CAN1_TX_FIFO_ELEMENTS_SIZE 4
#define CAN1_MESSAGE_RAM_END_ADDRESS (CAN_MESSAGE_RAM_BASE + (CAN1_TX_FIFO_START_ADDRESS + (CAN1_TX_FIFO_ELEMENTS_NUM * CAN1_TX_FIFO_ELEMENTS_SIZE)) * 4)
在当前的配置中,我使用RX_FIFO0作为CAN1的接收RAM,使用了64个元素,如需更改其他方式作为CAN1的接收RAM,可更改宏定义,会自动计算地址,但是需要更改CAN的配置
以下是CAN2的RAM空间分配宏定义:
#define CAN2_STANDARD_FILTER_START_ADDRESS 1280
#define CAN2_STANDARD_FLITER_ELEMENTS_NUM 128
#define CAN2_EXPAND_ID_FILTER_START_ADDRESS (CAN2_STANDARD_FILTER_START_ADDRESS + (CAN2_STANDARD_FLITER_ELEMENTS_NUM * 4))#define CAN2_EXPAND_ID_FILTER_ELEMENTS_NUM 64
#define CAN2_RX_FIFO0_START_ADDRESS (CAN2_EXPAND_ID_FILTER_START_ADDRESS + (CAN2_EXPAND_ID_FILTER_ELEMENTS_NUM * 4))
#define CAN2_RX_FIFO0_ELEMENTS_NUM 64
#define CAN2_RX_FIFO0_ELEMENTS_SIZE 4
#define CAN2_RX_FIFO1_START_ADDRESS (CAN2_RX_FIFO0_START_ADDRESS + (CAN2_RX_FIFO0_ELEMENTS_NUM * CAN2_RX_FIFO0_ELEMENTS_SIZE))
#define CAN2_RX_FIFO1_ELEMENTS_NUM 0
#define CAN2_RX_FIFO1_ELEMENTS_SIZE 0
#define CAN2_RX_BUFFER_START_ADDRESS (CAN2_RX_FIFO1_START_ADDRESS + (CAN2_RX_FIFO1_ELEMENTS_NUM * CAN2_RX_FIFO1_ELEMENTS_SIZE))
#define CAN2_RX_BUFFER_ELEMENTS_NUM 0
#define CAN2_RX_BUFFER_ELEMENTS_SIZE 0
#define CAN2_TX_EVENT_FIFO_START_ADDRESS (CAN2_RX_BUFFER_START_ADDRESS + (CAN2_RX_BUFFER_ELEMENTS_NUM * CAN2_RX_BUFFER_ELEMENTS_SIZE))
#define CAN2_TX_EVENT_FIFO_ELEMENTS_NUM 0
#define CAN2_TX_EVENT_FIFO_ELEMENTS_SIZE 0
#define CAN2_TX_BUFFER_START_ADDRESS (CAN2_TX_EVENT_FIFO_START_ADDRESS + (CAN2_TX_EVENT_FIFO_ELEMENTS_NUM * CAN2_TX_EVENT_FIFO_ELEMENTS_SIZE))
#define CAN2_TX_BUFFER_ELEMENTS_NUM 0
#define CAN2_TX_BUFFER_ELEMENTS_SIZE 0
#define CAN2_TX_FIFO_START_ADDRESS (CAN2_TX_BUFFER_START_ADDRESS + (CAN2_TX_BUFFER_ELEMENTS_NUM * CAN2_TX_BUFFER_ELEMENTS_SIZE))
#define CAN2_TX_FIFO_ELEMENTS_NUM 32
#define CAN2_TX_FIFO_ELEMENTS_SIZE 4
#define CAN2_MESSAGE_RAM_START_ADDRESS (CAN_MESSAGE_RAM_BASE + (CAN2_STANDARD_FILTER_START_ADDRESS * 4))
#define CAN2_MESSAGE_RAM_END_ADDRESS (CAN_MESSAGE_RAM_BASE + (CAN2_TX_FIFO_START_ADDRESS + (CAN2_TX_FIFO_ELEMENTS_NUM * CAN2_TX_FIFO_ELEMENTS_SIZE)) * 4)
具体的STM32H7的RAM空间划分可自行查看数据手册
以下则是仿ST标准库的数据结构
#define FDCAN_ELEMENT_MASK_STDID ((uint32_t)0x1FFC0000U) /* Standard Identifier */
#define FDCAN_ELEMENT_MASK_EXTID ((uint32_t)0x1FFFFFFFU) /* Extended Identifier */
#define FDCAN_ELEMENT_MASK_RTR ((uint32_t)0x20000000U) /* Remote Transmission Request */
#define FDCAN_ELEMENT_MASK_XTD ((uint32_t)0x40000000U) /* Extended Identifier */
#define FDCAN_ELEMENT_MASK_ESI ((uint32_t)0x80000000U) /* Error State Indicator */
#define FDCAN_ELEMENT_MASK_TS ((uint32_t)0x0000FFFFU) /* Timestamp */
#define FDCAN_ELEMENT_MASK_DLC ((uint32_t)0x000F0000U) /* Data Length Code */
#define FDCAN_ELEMENT_MASK_BRS ((uint32_t)0x00100000U) /* Bit Rate Switch */
#define FDCAN_ELEMENT_MASK_FDF ((uint32_t)0x00200000U) /* FD Format */
#define FDCAN_ELEMENT_MASK_EFC ((uint32_t)0x00800000U) /* Event FIFO Control */
#define FDCAN_ELEMENT_MASK_MM ((uint32_t)0xFF000000U) /* Message Marker */
#define FDCAN_ELEMENT_MASK_FIDX ((uint32_t)0x7F000000U) /* Filter Index */
#define FDCAN_ELEMENT_MASK_ANMF ((uint32_t)0x80000000U) /* Accepted Non-matching Frame */
#define FDCAN_ELEMENT_MASK_ET ((uint32_t)0x00C00000U) /* Event type */#define FDCAN_STANDARD_ID ((uint32_t)0x00000000U) /*!< Standard ID element */
#define FDCAN_EXTENDED_ID ((uint32_t)0x40000000U) /*!< Extended ID element */#define FDCAN_DATA_BYTES_8 ((uint8_t)0x00U) /*!< 8 bytes data field */
#define FDCAN_DATA_BYTES_12 ((uint8_t)0x01U) /*!< 12 bytes data field */
#define FDCAN_DATA_BYTES_16 ((uint8_t)0x02U) /*!< 16 bytes data field */
#define FDCAN_DATA_BYTES_20 ((uint8_t)0x03U) /*!< 20 bytes data field */
#define FDCAN_DATA_BYTES_24 ((uint8_t)0x04U) /*!< 24 bytes data field */
#define FDCAN_DATA_BYTES_32 ((uint8_t)0x05U) /*!< 32 bytes data field */
#define FDCAN_DATA_BYTES_48 ((uint8_t)0x06U) /*!< 48 bytes data field */
#define FDCAN_DATA_BYTES_64 ((uint8_t)0x07U) /*!< 64 bytes data field */#define FDCAN_TX_FIFO_OPERATION ((uint8_t)0x00U) /*!< FIFO mode */
#define FDCAN_TX_QUEUE_OPERATION ((uint8_t)0x01U) /*!< Queue mode */#define FDCAN_FRAME_CLASSIC ((uint8_t)0x00U) /*!< Classic mode */
#define FDCAN_FRAME_FD_NO_BRS ((uint8_t)0x01U) /*!< FD mode without BitRate Switching */
#define FDCAN_FRAME_FD_BRS ((uint8_t)0x02U) /*!< FD mode with BitRate Switching */
#define FDCAN_MODE_NORMAL ((uint8_t)0x00U) /*!< Normal mode */
#define FDCAN_MODE_RESTRICTED_OPERATION ((uint