【沧海拾昧】CAN总线通信——在STM32F10x标准库中

#C0405


沧海茫茫千钟粟,且拾吾昧一微尘

——《沧海拾昧集》@CuPhoenix


【阅前敬告】
沧海拾昧集仅做个人学习笔记之用,所述内容不专业不严谨不成体系
【如有问题必是本集记录有谬,切勿深究】


一、物理层连接

  • 低速 CAN 协议(ISO11519-2)支持 10k~125kbps 传输速率,高速 CAN 协议(ISO11898)支持 125K~125Mbps 传输速率,其物理层特征有差异,如 图1.1 所示,注意 120Ω 终端电阻必须只在端点设置,如果使用市售成品CAN 收发器模块,必须将中间节点上的 120Ω 电阻取下:
    在这里插入图片描述

    图 1.1 CAN 总线的物理连接

  • CAN 总线通信需要通过 CAN 控制器和 CAN 收发器共同实现,STM32 中内置有 CAN 控制器,但必须在外围电路中再设置有 CAN 收发器才可以驱动设备通过 CAN 总线进行通信,常用的 CAN 收发器(驱动 IC)包括:

表 1.1 CAN 总线的驱动 IC
低速CAN(ISO11519-2)高速CAN(ISO11898)
PCA82C252 / TJA1053 / SN65LBC032 等HA13721RPGE / PCA82C250 / Si9200 / CF15 等

二、采样点与波特率

1、基本概念

  • 每个二进制位可以分为同步段(Synchronization Segment,SS),传播段(Propagation Time Segment,PTS),相位缓冲段1(Phase Buffer Segment 1,PBS1)和 相位缓冲段2(Phase Buffer Segment 2,PBS2),其长度单位为 Tq(Time Quantum),Tq 是由 CAN 模块时钟分频后提供的最小时间单位。
  • 为便于使用,传播段(PTS)和相位缓冲段1(PBS1)合称位时间段1(TSEG1),在 STM32F10x 中记为 CAN_BS1;相位缓冲段2(PBS2)也可称为位时间段2(TSEG2),在 STM32F10x 中记为 CAN_BS2;位采样点位于 TSEG1 和 TSEG2 的交界处;
  • 再补偿同步宽度(SJW)直接影响到重同步时相位缓冲段的可调节的范围,SJW的值可以在1~4之间选择,选择 3~4 可以使总线获得更宽的波特率容忍度;

在这里插入图片描述

图 2.1 二进制位分解
  • 各个段允许的 Tq 数和具体功能如 表 2.1 所示:

在这里插入图片描述

表 2.1 段及其作用

2、波特率和采样点的计算

  • CAN 时钟 = CAN 时钟源 / CAN 分频系数,在 STM32F10x 中 APB1 桥的速度为 36MHz;
  • CAN 波特率 = CAN 时钟 / (SS + TSEG1 + TSEG2);
  • 可以注意到,位的总 Tq 数在 8~25Tq 之间,我们关注采样点的计算,如 图2.2 所示,总长度为 8Tq,其中 SS 段 1Tq,TSEG1 段4Tq,TSEG2 段 3Tq,因此采样点位置在第 5 个 Tq 后,即 62.5% 的位置;
img
图 2.2 采样点计算示例

:根据 CiA 协会(CAN in Automation)发布的 CANopen 协议的通信和应用层规范,推荐的采样点典型值为 87.5%。过早或过晚的采样可能导致刚好处于一个位的上升沿或者下降沿区间,进而导致数据识别错误。因此,CiA 建议波特率如 表2.2 所示。实际应用中,取 75%~85% 是一个较好的选择。

表 2.2 不同波特率下 CAN 总线通信配置的典型值

在这里插入图片描述

:较长的位时间会使得信号在总线上传播的时间更长,从而可能增加传输的噪声容忍度,这对长距离通信有利。而较短的位时间则适合较高的传输速率,但可能对噪声更为敏感。根据 CiA301 推荐,不同波特率对应的总线长度如 表2.3 所示。

表 2.3 不同波特率下 CAN 总线设置的最大长度

在这里插入图片描述

3、stm32f10x_can 中的实现

