您的位置:首页 > 教育 > 锐评 > 营销服务机构_贸易类公司取名_谷歌安装器_灰色词网站seo

营销服务机构_贸易类公司取名_谷歌安装器_灰色词网站seo

2025/5/9 6:21:46 来源:https://blog.csdn.net/wallace89/article/details/147319392  浏览:    关键词:营销服务机构_贸易类公司取名_谷歌安装器_灰色词网站seo
营销服务机构_贸易类公司取名_谷歌安装器_灰色词网站seo

导言


在 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库一样。实验成功!!!

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com