[其他ST产品] 记录一次对STM32G4串口硬件FIFO的调试

[复制链接]
 楼主| 结合国际经验 发表于 2023-11-28 16:16 | 显示全部楼层
问题2: 如果一次性接收到的数据刚好是4的倍数,那么最后一轮数据发完触发的是RTO中断还是RXFT中断还是都有?

经过多次验证,接收完最后一个数据后只能产生一个中断,如果先判断有没有产生RTO标志就不会再处理RXFT的内容(但前提是RTOR寄存器的RTO是0,不然最后只可能是RXFT中断),如果先判断有没有产生RXFT标志就不会再处理RTO的内容。
 楼主| 结合国际经验 发表于 2023-11-28 16:16 | 显示全部楼层
先判断RTO且RTOR寄存器的RTO是0的例子:
  1. void USART1_IRQHandler(void)
  2. {
  3.   /* USER CODE BEGIN USART1_IRQn 0 */
  4.         if(__HAL_UART_GET_FLAG(&huart1, UART_FLAG_RTOF))
  5.         {
  6.                 __HAL_UART_CLEAR_FLAG(&huart1, UART_CLEAR_RTOF);
  7.                 SET_TEST2;                               
  8.                
  9.                 for(int i = 0; i < 8; i ++)
  10.                 {                       
  11.                         if(!__HAL_UART_GET_FLAG(&huart1, UART_FLAG_RXFNE))
  12.                         {
  13.                                 break;
  14.                         }
  15.                         rxBuf[rxCnt++] = USART1->RDR;
  16.                 }                                       
  17.                 RESET_TEST2;
  18.         }       
  19.         if(__HAL_UART_GET_FLAG(&huart1, UART_FLAG_RXFT))
  20.         {       
  21.                 SET_TEST0;               
  22.                                
  23.                 for(int i = 0; i < 8; i ++)
  24.                 {                       
  25.                         if(!__HAL_UART_GET_FLAG(&huart1, UART_FLAG_RXFNE))
  26.                         {
  27.                                 break;
  28.                         }
  29.                         rxBuf[rxCnt++] = USART1->RDR;
  30.                 }
  31.                 RESET_TEST0;
  32.         }
  33.   /* USER CODE END USART1_IRQn 0 */
  34.   HAL_UART_IRQHandler(&huart1);
  35.   /* USER CODE BEGIN USART1_IRQn 1 */

  36.   /* USER CODE END USART1_IRQn 1 */
  37. }


 楼主| 结合国际经验 发表于 2023-11-28 16:17 | 显示全部楼层
240526565a1f3a7905.png
先判断RXFT的例子:
void USART1_IRQHandler(void)
{
  /* USER CODE BEGIN USART1_IRQn 0 */
        if(__HAL_UART_GET_FLAG(&huart1, UART_FLAG_RXFT))
        {       
                SET_TEST0;               
                               
                for(int i = 0; i < 8; i ++)
                {                       
                        if(!__HAL_UART_GET_FLAG(&huart1, UART_FLAG_RXFNE))
                        {
                                break;
                        }
                        rxBuf[rxCnt++] = USART1->RDR;
                }
                RESET_TEST0;
        }
        if(__HAL_UART_GET_FLAG(&huart1, UART_FLAG_RTOF))
        {
                __HAL_UART_CLEAR_FLAG(&huart1, UART_CLEAR_RTOF);
                SET_TEST2;                               
               
                for(int i = 0; i < 8; i ++)
                {                       
                        if(!__HAL_UART_GET_FLAG(&huart1, UART_FLAG_RXFNE))
                        {
                                break;
                        }
                        rxBuf[rxCnt++] = USART1->RDR;
                }                                       
                RESET_TEST2;
    }
  /* USER CODE END USART1_IRQn 0 */
  HAL_UART_IRQHandler(&huart1);
  /* USER CODE BEGIN USART1_IRQn 1 */

  /* USER CODE END USART1_IRQn 1 */
}
 楼主| 结合国际经验 发表于 2023-11-28 16:17 | 显示全部楼层
864426565a2081a2c9.png

这个问题仅会出现在字节数刚刚好是4的倍数的情况,如果不是则两种代码的结果都是一样的。或许ST是有意这么设计的,防止最后出现两次中断,还是说我哪里没有考虑到,如果有朋友能解释一下,鄙人不胜感激。
 楼主| 结合国际经验 发表于 2023-11-28 16:17 | 显示全部楼层
三、总结
随着我们工作、学习的不断深入,会接触到越来越高级的芯片、越来越复杂的外设功能,不再像以前那样随便看两篇教程、看两集视频、复制一段代码就能调通,即使是使用CubeMX加HAL库也不会那么容易。往后需要我们自己熟读手册,了解每一位寄存器的作用,要是遇到手册说得不清楚或者自己无法理解的情况,还需要我们动手实践,自己去摸索它们大致的功能和作用。

要不然以后遇到没有参考的时候,就只能干瞪眼了。就算有参考,也建议大家自己调一遍,不要复制黏贴,不要怕浪费时间。就好比这篇文章,我相信会有人看完后拿着逻辑分析仪一遍一遍的尝试,但恐怕更多的还是复制代码,能用就行。

自己调通自己写驱动代码,我觉得这才是做BSP的核心和魅力所在。
童雨竹 发表于 2024-8-16 09:02 | 显示全部楼层

CPU借助于APB总线访问相关寄存器达到对I2C1工作模块的控制
Wordsworth 发表于 2024-8-16 10:05 | 显示全部楼层

ART2固定使用PCLK时钟,只有开启和关闭的问题,不存在其它时钟源选择
Clyde011 发表于 2024-8-16 11:08 | 显示全部楼层

一部分是I2C1的工作模块,另外一部分是其控制模块
公羊子丹 发表于 2024-8-16 12:01 | 显示全部楼层

控制模块的时钟仍然由外设时钟PCLK提供
万图 发表于 2024-8-16 13:04 | 显示全部楼层

USART1可以有多个时钟源
Uriah 发表于 2024-8-16 14:07 | 显示全部楼层

STM32CUBEMX配置生成初始化代码
帛灿灿 发表于 2024-8-16 16:03 | 显示全部楼层

通过访问寄存器来控制I2C1工作时钟的开启。
Bblythe 发表于 2024-8-16 17:06 | 显示全部楼层

I2C1的时钟可以自行选择HSI或者SYSCLK
周半梅 发表于 2024-8-16 19:02 | 显示全部楼层

I2C1工作时钟源选择;I2C1模块工作时钟的开启使能。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 在线客服 返回列表 返回顶部