历史上的今天
返回首页

历史上的今天

今天是:2025年07月09日(星期三)

正在发生

2019年07月09日 | 使用STM32hal库usart的接收中断分析及出现部分问题的解决

2019-07-09 来源:eefocus

最近开始使用ST的hal库,这个库相较于之前的标准库,优缺点兼具吧,hal库封装了更多底层的细节,我们可以很轻易的实现我们需要的功能,但是由于封装了太多的细节,导致一旦出问题,你就很难发现问题,内部调用的复杂让你觉得懵逼。


(一)hal库接收中断的分析

这几天在使用hal库的USART,其中用到的是接收中断,官方推荐的使用接收中断的方式是:在初始化函数上面先开启接收中断(这里就不介绍串口的配置,网上一大推,我就不给世界增加无谓的存储量了),开启的函数如下:


HAL_UART_Receive_IT(&huart2,(uint8_t*)aRxBuffer, 1);//该函数会开启接收中断:标志位UART_IT_RXNE,并且设置接收缓冲以及接收缓冲接收最大数据量

接着直接调用总的回调函数就可以了(这个函数的名称是定义好的),的:


void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)

{

 

if(huart->Instance==USART2)//判断,如果是串口2

    {

 

          //在这里写入自己要实现的代码

    }

}

其实使用回调函数的原理大概是这样的:MCU接收到数据产生中断,进入中断函数:


//串口中断服务程序

void USART1_IRQHandler(void)               

u32 timeout=0;

HAL_UART_IRQHandler(&UART1_Handler); //调用HAL库中断处理公用函数

   //省略部分代码

   /*

   代码

  */

}

也就是中断进入了HAL_UART_IRQHandler(&UART1_Handler);这个函数,这个函数是一个总的中断处理函数,也就是很多串口的中断处理最后都汇集到这个地方来处理。其实体如下:


void HAL_UART_IRQHandler(UART_HandleTypeDef *huart)

{

   /*

    省略一部分代码

  */

      UART_Receive_IT(huart);

  /*

    省略一部分代码

   */

}

而UART_Receive_IT(huart);的实现如下:


static HAL_StatusTypeDef UART_Receive_IT(UART_HandleTypeDef *huart)

{

 /*

    省略一部分代码

   */

      HAL_UART_RxCpltCallback(huart);

 /*

    省略一部分代码

   */

}

也就是说最后会调用到  HAL_UART_RxCpltCallback(huart);,我们在这个函数内部做自己的需求就好了。


(二) 为了效率出了问题

由上面的分析,我们可以知道,hal库的中断接收虽然很方便,但是是非常没有效率的,兜兜转转绕了一个大弯才能处理中断接收的数据。尤其是我使用的是STM32F0的芯片,频率只有48M,不比那些动不动就上百兆的芯片,这样的中断处理显然不能接受。


所以,借鉴于标准库,我想直接在串口中断函数(void USART2_IRQHandler(void))上直接处理函数,而不用在转一个圈跑到回调函数( HAL_UART_RxCpltCallback(huart))上处理。


然而,一改,问题就来了,一共遇到过两个问题。


(1)一进中断就出不来


由于不知道之前hal库在中断处理做了什么手脚,所以自己也忘了判断和清除中断标志,加上下面几句话就好了。


void USART2_IRQHandler(void)

{

     /* UART in mode Receiver ---------------------------------------------------*/

    if((__HAL_UART_GET_IT(&huart2, UART_IT_RXNE) != RESET) && (__HAL_UART_GET_IT_SOURCE(&huart2, UART_IT_RXNE) != RESET))

    {

      /*

      处理代码

      */

 

        /* Clear RXNE interrupt flag */ 

        __HAL_UART_SEND_REQ(&huart2, UART_RXDATA_FLUSH_REQUEST); //清除接收数据非空中断标志

    }

}

(2)一进入中断MCU就死机


这个问题是由于我在中断处理了大量的任务导致的死机,虽然我之前同样在别的芯片上这样处理而没有出现问题,不过以前用的芯片比我现在用的这款强大太多了,还是那句老话:不要在中断干太多的任务。你可以在中断完成一些标志,或者处理一下接收的数据(可以转存到别的数据,但记住不要用hal库的函数,卡死不负责)然后在回到主函数处理。比如:


 

void USART2_IRQHandler(void)

{

     /* UART in mode Receiver ---------------------------------------------------*/

    if((__HAL_UART_GET_IT(&huart2, UART_IT_RXNE) != RESET) && (__HAL_UART_GET_IT_SOURCE(&huart2, UART_IT_RXNE) != RESET))

    {

flag_text=1;  //中断标志

        /* Clear RXNE interrupt flag */ 

        __HAL_UART_SEND_REQ(&huart2, UART_RXDATA_FLUSH_REQUEST); //清除接收数据非空中断标志

    }

}

最后,祝自己和各位少遇bug



推荐阅读

史海拾趣

DMC Tools公司的发展小趣事

