1. 从“瞎碰”到“搞通”:我的HC32L136 SPI DMA踩坑实录
大家好,我是老李,一个在嵌入式圈子里摸爬滚打了十多年的老码农。最近在做一个低功耗项目,主控选用了小华半导体(也就是大家常说的华大单片机)的HC32L136。这颗芯片性价比高,功耗控制得也不错,但在用它的SPI配合DMA发送数据时,我结结实实地掉进了一个大坑,折腾了将近两天。网上关于这颗国产MCU的实战资料不多,尤其是SPI DMA这种“进阶”应用,能找到的要么语焉不详,要么就是官方例程的简单复制,真遇到问题,还得自己摸着石头过河。
我当时的场景很简单,就是要驱动一块SPI接口的显示屏,需要高速、连续地发送大量显示数据。为了解放CPU,自然就想到了DMA。本以为配置好SPI和DMA通道,设置一下内存地址和外设地址,启动传输就完事了。结果呢?现象极其诡异:用逻辑分析仪抓波形,发现只有前两个字节的数据被正确发送出去了,从第三个字节开始,要么数据错了,要么时钟干脆就停了,后面的数据完全对不上号。我一开始怀疑是自己的底层配置有问题,反复检查时钟、引脚复用、SPI模式,甚至把官方库函数里里外外翻了个遍,问题依旧。
那感觉,就像你明明按照菜谱一步步做菜,出来的却是一盘“黑暗料理”。最后逼得没办法,只能静下心来,一字一句地去啃那份将近两千页的参考手册。这一看,才发现问题就出在一个非常关键,但手册描述又极易让人产生误解的概念上:DMA的触发方式。我最初错误地配置成了“软件触发”,而这恰恰是导致一切异常的根源。今天,我就把自己从“瞎碰”到“搞通”的全过程,以及过程中遇到的另一个“幽灵字节”的硬件小毛病,掰开揉碎了跟大家聊聊,希望能帮正在使用HC32L136的你,少走点弯路。
2. 核心迷思:软件触发 vs. 硬件触发,到底该怎么选?
相信很多朋友和我一开始的想法一样,觉得DMA触发嘛,无非就是两种:我代码里写一条命令让它开始,这叫软件触发;或者由某个外设(比如SPI的发送缓冲区空)自动产生一个信号让它开始,这叫硬件触发。为了图省事,我最初就选择了软件触发(配置为 DmaSWTrig)。心想,反正我控制发送时机,手动启动一下DMA通道,多直接。
但实测下来,这条路在HC32L136上根本走不通。 为什么?这得从小华半导体参考手册里那段让人有点“头大”的描述说起。手册里是这么讲的:SPI模块支持通过软件或硬件访问。同时,它又提到SPI的DMA传输“只支持硬件块传输模式”,并且当“SPI时钟和系统时钟不同频时,不支持硬件触发”。
看到这里,你是不是也懵了?我也是。我们来拆解一下这两个看似矛盾的说法:
- “只支持硬件块传输模式”:这里的“硬件块传输”指的是DMA控制器的一种工作模式(
DmaMskBlock),与我们说的“触发源”是两回事。它意味着DMA是以数据块为单位进行搬运的,这是配置DMA结构体时的enMode参数。 - “SPI时钟和系统时钟不同频时,不支持硬件触发”:这句话才是关键,也是最容易产生误导的地方。它这里的“硬件触发”,指的是一种非常具体的、由外设时钟域直接产生的触发信号。当SPI的通信时钟(比如2MHz)和内核的系统时钟(比如24MHz)不同源时,这种严格的“硬件触发”路径可能是不稳定或被禁用的。
那么问题来了,SPI作为通信外设,它的时钟(SCK)几乎百分之百和系统主频(HCLK)是不同的,否则波特率就固定死了。按字面意思理解,岂不是“硬件触发”完全不可用?那我们到底该用什么触发?
实践给出的答案是:用“硬件触发”,但不是手册里狭义理解的那种。 官方库函数里提供了一个枚举值 DmaSPI1TXTrig(对于SPI1发送)。当你把这个参数赋给DMA配置结构体的 enRequestNum 成员时,从代码角度看,你仍然需要调用 Dma_EnableChannel() 来启动一次传输,这似乎很“软件”。但实际上,这个调用只是“解锁”或“使能”了DMA通道,告诉DMA控制器:“SPI1的发送缓冲区空事件可以作为你的触发信号了”。真正的数据传输启动,是由SPI外设硬件在发送缓冲区空时,自动向DMA控制器发出请求而开始的。
所以,正确的理解链条应该是:
- 你配置DMA为硬件触发源(如
DmaSPI1TXTrig)。 - 你调用
Dma_EnableChannel()使能通道,此时DMA处于待命状态。 - SPI硬件一旦检测到发送缓冲区空,便自动拉响“警报”(触发信号),DMA控制器响应这个警报,开始搬运一个数据到SPI->DATA寄存器。
- SPI发送完这个数据,缓冲区又空了,再次触发DMA搬运下一个数据,如此循环,直到设定的传输计数完成。
这个过程,官方可能更倾向于称之为“硬件触发”或“外设触发”,因为它依赖外设的硬件事件。而我们手动调用 Dma_EnableChannel() 这个动作,更像是在扣动扳机前的“上膛”操作,真正的“开火”是自动的。
为了更直观,我把错误和正确的配置关键点做成了下面这个对比表格:


169

被折叠的 条评论
为什么被折叠?