表 2.4 不同波特率下 CAN 总线通信在 stm32f10x 中的典型值
波特率位时间时钟源频率CAN_PrescalerCAN_BS1CAN_BS2CAN_SJW采样点位置
1 Mbps1 us36 MHz
800 kbps1.25 us36 MHz
500 kbps2 us36 MHz
250 kbps4 us36 MHz
125 kbps8 us36 MHz
50 kbps20 us36 MHz
20 kbps50 us36 MHz
10 kbps100 us36 MHz
  • 初始化结构体 CAN_InitTypeDef 的定义为:

    typedef struct {
      uint16_t CAN_Prescaler;   /*!< 指定时间段的长度,取值范围 [1, 1024]. */
      uint8_t CAN_Mode;         /*!< 指定 CAN 操作模式,该参数可以是 @ref CAN_operating_mode 的值 */
      uint8_t CAN_SJW;          /*!< 指定 CAN 硬件允许延长或缩短一位以执行重新同步的最大时间量,该参数可以是 @ref CAN_synchronisation_jump_width 的值 */
      uint8_t CAN_BS1;          /*!< 指定位段1中的时间量数量,该参数可以是 @ref CAN_time_quantum_in_bit_segment_1 的值 */
      uint8_t CAN_BS2;          /*!< 指定位段2中的时间量数量,该参数可以是 @ref CAN_time_quantum_in_bit_segment_2 的值 */ 
      FunctionalState CAN_TTCM; /*!< 启用或禁用时间触发通信模式,该参数应设置为 ENABLE 或 DISABLE. */
      FunctionalState CAN_ABOM; /*!< 启用或禁用自动总线关闭管理,该参数应设置为 ENABLE 或 DISABLE. */
      FunctionalState CAN_AWUM; /*!< 启用或禁用自动唤醒模式,该参数应设置为 ENABLE 或 DISABLE. */
      FunctionalState CAN_NART; /*!< 启用或禁用无自动重传模式,该参数应设置为 ENABLE 或 DISABLE. */
      FunctionalState CAN_RFLM; /*!< 启用或禁用接收 FIFO 锁定模式,该参数应设置为 ENABLE 或 DISABLE. */
      FunctionalState CAN_TXFP; /*!< 启用或禁用传输 FIFO 优先级,该参数应设置为 ENABLE 或 DISABLE. */
    } CAN_InitTypeDef;
    
    • CAN_Prescaler:CAN 预分频器,即 CAN 从时钟源 APB1 进行分频的分频系数,取值为 1~1024;
    • CAN_Mode:CAN 操作模式,可以取值为 CAN_Mode_Normal(正常模式(可以向总线发送或从总线接收)),CAN_Mode_LoopBack(环回模式(环回接收,可以向总线发送,不可从总线接收)),CAN_Mode_Silent(静默模式(不可向总线发送,可以从总线接收)),CAN_Mode_Silent_LoopBack(静默环回模式(环回接收,不可向总线发送,不可从总线接收));
    • CAN_SJW:SJW 段长度,可取值为 CAN_SJW_1tq ~ CAN_SJW_4tq;
    • CAN_BS1:TSEG1 段长度,可取值为 CAN_BS1_1tq ~ CAN_BS1_16tq;
    • CAN_BS2:TSEG2 段长度,可取值为 CAN_BS2_1tq ~ CAN_BS2_8tq;
    • CAN_TTCM:启用 / 禁用时间触发通信模式,当取值为 DISABLE 时,CAN 控制器采用标准的事件触发通信模式;当取值为 ENABLE 时,接收或发送帧起始位会被采样,并将时间戳存储到 CAN_RDTxR(接收定时器)或 CAN_TDTxR(发送定时器)中,用来表示消息发送和接收的时间,适用于要求精确同步的场景;
    • CAN_ABOM:启用 / 禁用自动总线关闭管理,ABOM 功能是节点检测到发送或接受错误累计超过一定阈值时,进入 Bus-Off(离线)状态,停止发送或接收任何 CAN 报文;当取值为 DISABLE 时,CAN 控制器不会自动从 Bus-Off 状态恢复,需要手动重启;当取值为 ENABLE 时,会自动重启并尝试重新连接到总线;
    • CAN_AWUM:启用 / 禁用自动唤醒模式,当取值为 DISABLE 时,CAN 控制器进入低功耗模式后不会自动唤醒;当取值为 ENABLE 时,如果 CAN 上出现数据传输,会自动唤醒控制器;
    • CAN_NART:启用 / 禁用自动重传机制,当取值为 DISABLE 时,启用自动重传功能,如果 CAN 总线发生错误,控制器会自动重新发送数据帧,直到成功发送或达到最大重传次数;当取值为 ENABLE 时,禁用自动重传功能,如果数据帧发送失败,控制器不会自动重传;
    • CAN_RFLM:启用 / 禁用接收 FIFO 锁定模式,当取值为 DISABLE 时,若 FIFO 队列已满,新的报文会覆盖原报文;当取值为 ENABLE 时,启用接收 FIFO 锁定模式,新报文会被直接丢弃,直到 FIFO 空出空间;
    • CAN_TXFP:启用 / 禁用传输 FIFO 优先级,当取值为 DISABLE 时,数据帧发送优先级根据 CAN_ID 决定,低 ID 的帧被优先发送;当取值为 ENABLE 时,启用基于时间戳的 FIFO 优先级,即发送队列中的帧根据其被添加的时间顺序进行优先发送,可以避免频繁的重排和冲突;

