《STM32从零开始学习历程》——CAN相关结构体

24 篇文章 1 订阅
6 篇文章 6 订阅

《STM32从零开始学习历程》@EnzoReventon

CAN相关结构体

相关链接:

《STM32从零开始学习历程》——CAN通讯协议物理层
CAN-bus规范 V2.0版本
CAN总线入门
周立功-CAN协议中文版

参考资料:
[野火EmbedFire]《STM32库开发实战指南——基于野火霸天虎开发板》
[正点原子]STM32F4开发指南-库函数版本_V1.2
[ST]《STM32F4xx中文参考手册》
CAN-bus规范 V2.0版本
CAN总线入门
周立功-CAN协议中文版

CAN结构体

从STM32的CAN外设我们了解到它的功能非常多,控制涉及的寄存器也非常丰富,而使用STM32标准库提供的各种结构体及库函数可以简化这些控制过程。跟其它外设一样,STM32标准库提供了CAN初始化结构体及初始化函数来控制CAN的工作方式,提供了收发报文使用的结构体及收发函数,还有配置控制筛选器模式及ID的结构体。

  • 初始化结构体:CAN_InitTypeDef
typedef struct
{
  uint16_t CAN_Prescaler;   /*!< Specifies the length of a time quantum. 
                                 It ranges from 1 to 1024. 
                                 配置CAN外设的时钟分频,可以设置为1-1024*/ 
                                 
  
  uint8_t CAN_Mode;         /*!< Specifies the CAN operating mode.
                                 This parameter can be a value of @ref CAN_operating_mode 
                                 配置CAN的工作模式,回环或正常模式*/

  uint8_t CAN_SJW;          /*!< Specifies the maximum number of time quanta 
                                 the CAN hardware is allowed to lengthen or 
                                 shorten a bit to perform resynchronization.
                                 This parameter can be a value of @ref CAN_synchronisation_jump_width 
                                 配置SJW极限值*/

  uint8_t CAN_BS1;          /*!< Specifies the number of time quanta in Bit 
                                 Segment 1. This parameter can be a value of 
                                 @ref CAN_time_quantum_in_bit_segment_1 
                                 配置BS1段长度*/

  uint8_t CAN_BS2;          /*!< Specifies the number of time quanta in Bit Segment 2.
                                 This parameter can be a value of @ref CAN_time_quantum_in_bit_segment_2 
                                 配置BS2段长度*/
  
  FunctionalState CAN_TTCM; /*!< Enable or disable the time triggered communication mode.
                                This parameter can be set either to ENABLE or DISABLE. 
                                是否使能TTCM时间触发功能*/
  
  FunctionalState CAN_ABOM;  /*!< Enable or disable the automatic bus-off management.
                                  This parameter can be set either to ENABLE or DISABLE. 
                                  是否使能ABOM自动离线管理功能*/

  FunctionalState CAN_AWUM;  /*!< Enable or disable the automatic wake-up mode. 
                                  This parameter can be set either to ENABLE or DISABLE. 
                                  是否使能AWUM自动唤醒功能*/

  FunctionalState CAN_NART;  /*!< Enable or disable the non-automatic retransmission mode.
                                  This parameter can be set either to ENABLE or DISABLE.
                                  是否使用NART自动重传功能*/

  FunctionalState CAN_RFLM;  /*!< Enable or disable the Receive FIFO Locked mode.
                                  This parameter can be set either to ENABLE or DISABLE.
                                  是否使能RELM锁定FIFO功能 */

  FunctionalState CAN_TXFP;  /*!< Enable or disable the transmit FIFO priority.
                                  This parameter can be set either to ENABLE or DISABLE. 
                                  配置TXFP报文优先级的判定方法*/
} CAN_InitTypeDef;

CAN_Prescaler: 本成员设置CAN外设的时钟分频,它可控制时间片Tq的时间长度,这里设置的值最终会减1后再写入BRP寄存器位,即前面介绍的Tq计算公式:
T_q = (BRP[9:0]+1) x T_PCLK
等效于:T_q = CAN_Prescaler x T_PCLK

CAN_Mode: 本成员设置CAN的工作模式,可设置为正常模式(CAN_Mode_Normal)回环模式(CAN_Mode_LoopBack)静默模式(CAN_Mode_Silent)以及回环静默模式(CAN_Mode_Silent_LoopBack)

CAN_SJW: 本成员可以配置SJW的极限长度,即CAN重新同步时单次可增加或缩短的最大长度,它可以被配置为1-4Tq(CAN_SJW_1/2/3/4tq)。