随着全球对环保问题的日益关注,DMC Tools公司也积极响应号召,致力于绿色生产。公司引进了先进的环保设备和技术,对生产过程中的废弃物进行无害化处理。同时,公司还积极推广绿色产品,帮助客户实现绿色生产。这种对环保的关注和投入不仅彰显了公司的社会责任感,也为公司赢得了良好的社会声誉。

DELTA公司的发展小趣事

面对全球能源危机和环保意识的提高,Delta公司敏锐地捕捉到了能源管理市场的巨大潜力。于是,公司开始积极拓展能源管理业务,通过系统集成与解决方案,帮助客户提升效能、降低运营成本与资本支出。Delta的能源管理业务涵盖了工业自动化、太阳能、风能、车用电子与通讯电源等多个领域,为全球客户提供了全方位的能源管理解决方案。

Armel Electronics Inc公司的发展小趣事

在电子行业中,技术更新迅速,创新是企业持续发展的动力。Armel Electronics Inc公司始终将研发创新作为公司的核心竞争力。公司不断投入资金,引进先进设备和技术,加强研发团队的建设。通过不断创新,Armel成功推出了一系列具有行业领先水平的新产品,为公司的持续发展提供了有力保障。

General Microcircuits Corp公司的发展小趣事
根据所需的信号频率和增益来选择具有足够GBW的运算放大器。
台湾富致(FUZETEC)公司的发展小趣事

除了在工业控制和汽车领域取得显著成就外,Futaba还将其技术延伸至休闲娱乐领域。公司开发的遥控飞机、车、船等产品,凭借其先进的无线遥控技术和卓越的性能表现,成为户外休闲运动的热门选择。特别是2.4G接收机的推出,进一步丰富了Futaba的产品线,满足了不同消费者的需求。在航模遥控器市场中,Futaba凭借其独特的技术优势和品牌影响力,占据了重要地位。这一领域的拓展不仅为公司带来了新的增长点,还进一步提升了Futaba在全球电子行业中的知名度和影响力。

Emerging Display Technolgies公司的发展小趣事

某新兴显示技术公司,专注于柔性显示技术的研发。随着市场对可折叠、可卷曲电子设备需求的增加,该公司投入巨资研发新一代柔性屏幕。经过数年的努力,他们成功开发出了具有超高柔韧性、清晰度和耐用性的显示屏。这一技术的突破,不仅为智能手机、平板电脑等移动设备带来了全新的形态设计,也为可穿戴设备、车载显示等领域提供了更多可能性。

问答坊 | AI 解惑

CE下普通应用开发是选择C还是高级的.NET(Java)合适?

公司有一定数量的普通应用开发,涉及到Socket或其它网络通信,而不是开发驱动程序,这种情况下的常见方案是否选择C/C++?…

查看全部问答>

不同的嵌入式开发板的区别

举个例子来引出我的问题 MX27 处理器以MX21 为基础进行设计,基于ARM926EJ-S s3c2410的处理器是ARM920T 请问各位 首先,之间有什么区别,是不是:1、处理器型号?2、寄存器地址不同?等等 大家能不能帮我说个大概? 其次,编程的时候是不是每 ...…

查看全部问答>

急!请教

请问:如何在虚拟机下的linux访问windows资源啊? 谢谢…

查看全部问答>

应急灯LED一致性测试

闲的无事,来测试一下LED的一致性怎么样,用应急灯的变压器输出18V,串联470欧电阻,5只LED串联,测量得5只LED压降分别为 3V   2.92V  2.92V  2.91V  2.87V   电流为6mA。以上参数供大家参考。…

查看全部问答>

阻抗匹配的问题

阻抗匹配仅适用于电子电路吗? 在电工电路中(即强电电路中)是否就不用考虑阻抗匹配?为什么?…

查看全部问答>

初学者,定制OS遇见个小问题

(CoreCon) Failed to connect debug message service! Please check the transport settings.(CoreCon) Transport service failed to connect(CoreCon) Error: A service has failed to connect. Make sure that all services are correctly config ...…

查看全部问答>

向tiankai001求助winavr+avrstudio C语言编译要求makefile问题

tiankai001你好,我正想学用avr,刚一上手就遇到编译问题,在avrstudio4环境下借助winavr用C编写程序, 要求makefile,不知怎么解决。在论坛里看到你在用winavr,希望能得到你的帮助,如何在avrstudio中用C 编译一个程序,如点亮一个LED,多谢!…

查看全部问答>

关于2011 年全国大学生电子设计竞赛复测事项的通知

本帖最后由 paulhyde 于 2014-9-15 03:48 编辑    …

查看全部问答>

关于MC52i的Internet通信

我在连接上internet之后,隔了大概2分钟,服务器发来的数据我的GPRS就收不到了数据了。而在这2分钟之内发数据是可以收到的。谁能帮我解答下这是什么原因啊? 还有就是,确认MC52i跟Internet还是连接的,没有断开,因为在这期间一直可以发送数据到 ...…

查看全部问答>