三、数据格式

1、基本概念

  • 帧包括数据帧(发送单元向接收单元传输)、遥控帧(接收单元主动向发送单元请求)、错误帧、过载帧、帧间隔,用户只能主动地使用数据帧与遥控帧,在 CANopen 协议中,用户仅使用数据帧;
  • 标准格式的数据帧包括如 图1.2 所示部分,:

在这里插入图片描述

图 3.1 CAN 总线的数据帧

在这里插入图片描述

图 3.2 CAN 总线的数据帧波形图实例(包括stuff bit)

其中各部分具体为:

名称功能或组成
帧起始(Start of Frame)CAN 帧传输的起始位
仲裁段(Arbitration)包括 11位 ID 标识符,和 远程请求位(RTR)指示是否为遥控帧
控制段(Control)包括 扩展标志位(IDE)指示是否为扩展格式,数据长度(DLC)指示数据段的字节数
数据段(Data)具有 1~8 字节有效数据
CRC 校验段(CRC)CRC 校验范围包括帧起始,仲裁段,控制段,数据段(硬件实现)
帧结束(End of Frame)-
位填充(stuff bit)若存在连续 5 位相同电平,则在第 6 位插入一位相反电平,用以提高数据传输的稳定性与准确性
  • 仲裁规则:在 CAN 控制器的 Tx 引脚发送数据时,同时监听 Rx 引脚,若发送为 1 但接收为 0,说明有 ID 更小的单元正在参与仲裁,此时该单元自动退出仲裁。

图 3.3 仲裁示例

2、stm32f10x_can 中的实现

  • CanTxMsg 发送消息结构体定义为:

    typedef struct {
      uint32_t StdId;  /*!< 标准 ID,取值范围 [0, 0x7FF]. */
      uint32_t ExtId;  /*!< 扩展 ID,取值范围 [0, 0x1FFFFFFF]. */
      uint8_t IDE;     /*!< 发送的消息的标识符类型。此参数可以是 @ref can_identifier_type 的值. */
      uint8_t RTR;     /*!< 发送的消息的帧类型。此参数可以是 @ref can_remote_transmission_request 的值. */
      uint8_t DLC;     /*!< 发送的帧的长度,取值范围 [0, 8]. */
      uint8_t Data[8]; /*!< 待发送的数据数组,取值范围在 uint8_t 范围内. */
    } CanTxMsg;
    
  • CanRxMsg 接收消息结构体定义为:

    typedef struct {
      uint32_t StdId;  /*!< 标准 ID,取值范围 [0, 0x7FF]. */
      uint32_t ExtId;  /*!< 扩展 ID,取值范围 [0, 0x1FFFFFFF]. */
      uint8_t IDE;     /*!< 接收的消息的标识符类型,此参数可以是 @ref can_identifier_type 的值. */
      uint8_t RTR;     /*!< 接收的消息的帧类型,此参数可以是 @ref can_remote_transmission_request 的值. */
      uint8_t DLC;     /*!< 接收的帧的长度,取值范围 [0, 8]. */
      uint8_t Data[8]; /*!< 接收的数据数组,取值范围在 uint8_t 范围内. */
      uint8_t FMI;     /*!< 存储在邮箱中的邮件通过的筛选器的索引,取值范围 [0, 0xFF]. */
    } CanRxMsg;
    
    • StdId:CAN 协议中的 11 位标准 ID,取值为 0~0x7FF,该值与 ExtId 互斥,当 IDE 取值为 CAN_Id_Extended 时该值无效;
    • ExtId:CAN 协议中的 29 位扩展 ID,取值为 0~0x1FFFFFFF,该值与 StdId 互斥,当 IDE 取值为 CAN_Id_Standard 时该值无效;
    • IDE:标识符类型,可以取值为 CAN_Id_Standard(标准 ID)或 CAN_Id_Extended(扩展 ID);
    • RTR:帧类型,可以取值为 CAN_RTR_Data(数据帧)或 CAN_RTR_Remote(遥控帧);
    • DLC:数据长度,取值为 0~8;
    • Data[8]:数据字段,最多 8 字节;
    • FMI:过滤器索引,读取接收到的消息的过滤器索引;