CAN_BS1:本成员用于设置CAN位时序中的BS1段的长度,它可以被配置为1-16个Tq长度(CAN_BS1_1/2/3…16tq)。

CAN_BS2: 本成员用于设置CAN位时序中的BS2段的长度,它可以被配置为1-8个Tq长度(CAN_BS2_1/2/3…8tq)。
SYNC_SEG、BS1段及BS2段的长度加起来即一个数据位的长度,即前面介绍的原来计算公式:

T_1bit =1T_q+T_S1+T_S2 =1+ (T_S1[3:0] + 1)+ (T_S2[2:0] + 1)
等效于:T_1bit = 1T_q+CAN_BS1+CAN_BS2

CAN_TTCM: 本成员用于设置是否使用时间触发功能(ENABLE/DISABLE),时间触发功能在某些CAN标准中会使用到。

CAN_ABOM: 本成员用于设置是否使用自动离线管理(ENABLE/DISABLE),使用自动离线管理可以在节点出错离线后适时自动恢复,不需要软件干预。

CAN_ AWUM: 本成员用于设置是否使用自动唤醒功能(ENABLE/DISABLE),使能自动唤醒功能后它会在监测到总线活动后自动唤醒。

CAN_NART: 本成员用于设置是否使用自动重传功能(ENABLE/DISABLE),使用自动重传功能时,会一直发送报文直到成功为止。

CAN_RFLM: 本成员用于设置是否使用锁定接收FIFO(ENABLE/DISABLE),锁定接收FIFO后,若FIFO溢出时会丢弃新数据,否则在FIFO溢出时以新数据覆盖旧数据。

CAN_TXFP: 本成员用于设置发送报文的优先级判定方法(ENABLE/DISABLE),使能时,以报文存入发送邮箱的先后顺序来发送,否则按照报文ID的优先级来发送。

  • 发送及接收结构体:CanTxMsg及CanRxMsg
/** 
  * @brief  CAN Tx message structure definition  
  */
typedef struct
{
  uint32_t StdId;  /*!< Specifies the standard identifier.
                        This parameter can be a value between 0 to 0x7FF. 
                        存储报文的标准标识符11位,0-0x7FF*/

  uint32_t ExtId;  /*!< Specifies the extended identifier.
                        This parameter can be a value between 0 to 0x1FFFFFFF. 
                        存储报文的扩展标识符29位,0-0x1FFFFFFF*/

  uint8_t IDE;     /*!< Specifies the type of identifier for the message that 
                        will be transmitted. This parameter can be a value 
                        of @ref CAN_identifier_type 
                        存储IDE扩展标志*/

  uint8_t RTR;     /*!< Specifies the type of frame for the message that will 
                        be transmitted. This parameter can be a value of 
                        @ref CAN_remote_transmission_request 
                        存储RTR远程帧标志*/

  uint8_t DLC;     /*!< Specifies the length of the frame that will be 
                        transmitted. This parameter can be a value between 
                        0 to 8 
                        存储报文数据段长度,0-8*/

  uint8_t Data[8]; /*!< Contains the data to be transmitted. It ranges from 0 
                        to 0xFF. 
                        存储报文数据段的内容*/
} CanTxMsg;

/** 
  * @brief  CAN Rx message structure definition  
  */
typedef struct
{
  uint32_t StdId;  /*!< Specifies the standard identifier.
                        This parameter can be a value between 0 to 0x7FF.
                        存储了报文的标准标识符11位,0-0x7FF */

  uint32_t ExtId;  /*!< Specifies the extended identifier.
                        This parameter can be a value between 0 to 0x1FFFFFFF. 
                        存储了报文的扩展标识符29位,0-0x1FFFFFFF*/

  uint8_t IDE;     /*!< Specifies the type of identifier for the message that 
                        will be received. This parameter can be a value of 
                        @ref CAN_identifier_type 
                        存储了IDE扩展标志*/

  uint8_t RTR;     /*!< Specifies the type of frame for the received message.
                        This parameter can be a value of 
                        @ref CAN_remote_transmission_request 
                        存储了RTR远程帧标志*/

  uint8_t DLC;     /*!< Specifies the length of the frame that will be received.
                        This parameter can be a value between 0 to 8 
                        存储了报文数据段的长度,0-8*/

  uint8_t Data[8]; /*!< Contains the data to be received. It ranges from 0 to 
                        0xFF. 
                        存储了报文数据段的内容*/

  uint8_t FMI;     /*!< Specifies the index of the filter the message stored in 
                        the mailbox passes through. This parameter can be a 
                        value between 0 to 0xFF 
                        存储了本报文是由经过筛选器存储进FIFO的,0-0xFF*/
} CanRxMsg;

