STM32 库函数 CAN结构体
STM32 库函数 CAN结构体
CAN结构体
-
- CAN_InitTypeDef 初始化结构体
-
- CAN_FilterTypeDef 筛选器结构体
-
- CAN_TxHeaderTypeDef 发送结构体
-
- CAN_RxHeaderTypeDef 接收结构体
1 CAN_InitTypeDef 初始化结构体
typedef struct
{
uint32_t Prescaler; /*配置CAN外设时钟分频 在1——1024之间*/
uint32_t Mode; /* 工作模式*/
uint32_t SyncJumpWidth; /*! 重新同步时长*/
uint32_t TimeSeg1; /*!< 配置BS1段长度 @ref CAN_time_quantum_in_bit_segment_1*/
uint32_t TimeSeg2; /*!< 配置BS2段长度 CAN_time_quantum_in_bit_segment_2*/
FunctionalState TimeTriggeredMode; /*!< 时间触发模式使能位 */
FunctionalState AutoBusOff; /*!< 自动离线管理使能位*/
FunctionalState AutoWakeUp; /*!< 自动唤醒使能位*/
FunctionalState AutoRetransmission; /*!< 自动重传使能位*/
FunctionalState ReceiveFifoLocked; /*!< 接收FIFO锁定使能位*/
FunctionalState TransmitFifoPriority;/*!< 发送FIFO的报文优先级判断位 */
} CAN_InitTypeDef;
CAN_InitTypeDef 有11个参数。
1.1 - 参数 Prescaler
设置CAN时钟分频,可以控制时间片Tq的长度,来配置波特率,这里的值减1后会写入到BRP寄存器:
Tq = (BRP[9:0]+1) x TPCLK
Tq = CAN_Prescaler x TPCLK
Prescaler赋值时会自动减1,想分频多少这里就赋值多少。PCLK是CAN的时钟来源,这里是APB1总线时钟,stm32f4默认值为45MHz。
算出CAN通讯的波特率:
BaudRate = 1/N xTq
N为1bit位的长度,配置是下面两个参数 TimeSeg1 和TimeSeg2.
1.2 - 参数 TimeSeg1
TimeSeg1 配置BS1段长度,TimeSeg2 配置BS2段长度。
BS1段前面的SYNC_SEG是固定1tq 。
有了这两个参数就确定了1bit位的长度:
T1bit = 1Tq + TBS1 +Tbs2
TimeSeg1 可以按照下面的宏定义来方便赋值:
/** @defgroup CAN_time_quantum_in_bit_segment_1 CAN Time Quantum in Bit Segment 1
* @{
*/
#define CAN_BS1_1TQ (0x00000000U) /*!< 1 time quantum */
#define CAN_BS1_2TQ ((uint32_t)CAN_BTR_TS1_0) /*!< 2 time quantum */
#define CAN_BS1_3TQ ((uint32_t)CAN_BTR_TS1_1) /*!< 3 time quantum */
#define CAN_BS1_4TQ ((uint32_t)(CAN_BTR_TS1_1 | CAN_BTR_TS1_0)) /*!< 4 time quantum */
#define CAN_BS1_5TQ ((uint32_t)CAN_BTR_TS1_2) /*!< 5 time quantum */
#define CAN_BS1_6TQ ((uint32_t)(CAN_BTR_TS1_2 | CAN_BTR_TS1_0)) /*!< 6 time quantum */
#define CAN_BS1_7TQ ((uint32_t)(CAN_BTR_TS1_2 | CAN_BTR_TS1_1)) /*!< 7 time quantum */
#define CAN_BS1_8TQ ((uint32_t)(CAN_BTR_TS1_2 | CAN_BTR_TS1_1 | CAN_BTR_TS1_0)) /*!< 8 time quantum */
#define CAN_BS1_9TQ ((uint32_t)CAN_BTR_TS1_3) /*!< 9 time quantum */
#define CAN_BS1_10TQ ((uint32_t)(CAN_BTR_TS1_3 | CAN_BTR_TS1_0)) /*!< 10 time quantum */
#define CAN_BS1_11TQ ((uint32_t)(CAN_BTR_TS1_3 | CAN_BTR_TS1_1)) /*!< 11 time quantum */
#define CAN_BS1_12TQ ((uint32_t)(CAN_BTR_TS1_3 | CAN_BTR_TS1_1 | CAN_BTR_TS1_0)) /*!< 12 time quantum */
#define CAN_BS1_13TQ ((uint32_t)(CAN_BTR_TS1_3 | CAN_BTR_TS1_2)) /*!< 13 time quantum */
#define CAN_BS1_14TQ ((uint32_t)(CAN_BTR_TS1_3 | CAN_BTR_TS1_2 | CAN_BTR_TS1_0)) /*!< 14 time quantum */
#define CAN_BS1_15TQ ((uint32_t)(CAN_BTR_TS1_3 | CAN_BTR_TS1_2 | CAN_BTR_TS1_1)) /*!< 15 time quantum */
#define CAN_BS1_16TQ ((uint32_t)CAN_BTR_TS1) /*!< 16 time quantum */
/**
* @}
*/
1.3 - 参数 TimeSeg2
参数 TimeSeg1 和TimeSeg2组成了1bit位的长度
TimeSeg2 可以按照下面的宏定义来方便赋值:
/** @defgroup CAN_time_quantum_in_bit_segment_2 CAN Time Quantum in Bit Segment 2
* @{
*/
#define CAN_BS2_1TQ (0x00000000U) /*!< 1 time quantum */
#define CAN_BS2_2TQ ((uint32_t)CAN_BTR_TS2_0) /*!< 2 time quantum */
#define CAN_BS2_3TQ ((uint32_t)CAN_BTR_TS2_1) /*!< 3 time quantum */
#define CAN_BS2_4TQ ((uint32_t)(CAN_BTR_TS2_1 | CAN_BTR_TS2_0)) /*!< 4 time quantum */
#define CAN_BS2_5TQ ((uint32_t)CAN_BTR_TS2_2) /*!< 5 time quantum */
#define CAN_BS2_6TQ ((uint32_t)(CAN_BTR_TS2_2 | CAN_BTR_TS2_0)) /*!< 6 time quantum */
#define CAN_BS2_7TQ ((uint32_t)(CAN_BTR_TS2_2 | CAN_BTR_TS2_1)) /*!< 7 time quantum */
#define CAN_BS2_8TQ ((uint32_t)CAN_BTR_TS2) /*!< 8 time quantum */
/**
* @}
*/
1.4 - 参数 SyncJumpWidth
配置重新同步宽度 SJW,同步时通过这个参数增加或减少的时间长度。
可以按照下面的宏定义来方便赋值:
/** @defgroup CAN_synchronisation_jump_width CAN Synchronization Jump Width
* @{
*/
#define CAN_SJW_1TQ (0x00000000U) /*!< 1 time quantum */
#define CAN_SJW_2TQ ((uint32_t)CAN_BTR_SJW_0) /*!< 2 time quantum */
#define CAN_SJW_3TQ ((uint32_t)CAN_BTR_SJW_1) /*!< 3 time quantum */
#define CAN_SJW_4TQ ((uint32_t)CAN_BTR_SJW) /*!< 4 time quantum */
/**
* @}
*/
以上就是与位时序和波特率有关的参数。
例如配置波特率位1Mbps的方法:
参数 | 说明 |
---|---|
SYNC_SE段 | 固定为1Tq |
BS1段 | 设置为5Tq (实际写入TS1[3:0]的值为4) |
BS2段 | 设置为3Tq (实际写入TS2[2:0]的值为2) |
T PCLK | APB1按默认配置为F=45MHz, TPCLK=1/45M |
CAN外设时钟分频 | 设置为5分频(实际写入BRP[9:0]的值为4) |
1Tq时间长度 | Tq = (BRP[9:0]+1) x TPCLK = 5 x 1/45M=1/9M |
1位的时间长度 | T1bit =1Tq +TS1+TS2 = 1+5+3 = 9Tq |
波特率 | BaudRate = 1/N*Tq = 1/(1/9M x 9)=1Mbp |
1.5 - 参数 Mode
配置CAN工作模式,有4中模式,参数如下:
-
正常模式 :正常的CAN节点,可以向纵向发送和接收数据
-
静默模式 :发出的逻辑0被自己的输入端接收,逻辑1会被发送到总线, 所以只向总线发送逻辑1,不发送逻辑0。
由于逻辑1是隐性不会影响总线状态,所以称为静默,一般用于检测,用来分析总线流量。
-
回环模式 :输出端的内容全被输入端接收,同时也发送到总线上。输入端只接收自己发送端的内容,不接收总线上的内容,此模式用来自检。
-
回环静默模式:是静默和回环的组合,自己输出端的内容全部传输到自己的输入端,并且不会向总线发显性位影响总线。输入端只接收自己发送端的内容,不 接收总线也不影响总线。这种方式用来自检的时候不会干扰总线。
可以按照下面的宏定义来方便赋值:
/** @defgroup CAN_operating_mode CAN Operating Mode
* @{
*/
#define CAN_MODE_NORMAL (0x00000000U) /*!< 正常模式 */
#define CAN_MODE_LOOPBACK ((uint32_t)CAN_BTR_LBKM) /*!< 回环模式 */
#define CAN_MODE_SILENT ((uint32_t)CAN_BTR_SILM) /*!< 静默模式 */
#define CAN_MODE_SILENT_LOOPBACK ((uint32_t)(CAN_BTR_LBKM | CAN_BTR_SILM)) /*!< 回环静默模式 */
/**
* @}
*/
1.6 - 参数 TimeTriggeredMode
是否使用时间触发功能,发送时间戳。
1.7 - 参数 AutoBusOff
是否用自动离线管理,可以在节点出错离线后自动恢复。
1.8 - 参数AutoWakeUp
是否使用自动唤醒功能,如果在低功耗模式下检测到总线活动后自动唤醒。
1.9 -参数 AutoRetransmission
是否使用自动重传功能。出错的时候会一直重发报文直到成功为止。
1.10 - 参数 ReceiveFifoLocked
是否锁定接收队列FIFO。打开后,当两个FIFO都接收满了时锁定FIFO,否则覆盖掉。
1.11 - 参数 TransmitFifoPriority
设置报文优先级判定方法。打开后,按报文存入邮箱的先后顺序来发送,否则按报文的ID顺序来发送。一般都是按报文的ID顺序。
2 CAN_TxHeaderTypeDef 发送结构体
/**
* @brief CAN Tx message header structure definition
*/
typedef struct
{
uint32_t StdId; /*!< 报文的标准编号(Id)11位 0 - 0x7FF. */
uint32_t ExtId; /*!< 报文的扩展编号(Id)9位 0 - 0x1FFFFFFF. */
uint32_t IDE; /*!< 标准和扩展帧选择位 @ref CAN_identifier_type */
uint32_t RTR; /*!< 遥控帧(远程帧)选择 @ref CAN_remote_transmission_request */
uint32_t DLC; /*!< 报文控制段的长度 0 - 8. */
FunctionalState TransmitGlobalTime; /*!< 使能时间戳添加到 Data[6]和Data[7]*/
} CAN_TxHeaderTypeDef;
CAN_TxHeaderTypeDef 发送结构体有6个参数
2.1- 参数 StdId
报文的标准编号(Id)11位 0 - 0x7FF,使用标准帧时,ExtId不用管。
2.2- 参数 ExtId
报文的扩展编号(Id)9位 0 - 0x1FFFFFFF,使用扩展帧时StdId不用管。
2.3- 参数 IDE
标准和扩展帧选择位。可以按照下面的宏定义来方便赋值:
/** @defgroup CAN_identifier_type CAN Identifier Type
* @{
*/
#define CAN_ID_STD (0x00000000U) /*!< 标准帧 Id*/
#define CAN_ID_EXT (0x00000004U) /*!< 扩展帧 Id */
/**
* @}
*/
2.4- 参数 RTR
数据帧和遥控帧(远程帧)选择标志。可以按照下面的宏定义来方便赋值:
/** @defgroup CAN_remote_transmission_request CAN Remote Transmission Request
* @{
*/
#define CAN_RTR_DATA (0x00000000U) /*!<数据帧 */
#define CAN_RTR_REMOTE (0x00000002U) /*!< 遥控帧 */
/**
* @}
*/
2.5- 参数 DLC
报文控制段的长度,范围是0-8,当报文是遥控帧时DLC为0.
2.6- 参数 TransmitGlobalTime
时间触发模式用的,开启后会自动把时间戳添加到最后两字节的数据中。
3 CAN_RxHeaderTypeDef 接收结构体
/**
* @brief CAN Rx message header structure definition
*/
typedef struct
{
uint32_t StdId; /*!< 报文的标准编号(Id)11位 范围是0 - 0x7FF. */
uint32_t ExtId; /*!< 报文的扩展编号(Id)9位 范围是 0 - 0x1FFFFFFF. */
uint32_t IDE; /*!< 标准和扩展帧选择位 @ref CAN_identifier_type */
uint32_t RTR; /*!< 遥控帧(远程帧)选择 @ref CAN_remote_transmission_request */
uint32_t DLC; /*!< 报文控制段的长度范围是 0 - 8. */
uint32_t Timestamp; /*!< 使用时间触发模式时,记录时间戳 范围是 0 - 0xFFFF. */
uint32_t FilterMatchIndex; /*!< 报文筛选器的编号 范围是 0 - 0xFF. */
} CAN_RxHeaderTypeDef;
接收结构体参数有7个:
- StdId 和发送结构体相同
- ExtId 和发送结构体相同
- IDE 和发送结构体相同
- RTR 和发送结构体相同
- DLC 和发送结构体相同
- Timestamp 记录时间戳,范围是 0 - 0xFFFF,只在时间触发模式下使用。
- FilterMatchIndex 只有接收结构体有,保存筛选器编号,表示报文经过哪个筛选器收进FIFO的。
4 CAN_FilterTypeDef 筛选器结构体
typedef struct
{
uint32_t FilterIdHigh; /*!< 筛选器ID高位 0x0000 - 0xFFFF. */
uint32_t FilterIdLow; /*!< 筛选器ID低位 0x0000 - 0xFFFF. */
uint32_t FilterMaskIdHigh; /*!< 筛选器掩码模式ID 0x0000 - 0xFFFF. */
uint32_t FilterMaskIdLow; /*!< 筛选器掩码模式ID 0x0000 - 0xFFFF. */
uint32_t FilterFIFOAssignment; /*!< 为筛选器指定FIFO0或者FIFO1 of @ref CAN_filter_FIFO */
uint32_t FilterBank; /*!< 筛选器编号 0 - 13 或 0 - 27. */
uint32_t FilterMode; /*!< 筛选器工作模式, @ref CAN_filter_mode */
uint32_t FilterScale; /*!< 筛选器长度,32位或16位 @ref CAN_filter_scale */
uint32_t FilterActivation; /*!< 启用或禁用筛选器 @ref CAN_filter_activation */
uint32_t SlaveStartFilterBank; /*!< 指定辅CAN筛选器的编号 */
} CAN_FilterTypeDef;
筛选器结构体有10个参数。
4.1- 参数 FilterIdHigh
它的范围是 0x0000 到0xFFFF。
如果是32位,表示Id1的高16位。如果是16位,表示Id1的完整数值。
4.2- 参数 FilterIdLow
它的范围是 0x0000 到0xFFFF。
如果是32位,表示Id1的低16位。如果是16位,表示Id2的完整数值。
4.3- 参数 FilterMaskIdHigh
它的范围是 0x0000 到0xFFFF。
如果是32位列表,表示Id2的高16位。若是32位掩码,表示Id1掩码高16位。
如果是16位列表,表示Id3的完整数值。如果是16位掩码,表示Id1的掩码。
4.4- 参数 FilterMaskIdLow
如果是32位列表,表示Id2的低16位。如果是32位掩码,表示Id1掩码的低16位。
如果是16位列表,表示Id4的完整数值。如果是16位掩码,表示Id2的掩码。
4.5- 参数 FilterFIFOAssignment
经过筛选后报文存到哪个FIFO
配置参数如下:
/** @defgroup CAN_filter_FIFO CAN Filter FIFO
* @{
*/
#define CAN_FILTER_FIFO0 (0x00000000U) /*!< 报文保存到 FIFO 0 */
#define CAN_FILTER_FIFO1 (0x00000001U) /*!< 报文保存到 FIFO 1 */
/**
* @}
*/
4.6- 参数 FilterBank
筛选器编号,选择哪组筛选器,共有28个,参数范围是0-27。
4.7- 参数 FilterMode
筛选器工作模式:Id掩码模式 和 Id列表模式
配置参数如下:
/** @defgroup CAN_filter_mode CAN Filter Mode
* @{
*/
#define CAN_FILTERMODE_IDMASK (0x00000000U) /*!< Id掩码模式 */
#define CAN_FILTERMODE_IDLIST (0x00000001U) /*!< Id列表模式 */
/**
* @}
*/
4.8- 参数 FilterScale
筛选器长度,32位或16位长度。
配置参数如下:
/** @defgroup CAN_filter_scale CAN Filter Scale
* @{
*/
#define CAN_FILTERSCALE_16BIT (0x00000000U) /*!< 两个 16-bit 筛选器 */
#define CAN_FILTERSCALE_32BIT (0x00000001U) /*!< 一个 32-bit 筛选器 */
/**
* @}
*/
4.9- 参数 FilterActivation
启用或禁用筛选器,只有这里启用了后前面的配置才有用。
配置参数如下:
/** @defgroup CAN_filter_activation CAN Filter Activation
* @{
*/
#define CAN_FILTER_DISABLE (0x00000000U) /*!< 禁用筛选器 */
#define CAN_FILTER_ENABLE (0x00000001U) /*!< 启用筛选器 */
/**
* @}
*/
4.10- 参数 SlaveStartFilterBank
当用双CAN总线(例如一个主和辅),这个参数指定辅CAN筛选器的编号,参数范围是0-27。
4.5 筛选器结构体的前4个参数组合:
模式 | CAN_FilterIdHigh | CAN_FilterIdLow | CAN_FilterMaskIdHigh | CAN_FilterMaskIdLow |
---|---|---|---|---|
32位列表模式 | ID1的高16位 | ID1的低16位 | ID2的高16位 | ID2的低16位 |
32位掩码模式 | ID1的高16位 | ID1的低16位 | ID1掩码的高16位 | ID1掩码的低16位 |
16位列表模式 | ID1的完整数值 | ID2的完整数值 | ID3的完整数值 | ID4的完整数值 |
16位掩码模式 | ID1的完整数值 | ID2的完整数值 | ID1掩码的完整数值 | ID2掩码完整数值 |