四、过滤器

1、基本概念

  • CAN 过滤器使用的目的:通过硬件过滤掉 ID 不符合要求的消息,降低软件处理成本(尤其是避免软件频繁进入中断);
  • 过滤器组:过滤器组间互相并联,只要消息能通过任一过滤器组,即可将 CAN 消息接收到 FIFO 中,STM32F103 系列配置有 14 个过滤器组;每个过滤器组中有两个 32 位寄存器 CAN_FxR1 和 CAN_FxR2;
  • 过滤器组的模式:过滤模式可配置为列表模式(List)或掩码模式(Mask),位宽可配置为 32 位或 16 位,即可组合成四种模式:1 个 32 位的掩码模式过滤器、2 个 32 位的列表模式过滤器、2 个 16 位的屏蔽模式过滤器、4 个 16 位的列表模式过滤器;
    • 列表模式:对 ID 的精确匹配;
      • 32 位列表模式:CAN_FxR1 存储过滤器 0 的标准值,CAN_FxR2 存储过滤器 1 的标准值;
      • 16 位列表模式:CAN_FxR1 的 [15:0] 存储过滤器 0 的标准值,[31:16] 存储过滤器 1 的标准值,CAN_FxR2 的 [15:0] 存储过滤器 2 的标准值,[31:16] 存储过滤器 3 的标准值;
    • 掩码模式:先将 ID 和掩码取与,然后再匹配(即只有掩码为 1 的位参与匹配);
      • 32 位掩码模式:CAN_FxR1 存储过滤器的标准值,CAN_FxR2 存储过滤器的掩码值;
      • 16 位掩码模式:CAN_FxR1 配置过滤器 0,其中 [31:16] 存储掩码值,[15:0] 存储标准值;CAN_FxR2 配置过滤器 1,其中 [31:16] 存储掩码值,[15:0] 存储标准值;

在这里插入图片描述

图 4.1 寄存器的使用

:值占据寄存器的高位,例如在 16 位列表模式下,标准帧 11 位 ID 应占据 16 位寄存器的高 11 位(即左移 5 位)。

  • 过滤器的关联:每组过滤器必须关联且仅能关联 1 个 FIFO(默认关联到 FIFO_0),每个 FIFO 中必须至少激活 1 个过滤器,才能收到报文;报文接受时,先与 FIFO_0 关联的过滤器进行比较,再与 FIFO_1 关联的过滤器进行比较,即若某报文同时满足 FIFO_0 / FIFO_1 过滤器的条件,会被接收到 FIFO_0 中;