在发送或接收报文时,需要往发送邮箱中写入报文信息或从接收FIFO中读取报文信息,利用STM32标准库的发送及接收结构体可以方便地完成这样的工作。

StdId: 本成员存储的是报文的11位标准标识符,范围是0-0x7FF。

ExtId: 本成员存储的是报文的29位扩展标识符,范围是0-0x1FFFFFFF。ExtId与StdId这两个成员根据下面的IDE位配置,只有一个是有效的。

IDE: 本成员存储的是扩展标志IDE位,当它的值为宏CAN_ID_STD时表示本报文是标准帧,使用StdId成员存储报文ID;当它的值为宏CAN_ID_EXT时表示本报文是扩展帧,使用ExtId成员存储报文ID。

RTR: 本成员存储的是报文类型标志RTR位,当它的值为宏CAN_RTR_Data时表示本报文是数据帧;当它的值为宏CAN_RTR_Remote时表示本报文是遥控帧,由于遥控帧没有数据段,所以当报文是遥控帧时,下面的Data[8]成员的内容是无效的。

DLC: 本成员存储的是数据帧数据段的长度,它的值的范围是0-8,当报文是遥控帧时DLC值为0

Data[8]: 本成员存储的就是数据帧中数据段的数据。

FMI: 本成员只存在于接收结构体,它存储了筛选器的编号,表示本报文是经过哪个筛选器存储进接收FIFO的,可以用它简化软件处理。

CAN_FilterInitTypeDef当需要使用CAN发送报文时,先定义一个上面发送类型的结构体,然后把报文的内容按成员赋值到该结构体中,最后调用库函数CAN_Transmit把这些内容写入到发送邮箱即可把报文发送出去。

接收报文时,通过检测标志位获知接收FIFO的状态,若收到报文,可调用库函数CAN_Receive把接收FIFO中的内容读取到预先定义的接收类型结构体中,然后再访问该结构体即可利用报文。

  • 筛选器结构体:
/** 
  * @brief  CAN filter init structure definition
  */
typedef struct
{
  uint16_t CAN_FilterIdHigh;         /*!< Specifies the filter identification number (MSBs for a 32-bit
                                              configuration, first one for a 16-bit configuration).
                                              This parameter can be a value between 0x0000 and 0xFFFF 
                                              CAN_FxR1寄存器的高16位*/

  uint16_t CAN_FilterIdLow;          /*!< Specifies the filter identification number (LSBs for a 32-bit
                                              configuration, second one for a 16-bit configuration).
                                              This parameter can be a value between 0x0000 and 0xFFFF 
                                              CAN_FxR1寄存器的低16位*/

  uint16_t CAN_FilterMaskIdHigh;     /*!< Specifies the filter mask number or identification number,
                                              according to the mode (MSBs for a 32-bit configuration,
                                              first one for a 16-bit configuration).
                                              This parameter can be a value between 0x0000 and 0xFFFF 
                                              CAN_FxR2寄存器的高16位*/

  uint16_t CAN_FilterMaskIdLow;      /*!< Specifies the filter mask number or identification number,
                                              according to the mode (LSBs for a 32-bit configuration,
                                              second one for a 16-bit configuration).
                                              This parameter can be a value between 0x0000 and 0xFFFF 
                                              CAN_FxR2寄存器的低16位*/

  uint16_t CAN_FilterFIFOAssignment; /*!< Specifies the FIFO (0 or 1) which will be assigned to the filter.
                                              This parameter can be a value of @ref CAN_filter_FIFO 
                                              设置经过筛选后数据存储到哪个接收FIFO*/
  
  uint8_t CAN_FilterNumber;          /*!< Specifies the filter which will be initialized. 
  											  筛选器编号,范围为0-27*/

  uint8_t CAN_FilterMode;            /*!< Specifies the filter mode to be initialized.
                                              This parameter can be a value of @ref CAN_filter_mode 
                                              筛选器模式*/

  uint8_t CAN_FilterScale;           /*!< Specifies the filter scale.
                                              This parameter can be a value of @ref CAN_filter_scale 
                                              设置筛选器的尺度*/

  FunctionalState CAN_FilterActivation; /*!< Enable or disable the filter.
                                              This parameter can be set either to ENABLE or DISABLE. 
                                              是否是能本筛选器*/
} CAN_FilterInitTypeDef;

