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.
对于我的应用、我希望将 ADC 结果(单字)传输到循环缓冲器(例如256字长)。 我希望传输在每个 ADC EOC 上发生、因此每个突发/传输将仅为一个字。
我希望 这可以在 完全没有 CPU 干预的情况下无限期执行、但根据 此线程以及 TRM 中的图5-5、这是不可能的。 我对 DMA 的设计方式感到困惑、但我希望能够以某种方式利用它、即使它已被削弱。
我希望每个 DMA 触发器执行一次突发、这意味着我想保持在图5-5的"左下环路"中。
哎呀、意外切断了我的电源...
无论如何、我想使用左下方的循环、循环会穿过底部的"另一个 DMA 触发事件"框(OneShot 模式已禁用)。 但是、要保持该循环、TRANSFER_COUNT 必须保持大于零、但每次触发时都会递减。 因此、为了使这个循环缓冲器无限期运行、我的 CPU 必须使 TRANSFER_COUNT 保持为零、类似于看门狗计时器。 我想它可以设置为任意大的数字、对吧?
是否需要其他干预来完成此工作? 当然、除了在缓冲器被木制之前从缓冲器中读取数据之外。
Mike、
是的、您应该能够实现您要做的事情。
在每个 ADC EOC 上、您应该能够启动一个突发。 以下是关键设置。
1) 1)设置 BURST_SIZE = 0 (每个 ADC EOC 1个字)。
该设置将确保在每个 ADC EOC 上、1个字传输到缓冲区
2) 2)设置 transfer_size = circed_buffer_size。
此设置将确保 DMA 中断仅在完成循环缓冲区填充后才被触发。 如果您不希望 CPU 干预、只需在 PIE 中禁用 DMA 中断。
3) 3)设置 wrap_size = circed_buffer_size
此设置确保创建循环缓冲器。
此致、
曼诺伊
因此、如果您从将 TRANSFER_SIZE 设置为256开始、那么在每个 DMA 触发后、您将分支到"右上环路"、因为 TRANSFER_COUNT>0。 在下一个 DMA 触发器上、活动地址寄存器将重新加载影子地址。 因此将发生256次传输(每个传输一个字突发)、但所有传输都使用影子地址(缓冲区中的第一个条目)、而不是向缓冲区中的256个地址中的每个地址写入一次。 完全不是循环缓冲器。
Mike、
很抱歉、我无法遵循您想要传达的信息。 您说的右上环路是什么意思?
您的配置详细信息是什么?
此致、
曼诺伊
我指的是 TRM 中的图5-5、如我的第一篇帖子中所示。 图中有两个节点等待 DMA 触发事件、一个在顶部、一个在底部。 当我查看图5-5时、我看到两个主要循环、每个循环都有其中一个等待状态、用于控制迭代时间。 下面是一张更清晰的图片:
右上环路会在每次触发时将活动地址寄存器重置回影子寄存器。 这不会用作循环缓冲器。 左下方循环不会在每次触发时复位活动地址寄存器、但允许它们进行单步执行和后续处理。 但是,只要 TRANSFER_COUNT>1,它就会留在该循环中。 当 TRANSFER_COUNT 达到零时、它将返回右上环路、返回到顶部(假设我们处于连续模式)、然后活动寄存器将再次被覆盖。
我没有为此编写任何代码、我只是在编写文档。 我假设这将在启用连续模式、禁用 OneShot 模式的情况下工作。 我不打算使用任何 DMA ISR (如果可能)。
Mike、
是的、您将能够实现连续模式启用和一次性模式禁用的循环缓冲器、并且您无需使用 DMA ISR。
一个 DMA 触发事件、DMA 通道执行(BURST_SIZE + 1)个字的传输。 这称为突发。
一个 DMA 传输循环被认为只有在(transfer_size + 1)个突发数量完成后才完成。 因此、为了完成1 DMA 传输循环、您需要 TRANSFER_SIZE + 1个 DMA 触发事件数。 当一个 DMA 传输循环完成时、DMA 将已传输(TRANSFER_SIZE + 1) x (BURST_SIZE + 1)个字。 仅在第一次突发开始时才需要将影子寄存器复制到活动寄存器。
要实现循环缓冲区函数、您的 wrap_size 应该小于(或)等于 transfer_size。 wrap_size 指定源/目标地址回绕到起始地址之前要完成的突发数。
此外,我建议您查看下面链接中提供的“直接存储器存取(DMA)--实验:使用 DMA 缓冲 ADC 结果”。 它介绍了如何使用 C2000 DMA 实现循环缓冲器。
training.ti.com/c2000-f2837xd-microcontroller-workshop
希望这对您有所帮助。
此致、
曼诺伊
您好、Monaj、
我明白你的意思。 当(transfer_size+1)恰好是(wrap_size+1)的整数倍数时、以及当您从缓冲区中的第一个条目开始并且 wrap_step=0时、它会起作用。 在这种情况下、transfer_count 将在 wrap_count 也变为零的同时达到零。 因此、分支到流程图顶部会导致按照流程图底部的相同方式进行换行。
还有一个更简单的问题:在传输过程中是否可以手动覆盖计数寄存器和活动寄存器? 我假设在实际的数据传输过程中执行此操作可能会导致一些问题、但如果我确保仅在 DMA 等待触发时执行此操作、是否可以?
谢谢!
Mike