HAL库无法实现UART的DMA传输真是这样吗?

发布时间:2024-03-18  

有人使用STM32H7芯片做些事情,发现基于ST公司的HAL库开发UART1的DMA收发时可以轻松实现,而当使用ST的LL库组织代码时,却没法实现UART的DMA传输。

感觉上就是使用HAL库编写代码功能正常而基于LL库则不行。真是这样吗?

使用STM32CubeMx进行图形化配置,并生成基于HAL库的初始代码,要实现UART收发功能的DMA传输的话,除了安排好的收发缓冲内存外,再就只需调用下面两个HAL库的API函数即可进行功能验证。

a21e7c38-8e71-11ed-bfe3-dac502259ad0.png

从功能实现上讲,使用HAL库及相应API还是很方便、很简单的。每个API函数就像个黑盒子,对于里面的内容,如果你不点进去阅读是不会知晓的。

不过,建议尽可能地多点进去瞧瞧,那里往往别有洞天。

如果基于LL库来组织代码的话,先使用STM32CubeMx进行配置并生成基于LL库的初始化代码。

a230b31c-8e71-11ed-bfe3-dac502259ad0.png

a241dff2-8e71-11ed-bfe3-dac502259ad0.png

基于CubeMx配置完毕后生成初始化工程,准备收发缓冲内存,然后添加用户代码。

刚开始用户代码是这样编写安排的。见下面代码截图。

a2504d94-8e71-11ed-bfe3-dac502259ad0.png

上图中A处代码的作用就是开启两个DMA stream的功能,即对相关DMA Stream的控制寄存器的使能位进行使能置1。

编译无错后运行代码,可是根本没有数据的收发动作发生。看来,跟反馈者的症状一样。

没办法,硬着头皮核查代码。除了核查我添加的用户代码外,还核查UART及DMA的初始化代码。看来看去,似乎该有的都有了,该写的都写了。

后来,根据代码里涉及到的寄存器去跟STM32H7手册里寄存器做比较阅读。

在查看DMA各个stream配置控制寄存器【DMA_SxCR】内容时,突然发现并想起了点什么。

其实也是之前在别的DMA应用场合也碰到过的类似问题。

下面为该寄存器的内容布局截图。

a27c309e-8e71-11ed-bfe3-dac502259ad0.png

隐约记得,该DMA Stream或Channel的控制使能位为0时才能做DMA相关其它参数的配置的。

我们可以在手册里找到针对该位的明确描述:

a28984c4-8e71-11ed-bfe3-dac502259ad0.png

这里的意思是说,要想让某DMA stream工作,必须令该EN位为1。

不过,当该EN位为1时时,是不允许对DMA及相应FIFO寄存器做配置的。

换言之,若要针对某Stream做DMA相关配置,得先让该控制寄存器的EN位保持为0状态。

而在我的用户代码里,对EN位写1操作则放在了对DMA做各种配置的前面,即上面代码截图的A处。

a29a48cc-8e71-11ed-bfe3-dac502259ad0.png

a2a4da3a-8e71-11ed-bfe3-dac502259ad0.png

既然这样,我们把对DMA控制寄存器EN位的置1操作放在其它DMA相关配置之后就应该可以了,即从上面代码截图中的A处拉到B处。

然后,进行测试,结果果真正常了。

其实就是一个配置代码顺序问题,卡了半天。

如果不是用LL库而是用HAL库可能就不太容易碰到这个问题。前面说过了,基于HAL库的API函数像个黑盒子,它帮我们处理了很多细节性、判断性的东西。

基于LL库组织的代码,相比HAL库组织的代码,代码精简、流程清晰、运行高效。不过,使用LL库做开发需要开发者对芯片各个模块的工作原理,操作流程有更清晰、更精准的了解,同时往往还需要开发者对应用相关的寄存器有更细致、深入的把握。

而HAL库往往事先帮我们充分考虑到了基于硬件需求的操作流程、时序,基于软件层面的诸多事件及状态的互斥管理,以及不同STM32系列的代码兼容性,并做了很好、很全面的封装。

所以我们在利用HAL库来实现相应功能时,往往无须对操作流程、时序以及寄存器本身做过多的了解就可以完成。

从开发角度讲,利用HAL库往往比利用LL库能更快地完成任务,同时基于HAL库的代码也有更好的移植性,代价就是代码相对LL库要庞大些。

对应STM32开发者而言,即使基于HAL库开发了一些STM32项目,对于芯片的诸多功能细节以及寄存器的了解往往可能比较有限。当然,这点因人而异吧,不可说死。

对于HAL库和LL库的选用,我们每个人可以根据自身情况来。比方,对芯片软硬件不熟悉时、任务紧急时先使用HAL库,等对芯片及库函数熟悉、任务不紧急时可以切换到LL库。