2、stm32f10x_can 中的实现

  • 初始化结构体 CAN_FilterInitTypeDef 的定义为:

    typedef struct {
      uint16_t CAN_FilterIdHigh;            /* CAN_FxR1 寄存器的高 16 位. */
      uint16_t CAN_FilterIdLow;             /* CAN_FxR1 寄存器的低 16 位. */
      uint16_t CAN_FilterMaskIdHigh;        /* CAN_FxR2 寄存器的高 16 位. */
      uint16_t CAN_FilterMaskIdLow;         /* CAN_FxR2 寄存器的低 16 位. */
      uint16_t CAN_FilterFIFOAssignment;    /* 指定将分配给筛选器的 FIFO 编号,此参数可以是 @ref CAN_filter_FIFO 的值. */
      uint8_t CAN_FilterNumber;             /* 过滤器编号,取值范围 [0, 13]. */
      uint8_t CAN_FilterMode;               /* 过滤器模式,此参数可以是 @ref CAN_filter_mode 的值. */
      uint8_t CAN_FilterScale;              /* 过滤器位宽,此参数可以是 @ref CAN_filter_scale 的值. */
      FunctionalState CAN_FilterActivation; /* 启用或禁用过滤器,该参数应设置为 ENABLE 或 DISABLE. */
    } CAN_FilterInitTypeDef;
    
    • CAN_FilterIdHigh:CAN_FxR1 寄存器的高 16 位;
    • CAN_FilterIdLow:CAN_FxR1 寄存器的低 16 位;
    • CAN_FilterMaskIdHigh:CAN_FxR2 寄存器的高 16 位;
    • CAN_FilterMaskIdLow:CAN_FxR2 寄存器的低 16 位;
    • CAN_FilterFIFOAssignment:指定将分配给筛选器的 FIFO 编号,可以取值 CAN_Filter_FIFO0 或 CAN_Filter_FIFO1;
    • CAN_FilterNumber:过滤器编号,可以取值 0~13;
    • CAN_FilterMode:过滤器模式,可以取值 CAN_FilterMode_IdMask(掩码模式)或CAN_FilterMode_IdList(列表模式);
    • CAN_FilterScale:过滤器位宽,可以取值 CAN_FilterScale_16bit 或 CAN_FilterScale_32bit;
    • CAN_FilterActivation:启用或禁用过滤器,可以取值 DISABLE 或 ENABLE;

五、中断

  • STM32F10x 中与 CAN 总线通信有关的中断包括接收中断、发送中断和错误中断,具体包括:
USB_HP_CAN1_TX_IRQn					//	CAN1 发送中断
USB_LP_CAN1_RX0_IRQn 				//	CAN1 接收中断 0(用于 FIFO_0 数据读取)
CAN1_RX1_IRQn						//	CAN1 接收中断 1(用于 FIFO_1 数据读取)
CAN1_SCE_IRQn						//	CAN1 错误警告中断

所对应的中断服务函数分别为

USB_HP_CAN1_TX_IRQHandler
USB_LP_CAN1_RX0_IRQHandler
CAN1_RX1_IRQHandler
CAN1_SCE_IRQHandler
  • 发送中断:由下列事件产生
    • 发送邮箱 0 变为空,CAN_TSR 寄存器的 RQCP0 位被置 1;
    • 发送邮箱 1 变为空,CAN_TSR 寄存器的 RQCP1 位被置 1;
    • 发送邮箱 2 变为空,CAN_TSR 寄存器的 RQCP2 位被置 1;
  • FIFO0 接收中断:由下列事件产生
    • FIFO0 收到一个新报文,CAN_RF0R 寄存器的 FMP0 位不再是 00;
    • FIFO0 变为满,CAN_RF0R 寄存器的 FULL0 位被置 1;
    • FIFO0 发生溢出,CAN_RF0R 寄存器的 FOVR0 位被置 1;
  • FIFO1 接收中断:由下列事件产生
    • FIFO1 收到一个新报文,CAN_RF1R 寄存器的 FMP1 位不再是 00;
    • FIFO1 变为满,CAN_RF1R 寄存器的 FULL1 位被置 1;
    • FIFO1 发生溢出,CAN_RF1R 寄存器的 FOVR1 位被置 1;

在这里插入图片描述

图 5.1 CAN 相关中断

六、stm32f10x_can 中的函数(标准库函数)

1、反初始化函数

void CAN_DeInit(CAN_TypeDef* CANx);

2、初始化和配置函数

uint8_t CAN_Init(CAN_TypeDef* CANx, CAN_InitTypeDef* CAN_InitStruct);
  • 功能:初始化指定的 CAN 控制器,并根据 CAN_InitStruct 中的配置进行设置;

  • 返回值:0 - 初始化成功,1 - 初始化失败;

void CAN_FilterInit(CAN_FilterInitTypeDef* CAN_FilterInitStruct);
  • 功能:初始化指定的 CAN 过滤器,并根据 CAN_FilterInitStruct 中的配置进行设置;
void CAN_StructInit(CAN_InitTypeDef* CAN_InitStruct);
  • 功能:将 CAN_InitStruct 结构体初始化为默认值(TTCM、ABOM、AWUM、NART、RFLM、TXFP 均为 DISABLE,Mode 设置为正常模式, SJW = 1Tq,BS1 = 4Tq,BS2 = 3Tq,预分频系数为 1);
void CAN_SlaveStartBank(uint8_t CAN_BankNumber);
  • 该函数仅针对 STM32 连接线设备生效(即 STM32F105xx 和 STM32F107xx 系列);
  • 功能:配置从存储器的 CAN 过滤器(CAN2)的起始编号;