CAN_FilterIdHigh: CAN_FilterIdHigh成员用于存储要筛选的ID,若筛选器工作在32位模式,它存储的是所筛选ID的高16位;若筛选器工作在16位模式,它存储的就是一个完整的要筛选的ID。

CAN_FilterIdLow: 类似地,CAN_FilterIdLow成员也是用于存储要筛选的ID,若筛选器工作在32位模式,它存储的是所筛选ID的低16位;若筛选器工作在16位模式,它存储的就是一个完整的要筛选的ID。

CAN_FilterMaskIdHigh: CAN_FilterMaskIdHigh存储的内容分两种情况,当筛选器工作在标识符列表模式时,它的功能与CAN_FilterIdHigh相同,都是存储要筛选的ID;而当筛选器工作在掩码模式时,它存储的是CAN_FilterIdHigh成员对应的掩码,与CAN_FilterIdLow组成一组筛选器。

CAN_FilterMaskIdLow: 类似地,CAN_FilterMaskIdLow存储的内容也分两种情况,当筛选器工作在标识符列表模式时,它的功能与CAN_FilterIdLow相同,都是存储要筛选的ID;而当筛选器工作在掩码模式时,它存储的是CAN_FilterIdLow成员对应的掩码,与CAN_FilterIdLow组成一组筛选器。

不同模式下各结构体成员的内容:

模式CAN_FilterIdHighCAN_FilterIdLowCAN_FilterMaskIdHighCAN_FilterMaskIdLow
32位列表模式ID1的高16位ID1的低16位ID2的高16位ID2的低16位
16位列表模式ID1的完整数值ID2的完整数值ID3的完整数值ID4的完整数值
32位掩码模式ID1的高16位ID1的低16位ID1掩码的高16位ID1掩码的低16位
16位掩码模式ID1的完整数值ID2的完整数值ID1掩码的完整数值ID2掩码完整数值

CAN_FilterFIFOAssignment: 本成员用于设置当报文通过筛选器的匹配后,该报文会被存储到哪一个接收FIFO,它的可选值为FIFO0或FIFO1(宏CAN_Filter_FIFO0/1)。

CAN_FilterNumber: 本成员用于设置筛选器的编号,即本过滤器结构体配置的是哪一组筛选器,CAN一共有28个筛选器,所以它的可输入参数范围为0-27。

CAN_FilterMode: 本成员用于设置筛选器的工作模式,可以设置为列表模式(宏CAN_FilterMode_IdList)及掩码模式(宏CAN_FilterMode_IdMask)。

CAN_FilterScale: 本成员用于设置筛选器的尺度,可以设置为32位长(宏CAN_FilterScale_32bit)及16位长(宏CAN_FilterScale_16bit)。

CAN_FilterActivation: 本成员用于设置是否激活这个筛选器(宏ENABLE/DISABLE)。

  • 7
    点赞
  • 48
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 18
    评论
从零开始进行STM32开发,需要以下几个步骤: 1. 硬件准备:选择一款适合自己的STM32芯片,购买相应的开发板和其他必要的配件。 2. 软件准备:下载并安装Keil MDK集成开发环境,选择一个合适的编译器版本,并下载并安装STM32库文件和CMSIS库文件。 3. 创建工程:在Keil MDK中创建一个新的工程,并选择适合自己的芯片型号。 4. 编写代码:使用C语言编写STM32开发代码,并添加必要的注释。代码的编写需要遵循STM32的编程规范和相关文档,同时需要结合具的硬件和需求进行编写。 5. 编译和下载:将代码编译为可执行文件,并下载到STM32开发板中进行调试和测试。 以下是一个简单的STM32开发代码示例及注释,供参考: ``` #include "stm32f10x.h" // 引入STM32库文件 int main(void) { GPIO_InitTypeDef GPIO_InitStructure; // 定义GPIO初始化结构 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); // 使能GPIOA时钟 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; // 配置GPIOA0引脚 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; // 设置为推挽输出 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // 设置最大输出速度 GPIO_Init(GPIOA, &GPIO_InitStructure); // 初始化GPIOA0引脚 while(1) { GPIO_SetBits(GPIOA, GPIO_Pin_0); // 将GPIOA0引脚输出高电平 Delay(500); // 延时500毫秒 GPIO_ResetBits(GPIOA, GPIO_Pin_0); // 将GPIOA0引脚输出低电平 Delay(500); // 延时500毫秒 } } void Delay(uint32_t nCount) // 定义延时函数 { uint32_t i; for(i=0;i<nCount;i++); } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 18
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

EnzoReventon

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值