|
有人使用STM32N6系列芯片的ADC模块时,发现通过 GPDMA 往内存搬运转换结果时,出现如下现象: 当DMA 的 Source Data Width 和 Destination Data Width 配置为 HalfWord 时,DMA 无法正常搬运 ADC 数据。 当两者配置为 Word 时,DMA 可以正常工作。 从眼前ADC分辨率角度看,转换结果有效位数小于等于 16位,基于应用经验认为 DMA 使用 HalfWord 数据宽度是不该有啥问题的。何况,事实上很多其它STM32系列也支持这样的配置,即源端和目的端的数据访问宽度都配置为Halfword。 为什么到这里就不行了呢? 看来有必要从STM32N6芯片的ADC外设相关的总线访问宽度找找原因,即从硬件接口层面找原因。 来,我们高举那盏名为耐心的灯,睁大双眼,一起游走于寄存器、时序图与文字段落构建的迷宫里,逐行逐段地叩问真相,心无旁骛。 功夫不负有心人,我们从STM32N6的参考手册中看到两处描述,可以作为问题的解释。 第一处: ADC 总线接口说明 手册里有这样的描述: Slave AHB interface The ADCs implement an AHB slave port for control/status register and data access. The features of the AHB interface are listed below: • Word accesses 该描述清晰地指出: ADC 通过AHB slave 接口对外提供寄存器及数据的访问; 该接口访问特性明确为字访问; 因此我们可以得知: ADC 作为AHB 从设备,各类主设备对ADC寄存器的访问粒度为 32 位字; DMA 作为总线主设备访问ADC 时,自然要遵循32位字访问粒度。 第二处: ADC 数据存储结构说明 在STM32N6系列参考手册里还可以看到如下描述: The converted data are stored into the eight 32-bit word FIFO accessible through the ADC_DR register. 该描述说明: ADC 转换结果不是简单存放在一个 16位或32位数据寄存器中, 转换结果首先进入一个 深度为 8 的 FIFO; FIFO 的每个条目的宽度为32位字; ADC_DR 其实是访问该 FIFO 的寄存器接口; 这意味着从硬件结构上看,ADC数据对外暴露的可访问原子单位是32位字,而非其它。 小结 对于STM32N6的ADC模块而言,虽然 ADC 的有效转换结果可能仅为 12 位或 16 位,但 DMA 是否能实现正常搬运,还取决于 ADC 数据接口是否允许以对应位宽访问。在这里,ADC 数据接口允许主设备访问的位宽明确要求为 32 位字。另外,ADC_DR 也不是一个普通静态数据寄存器。准确地说,它是 ADC内部FIFO 的读出映射寄存器。FIFO的每个元素为 32位,通过 ADC_DR 实施读取时,本质是在读取一个 FIFO 条目。 顺便提醒下,在使用STM32CubeMx配置STM32N6 ADC时,关于那个overrun behaviour的选项,目前请选择data overwriten,不要选择data preserved,不然基于STM32 HAL库代码进行ADC校准时会失败。初步估计库代码在这个地方的处理有点小bug,要待后续完善。 OK,今天的分享就到这里,下次再聊。 |
《STM32N6视频课程》学习笔记+STM32N6 AI Github仓库和软件包介绍总览
《STM32N6视频课程》学习笔记+STM32N6 ST EdgeAI tool工具介绍(三)
《STM32N6视频课程》学习笔记+STM32N6 ST EdgeAI tool工具介绍(二)
《STM32N6视频课程》学习笔记+STM32N6 ST EdgeAI tool工具介绍(一)
《STM32N6视频课程》学习笔记+STM32N6 ISP调试(二)
《STM32N6视频课程》学习笔记+STM32N6 ISP调试(一)
《STM32N6视频课程》学习笔记+使用STM32CubeMX生成STM32N6的ExtMemLoader, FSBL, Appli的一个LED点灯工程
《STM32N6视频课程》学习笔记+STM32N6 功耗测量
《STM32N6视频课程》学习笔记+STM32N6启动与调试技巧(三)
《STM32N6视频课程》学习笔记+STM32N6启动与调试技巧(二)
微信公众号
手机版