void CAN_DBGFreeze(CAN_TypeDef* CANx, FunctionalState NewState);
  • 该函数仅在处于调试模式时有效,用于在调试器暂停时控制 CAN 控制器的行为,如不使用调试功能,CAN 控制器不受该函数的影响;
  • 功能:使能或禁用 CAN 控制器的调试冻结功能;
void CAN_TTComModeCmd(CAN_TypeDef* CANx, FunctionalState NewState);
  • 功能:使能或禁用 CAN 控制器的时间触发通信模式;

3、发送功能函数

uint8_t CAN_Transmit(CAN_TypeDef* CANx, CanTxMsg* TxMessage);
  • 功能:通过指定的 CAN 控制器发送一条消息,消息以 TxMessage 结构体的形式提供;
  • 返回值:uint8_t transmit_mailbox,使用的发送邮箱编号(如果没有空邮箱,返回 CAN_TxStatus_NoMailBox );
uint8_t CAN_TransmitStatus(CAN_TypeDef* CANx, uint8_t TransmitMailbox);
  • 功能:获取指定发送邮箱的发送状态。当消息发送成功后,使用的邮箱会立即变为空状态;
  • 参数:uint8_t TransmitMailbox,指定发送邮箱的编号;
  • 返回值:如果发送成功,则返回 CAN_TxState_Ok,否则返回 CAN_TxStatus_Failed
void CAN_CancelTransmit(CAN_TypeDef* CANx, uint8_t Mailbox);
  • 功能:取消指定邮箱中的发送任务(手动释放邮箱);

4、接收功能函数

void CAN_Receive(CAN_TypeDef* CANx, uint8_t FIFONumber, CanRxMsg* RxMessage);
  • 功能:从指定的 FIFO 接收 CAN 消息;
  • 参数:uint8_t FIFONumber,指定的 FIFO 编号(从 CAN_receive_FIFO_number_constants 中取值,可取值为 CAN_FIFO0CAN_FIFO1);

:CAN_Receive 函数成功从 FIFO 接收 1 条消息后,会自动执行一次 CAN_FIFORelease 函数,不需要手动操作。如果通过中断方式进行接收,CAN_Receive 函数也会清空对应的 CAN_IT_FMRx 标志位,不需要手动清空。

void CAN_FIFORelease(CAN_TypeDef* CANx, uint8_t FIFONumber);
  • 功能:释放指定 FIFO 中的消息;

:每当软件对 RFOMx 位写 1 来释放 FIFO 时,对应的 FMPx 位减一,直到 FMPx = 0x00 的空状态。

uint8_t CAN_MessagePending(CAN_TypeDef* CANx, uint8_t FIFONumber);
  • 功能:检查 FIFO 中是否有待接收的消息;
  • 返回值:FIFO 的 message_pending 值;

:FIFO 状态包括五种可能,即

  • EMPTY:空状态,表示 FIFO 为空,此时 FMP 位(表示挂起的消息)为 0x00,溢出指示位 FOVR = 0;
  • PENDING_1:当 EMPTY 状态下接收到 1 条有效消息时,转为 PENDING_1 状态,FMP = 0x01, FOVR = 0;
  • PENDING_2:当 PENDING_1 状态下接收到 1 条有效消息时,转为 PENDING_2 状态,FMP = 0x10, FOVR = 0;
  • PENDING_3:当 PENDING_2 状态下接收到 1 条有效消息时,转为 PENDING_3 状态,FMP = 0x11(表示已满), FOVR = 0;
  • OVERRUN:溢出状态,当 PENDING_3 状态下接收到 1 条有效消息时,转为此状态,FMP = 0x11, FOVR = 1;

在这里插入图片描述

图 6.1 FIFO 状态的状态机

5、操作模式函数

uint8_t CAN_OperatingModeRequest(CAN_TypeDef* CANx, uint8_t CAN_OperatingMode);
  • 功能:切换 CAN 控制器的 CAN_Mode 模式,该值从 CAN_OperatingMode_TypeDef 中取值;
uint8_t CAN_Sleep(CAN_TypeDef* CANx);
  • 功能:使 CAN 控制器进入睡眠模式(停止 CAN 的时钟以降低功耗,但软件仍可以访问邮箱寄存器);
