当前位置: 首页 > news >正文

STM32F103_HAL库+寄存器学习笔记18 - CAN接收溢出中断

导言


在 STM32F103 上使用 CAN 外设时,接收 FIFO 溢出(FOVR)并不是可忽略的小概率事件,而是一种可能导致严重后果的硬件行为。你需要持续监控并在溢出发生时及时处理,主要基于以下几点理由:

  1. 避免丢失关键报文
    CAN 总线常用于实时控制和安全相关场景(电机控制、车身网络、传感器数据采集等),一旦 FIFO 满后再进来的帧就会被硬件直接丢弃,不会再触发中断,也不会自动覆盖旧数据。丢失报文可能导致控制环路失稳或安全机制失效。
  2. 保持中断机制的正常运行
    当 FIFO 溢出标志(RF0R.FOVR0 或 RF1R.FOVR1)被置位后,如果不在中断服务中清除它,后续的接收中断往往会被“卡死”,因为硬件认为你还没处理上一次的溢出。及时检测并清除溢出标志,才能保证新的接收中断正常触发。
  3. 系统可观测性与调优依据
    将每次溢出事件记录下来(比如维护一个溢出计数器),可以让你了解系统在何种负荷或何种通信模式下容易发生瓶颈。基于这些数据,你可以:
  • 调整 CAN 波特率(降低总线负载)
  • 优化上层协议逻辑(限流、分帧、优先级)
  • 扩大应用层的接收缓存(如环形缓冲区ringbuffer)

总之,CAN接收FIFO1的溢出监控非常重要。

在这里插入图片描述
如上所示,根据《STM32F1中文参考手册》的章节22.8,通过寄存器CAN_IER可以打开FIFO1溢出中断。然后,在全局中断里查看寄存器CAN_RF1R的FOVR1是否被置1。
`在这里插入图片描述
如上所示,寄存器CAN_RF1R的FOVR1的说明。

项目地址:

  • HAL库:https://github.com/q164129345/MCU_Develop/tree/main/stm32f103_hal_library18_Can_Rec_Overflow_Error
  • 寄存器方式:https://github.com/q164129345/MCU_Develop/tree/main/stm32f103_ll_library18_Can_Rec_Overflow_Error

一、代码(HAL库)


1.1、HAL库对接收FIFO的溢出中断支持不足

在这里插入图片描述
如上所示,FIFO1溢出中断并没有像接收中断一样(HAL_CAN_RxFifo1MsgPendingCallback()),另外,有一个对应的函数名给我们去使用。错误类型的中断,全部统一用HAL_CAN_ErrorCallback()

几番调试后发现HAL_CAN_ErrorCallback()也不行,FIFO1溢出中断产生的时候,不会进入HAL_CAN_ErrorCallback()。所以决定不用HAL库的函数HAL_CAN_ErrorCallback()!!!

1.2、myCanDrive.c

在这里插入图片描述
在这里插入图片描述
如上所示,在全局中断函数CAN1_RX1_IRQHandler()里调用自己编写的FIFO1接收溢出中断处理函数CAN_FIFO1_Overflow_Handler()。函数CAN_FIFO1_Overflow_Handler()的目的很简单,只是将全局变量g_RxOverflowError累加。通过全局变量g_RxOverflowError等于10的话,证明有10个CAN消息被丢掉了,丢掉的原因是FIFO1满了,导致接收溢出。

实际项目上,我们就是通过全局变量g_RxOverflowError来监控CAN接收的情况。如果有接收溢出的话,证明我们应调整CAN接收过滤器。让那些我们不关心的CAN报文禁止进入接收FIFO1。

1.3、myCanDrive.h

在这里插入图片描述

1.4、stm32f1xx_it.c

在这里插入图片描述

二、测试(HAL库)


2.1、编译代码

在这里插入图片描述
如上所示,代码编译成功。

2.2、debug测试

在这里插入图片描述
如上所示:

  1. 程序初始化后,使用CAN分析仪发送4个CAN报文到CAN总线上,立刻触发了STM32F103的接收FIFO1溢出中断。
  2. 在Keil的debug模式下,观察System Viewer->CAN->CAN_RF1R,看到FOVR1被置1(FIFO1溢出了)、看到FULL1被置1(FIFO1满了,没有空闲的接收邮箱)、看到FMP1 = 3(FIFO1的三个邮箱都有CAN报文)。
  3. 调试断点卡在函数CAN_FIFO1_Overflow_Handler()里。
    在这里插入图片描述
    如上所示,云释放函数CAN_FIFO1_Overflow_Handler()里的断点后,全局变量g_RxOverflowError从0变成1,表示FIFO1接收溢出了(丢失了)一条CAN报文。
    总的效果如下:
    在这里插入图片描述

三、代码(寄存器方式)


3.1、myCanDrive_reg.c

在这里插入图片描述
函数CAN_Config()里,将代码CAN1->IER |= CAN_IER_FMPIE1;注释掉,方便触发FIFO1溢出中断。接着,通过代码CAN1->IER |= CAN_IER_FOVIE1;开启FIFO1溢出中断。
在这里插入图片描述
为了让代码更加模块化,将FIFO1溢出中断处理与之前的FIFO1挂号中断处理都各自编写一个函数来处理。
在这里插入图片描述
在全局中断里,根据标志位判断到底是什么中断,根据中断标志进行处理。

四、测试(寄存器方式)


4.1、编译代码

在这里插入图片描述

4.2、debug测试

在这里插入图片描述
在这里插入图片描述
总的来说,效果跟HAL库一样。但是,寄存器的代码精简很多,效率最高。
在这里插入图片描述
如上所示,效果跟HAL库一样。实验成功!!!

相关文章:

  • win10 应用市场 开发
  • 【java 13天进阶Day04】常用API、正则表达式,泛型、Collection集合API
  • P10416 [蓝桥杯 2023 国 A] XYZ
  • 关于yarn和hadoop
  • STM32 HAL库 Freertos队列使用解析
  • 深入理解红黑树:原理、实现与应用
  • 02.diboot项目分析
  • 【数据结构与算法】——插入排序
  • 论文阅读:2023 arxiv Safe RLHF: Safe Reinforcement Learning from Human Feedback
  • Spring Boot日志系统详解:Logback与SLF4J的默认集成
  • iOS Facebook 登录
  • CentOS7执行yum命令报错 Could not retrieve mirrorlist http://mirrorlist.centos.org
  • 【刷题Day19】HTTP的各个版本(浅)
  • iOS Google登录
  • 2025妈妈杯数学建模B题完整分析论文
  • 【全部更新】2025妈妈杯D题1-4问mathercupD题数学建模挑战赛D题数学建模思路代码文章教学短途运输货量预测及车辆调度问题
  • 2025MathorcupD题 短途运输货量预测及车辆调度问题 保姆级教程讲解|模型讲解
  • 36V转2.8V3A同步降压恒压WT6043A
  • 下载HBuilder X,使用uniapp编写微信小程序
  • 数控机床中滚珠导轨的作用是什么?
  • 云南蒙自:一汪南湖见证近代开埠史与西南联大的弦歌不绝
  • 2025年一季度上海市生产总值
  • 特朗普称或将“大幅降低”对华关税,外交部:打,奉陪到底;谈,大门敞开
  • 外媒:特朗普称或将“大幅降低”对中国的关税
  • 神二十航天员公布
  • 白宫新闻秘书:美政府将在法庭上回应哈佛大学诉讼