This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] LP-MSPM0C1104:首次触发后、DMA 未通过 ADC12 序列转换进行更新

Guru**** 2576215 points
Other Parts Discussed in Thread: SYSCONFIG

请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/1570150/lp-mspm0c1104-dma-not-updating-with-adc12-sequence-conversions-after-first-trigger

器件型号:LP-MSPM0C1104
主题:SysConfig 中讨论的其他器件

工具/软件:

我尝试在 MSPM0 器件上通过 DMA 读取 12 位 ADC 的结果。

ADC 由 Timer0 零事件触发、该事件每秒发生一次(计时器周期= 1000ms)。
在每次触发时、ADC 执行 A 非重复通道序列转换 在 3 个 ADC 通道之间(配置的 MEM0、MEM1、MEM2)。

序列完成后、ADC 会将MEM2_RESULT_LOADED中断置为有效。 然后、这应该会触发 DMA、DMA 配置为将 ADC MEMx 寄存器的结果传输到数组中。

问题:

  • 然后进行传输 只是第一次 计时器达到零。

  • 每次后续 DMA 传输始终包含相同的第一组值、即使物理输入信号发生变化(例如,通道连接至 GND)也是如此。

  • 如果我禁用 DMA 而不是使用 ADC 中断处理程序手动读取 MEMx 结果、则每个触发器的值都会正确更新。

我检查过的内容/观察结果:

  • ADC 序列本身正在工作并产生新的结果(通过 ISR 进行验证)。

  • DMA 通道已准备就绪、中断按预期触发(发生 DMA_DONE)。

  • 但是、在第一次触发后、目标缓冲区永远不会使用新的转换进行更新。

  • 缓冲区是一个 32 位数组、DMA 配置用于半字传输(可能的宽度不匹配?)。

  • 源增量当前已启用(可能是错误的,因为所有结果都来自固定的 ADC MEM 寄存器)。

  • 启用 ADC 后初始化 DMA - ADC 启用顺序与 DMA 设置顺序是否相关?

所以它似乎是一个 ADC12 DMA 触发与 DMA 通道设置之间的配置不匹配(宽度,增量,初始化序列) 而不是 ADC 问题。

请确认 针对多通道 ADC 序列的 DMA 的预期配置 (例如 srcIncrement,传输宽度,初始化顺序)?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    这听起来 DMA 没有启用 (DL_DMA_enableChannel())。

    您能否显示用于(重新)布防转换序列的序列? 也许有一条线索。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Jo:
    您是否可以尝试在 while 循环中重置源地址和目标地址? 如果地址更新不正确、这可能有所帮助。 此外、您是否对 Timer0 使用连续计时器和向下计数?

    此致、

    Diego Abad

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    迪戈说的。 在非重复传输之后、源/目标地址保持原样;只有在重复传输之后、它们才会恢复为原始值。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我不确定我是否正确理解您的建议。 在 SysConfig 中、我将 DMA 配置为块到块传输、递增模式、半字数据长度和块传输模式。 那么我应该手动设置每次传输的目标地址和源地址(使用 DL_DMA_SetSrcAddr 和 DL_DMA_SetDestAddr)?  

    我对 Timer0 使用定期向下计数计时器。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    是的、您应  在 DL_DMA_enableChannel 调用之前再次调用 DL_DMA_SetDestAddr(可能还有 DL_DMA_SetSrcAddr)。 或者、您可以使用源和目标都不递增的块传输。

    如果您比较 TRM (SLAU893C) 表 5-2 的 DMATM=0 且=2、则会注意到只有 DMATM=2(重复)提到“当 DMASZ 向下计数到零时、sic、DMADA 和 DMASZ 寄存器重新加载到原始值“、因此如果指针递增、它们会在末尾按该方式保留 作为一个实验:尝试在调试器中暂停您的程序,并检查 DMADA 指向的位置(这就是我注意到这个伪影)。  

    未经请求:请小心在 C1104 中调用 sprintf()。 我的发现(这里)是 sprintf(“%d") 的“ 的堆栈成本超过 840 字节(您的 SRAM 的 80%)。 ltoa() 可能是一个更好的选择。 这不是你现在的问题,但它最终会.