uint8_t CAN_WakeUp(CAN_TypeDef* CANx);
  • 功能:唤醒睡眠模式的 CAN 控制器;

6、错误管理函数

uint8_t CAN_GetLastErrorCode(CAN_TypeDef* CANx);
  • 功能:获取上次错误的错误代码,返回值在 CAN_Error_Code_constants 中取值(包括无错误、位填充错误、格式错误、ACK确认错误、CRC校验错误、位主导错误等错误代码);
uint8_t CAN_GetReceiveErrorCounter(CAN_TypeDef* CANx);
  • 功能:获取接收错误计数器的值。
uint8_t CAN_GetLSBTransmitErrorCounter(CAN_TypeDef* CANx);
  • 功能:获取传输错误计数器的值。

7、中断和标志管理函数

void CAN_ITConfig(CAN_TypeDef* CANx, uint32_t CAN_IT, FunctionalState NewState);
  • 功能:配置指定的 CAN 中断,其中中断源 CAN_IT 的取值可以是 CAN_interrupts 中的值;
  • CAN_interrupts 中的值包括:
    • 发送类中断:CAN_IT_TME(发送邮箱空);
    • 接收类中断:CAN_IT_FMP0( FIFO0 中有新消息待接收),CAN_IT_FF0( FIFO0 满),CAN_IT_FOV0( FIFO0 溢出),CAN_IT_FMP1( FIFO1 中有新消息待接收),CAN_IT_FF1( FIFO1 满),CAN_IT_FOV1( FIFO1 溢出);
    • 操作类中断:CAN_IT_WKU(从睡眠模式唤醒时触发),CAN_IT_SLK(控制器无法与其它设备保持同步时触发);
    • 错误类中断:CAN_IT_EWG(错误警告中断,表示正在经历较高的错误频率),CAN_IT_EPV(严重错误中断,但此时系统仍可以收发消息),CAN_IT_BOF(进入 Bus-off 离线状态时触发),CAN_IT_LEC(Last Error code 中断),CAN_IT_ERR(错误中断);
FlagStatus CAN_GetFlagStatus(CAN_TypeDef* CANx, uint32_t CAN_FLAG);
  • 功能:获得指定标志位的值,其中 CAN_FLAG 取值可以是 CAN_flags 中的值;
  • CAN_flags 中的值包括(具体缩写含义可参阅前文):
    • 发送类标志:CAN_FLAG_RQCP0CAN_FLAG_RQCP1CAN_FLAG_RQCP2
    • 接受类标志:CAN_FLAG_FMP0CAN_FLAG_FF0CAN_FLAG_FOV0CAN_FLAG_FMP1CAN_FLAG_FF1CAN_FLAG_FOV1
    • 操作模式标志:CAN_FLAG_WKUCAN_FLAG_SLAK(当 SLAK 中断被禁用时,无法对 SLAKI 进行轮询);
    • 错误类标志:CAN_FLAG_EWGCAN_FLAG_EPVCAN_FLAG_BOFCAN_FLAG_LEC
void CAN_ClearFlag(CAN_TypeDef* CANx, uint32_t CAN_FLAG);
  • 功能:清除指定标志位,其中 CAN_FLAG 取值可以是 CAN_flags 中的值;
ITStatus CAN_GetITStatus(CAN_TypeDef* CANx, uint32_t CAN_IT);
  • 功能:获取指定中断状态;
  • 返回值:若中断挂起,返回 SET,否则返回 RESET
void CAN_ClearITPendingBit(CAN_TypeDef* CANx, uint32_t CAN_IT);
  • 功能:清除指定中断挂起位;
    `(当 SLAK 中断被禁用时,无法对 SLAKI 进行轮询);
  • 错误类标志:CAN_FLAG_EWGCAN_FLAG_EPVCAN_FLAG_BOFCAN_FLAG_LEC
void CAN_ClearFlag(CAN_TypeDef* CANx, uint32_t CAN_FLAG);
  • 功能:清除指定标志位,其中 CAN_FLAG 取值可以是 CAN_flags 中的值;
ITStatus CAN_GetITStatus(CAN_TypeDef* CANx, uint32_t CAN_IT);
  • 功能:获取指定中断状态;
  • 返回值:若中断挂起,返回 SET,否则返回 RESET
void CAN_ClearITPendingBit(CAN_TypeDef* CANx, uint32_t CAN_IT);
  • 功能:清除指定中断挂起位;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值