0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

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

茶话MCU 来源:茶话MCU 2023-01-08 11:16 次阅读

有人使用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库组织代码和基于汇编指令组织代码实现相同功能时,对我们自身的挑战及相应的收获是不可同日而语的。








审核编辑:刘清

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • dma
    dma
    +关注

    关注

    3

    文章

    559

    浏览量

    100411
  • HAL库
    +关注

    关注

    1

    文章

    114

    浏览量

    6168
  • stm32h7
    +关注

    关注

    0

    文章

    37

    浏览量

    1753

原文标题:STM32 DMA编程时的一个应用小提醒

文章出处:【微信号:stmcu832,微信公众号:茶话MCU】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    求助,关于HALHAL_UART_Receive使用问题求解

    各位好,我在使用HALHAL_UART_Receive()函数时遇到了这样的问题,在第一次使用HAL_UART_Receive()进行接
    发表于 04-10 07:25

    如何使用HAL实现不定长UART数据包的DMA接收?

    ;; ART_HandleTypeDef huart1; HAL_UART_Receive_DMA( huart1,rxbuf,sizeof(rxbuf)); 函数原型如下: /** * @briefReceives
    发表于 04-30 06:27

    stm32f103 + HAL + UART + DMA + UCOS III数据发送问题

    目的:stm32f103 + HAL + UART + DMA实现调试日志打印输出功能。实现
    发表于 08-02 10:10

    STM32 HAL使用带DMA的ADC会影响UART传输

    , adc_dma_values, 2);UART传输发送正确的数据。当我HAL_UART_Transmit_IT()用HAL_UART_T
    发表于 09-18 15:17

    STM32 HAL UART发送DMA问题

    4; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); /* UART4 DMA Init */ /* UART4_TX Init
    发表于 09-27 14:13

    请问HAL_UART_Receive_DMAHAL_UART_Transmit_DMA怎么用

    HAL_UART_Receive_DMA HAL_UART_Transmit_DMA通过UART接受数据,难道要写一个 HAL_UART_Transmit_DMA 不停的轮询吗? 除了
    发表于 11-16 08:43

    stm32f103+HAL+UART+DMA+UCOS III数据发送没有进入UART_TX_DMA中断服务函数

    目的:stm32f103 + HAL + UART + DMA实现调试日志打印输出功能。实现
    发表于 12-28 09:09

    HALSPI DMA的使用问题

    使用了HAL的函数来进行数据的读写:HAL_StatusTypeDef HAL_SPI_TransmitReceive_DMA(SPI_HandleTypeDef *hspi, ui
    发表于 04-01 11:47

    求大佬分享HALSPI DMA UART驱动开发的程序

    求大佬分享HALSPI DMA UART驱动开发的程序
    发表于 12-03 07:53

    stm32 HAL实现UART的不定长数据DMA接收的方法

    发送接收就显得十分必要了,因为串口中断每收到一个byte的数据就会发生中断,这样会非常的消耗单片机的资源。而DMA接受一帧数据才会发生中断,可以极大的节省单片机的资源。STM32中的代码使用HAL
    发表于 01-20 08:07

    在STM32H753ZI上使用DMAUART获取HAL_DMA_ERROR_TE出现传输错误怎么解决?

    _PRIORITY_MEDIUM;hdma_uart5_tx.Init.FIFOMode = DMA_FIFOMODE_DISABLE; HAL_DMA_Init(&hdma_uart
    发表于 01-03 08:08

    HAL_UART_Transmit_DMA传输问题求解

    目前我正在研究 UART DMA,在通过 DMA UART 传输数据后遇到了问题。在 1 次成功的数据
    发表于 01-04 07:06

    HAL_UART_Receive_DMA 随机停止工作怎么处理?

    HAL_UART_Receive_DMA 以开始新的传输。我这样做(而不是使用循环模式),以便我可以通过计算 512 字节的完整“帧”数并添加 (512 - CNDTR) 来计算传输
    发表于 01-09 07:56

    FreeRTOS中的HAL_UART_Transmit_DMA问题如何处理?

    得不到。第二个 DMA 语句无法运行,因为 HAL_UART_GetState(&UART_Handle_Console) 一直忙于 TX。以上是我的测试代码。我的目的是使用二进制信号
    发表于 01-09 08:15

    STM32 HAL UART 串口读写功能笔记

    STM32L0 HAL UART 串口读写功能串口发送功能:uint8_t TxData[10]= “01234abcde”;HAL_UART_Transmit(&huart2
    发表于 12-27 19:11 13次下载
    STM32 <b class='flag-5'>HAL</b><b class='flag-5'>库</b> <b class='flag-5'>UART</b> 串口读写功能笔记