或者说,只是做些功能性验证确认,使用HAL库组织代码也是非常快捷方便的。

当然,一个工程里HAL库、LL库是可以同时并存的。另外,当我们对芯片寄存器、内核指令系统足够熟悉时,甚至可以尝试使用汇编语言做MCU编程开发。

作为开发人员,基于HAL库组织代码和基于汇编指令组织代码实现相同功能时,对我们自身的挑战及相应的收获是不可同日而语的。


文章来源于:电子工程世界    原文链接
本站所有转载文章系出于传递更多信息之目的,且明确注明来源,不希望被转载的媒体或个人可与我们联系,我们将立即进行删除处理。

相关文章

    STM32CubeMX之串口接收不定长数据;基本串口通信通常只能接收到定长数据,无法稳定接收不定长数据,本章介绍利用STM32单片机的IDLE空闲中断,接收不定长数据。 使能串口1的异......
    工程师笔记 | 使用UART IDLE中断接收不定长数据;前言 在串口通信过程中,我们常常用到接受和发送中断,相信大家都不陌生。这里还有另一个非常有用的中断可能被大家所忽略,即总线空闲状态IDLE......
    STM32CUBEMX(8)--USART通过定时器中断方式接收不定长数据;概述 本文利用中断实现串口不定长接收(非DMA),使用HAL库,将接收的数据打印出去。 DMA接收请查看:https......
    ,在主程序中判断一帧数据的接收完成并处理。测试结果就不贴了。 4.总结 上面几种方式都可以实现串口接收不定长数据,各有优缺点,可根据实际需求选择用哪种。需要注意的是,上面的例程只是简单地接收数据......
    STM32 HAL库串口收发如何使用;前言 对于 STM32 串口的使用,确实很简单使用 STM32CubeMX 做好初始化,就可以直接使用了。 但是最近在某些产品上使用串口同时收发的时候,发现有时候串口会收不到数据......
    三种串口接收不定长数据方法详解; 方法1:串口接受数据,定时器来判断超时是否接受数据完成。 方法2:DMA接受+IDLE中断 实现思路:采用STM32F103的串口1,并配置成空闲中断IDLE模式......
    STM32单片机接收不定长度字节数据的方法解析;今天说一下STM32单片机的接收不定长度字节数据的方法。由于STM32单片机带IDLE中断,所以利用这个中断,可以接收不定长字节的数据,由于STM32......
    STM32串口接收不定长数据:采用标志位(比如0X0D,0X0A)结束法;缺点:有些情况下会导致数据丢失(可能返回数据中0x0d、0a本身为有效数据) 适用:约定协议的数据帧(发送数据的设备必须以相应的约定字节作为一次数据......
    STM32CUBEMX(6)--移植雅特力AT32F403AVGT7,双串口通过DMA方式接收不定长数据;概述 本篇文章主要介绍如何使用STM32CubeMX移植到雅特力AT32F403AVGT7......
    来获取当前发送状态,从而进行相关处理。3. 接收数据串口接收数据也需要进行初始化,并设置相关参数。HAL库提供了两个基本函数:`HAL_UART_Receive`和......

我们与500+贴片厂合作,完美满足客户的定制需求。为品牌提供定制化的推广方案、专属产品特色页,多渠道推广,SEM/SEO精准营销以及与公众号的联合推广...详细>>

利用葫芦芯平台的卓越技术服务和新产品推广能力,原厂代理能轻松打入消费物联网(IOT)、信息与通信(ICT)、汽车及新能源汽车、工业自动化及工业物联网、装备及功率电子...详细>>

充分利用其强大的电子元器件采购流量,创新性地为这些物料提供了一个全新的窗口。我们的高效数字营销技术,不仅可以助你轻松识别与连接到需求方,更能够极大地提高“闲置物料”的处理能力,通过葫芦芯平台...详细>>

我们的目标很明确:构建一个全方位的半导体产业生态系统。成为一家全球领先的半导体互联网生态公司。目前,我们已成功打造了智能汽车、智能家居、大健康医疗、机器人和材料等五大生态领域。更为重要的是...详细>>

我们深知加工与定制类服务商的价值和重要性,因此,我们倾力为您提供最顶尖的营销资源。在我们的平台上,您可以直接接触到100万的研发工程师和采购工程师,以及10万的活跃客户群体...详细>>

凭借我们强大的专业流量和尖端的互联网数字营销技术,我们承诺为原厂提供免费的产品资料推广服务。无论是最新的资讯、技术动态还是创新产品,都可以通过我们的平台迅速传达给目标客户...详细>>

我们不止于将线索转化为潜在客户。葫芦芯平台致力于形成业务闭环,从引流、宣传到最终销售,全程跟进,确保每一个potential lead都得到妥善处理,从而大幅提高转化率。不仅如此...详细>>