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.

[参考译文] MSPM0G3507:通过 DMA 传输进行连续 ADC 采样

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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1615788/mspm0g3507-continuous-adc-sampling-with-dma-transfer

器件型号: MSPM0G3507

尊敬的 TI 团队:

我尝试使用 DMA 传输进行连续 ADC 采样。 我需要 1024 个样本/秒 采样时间 0 设置为 976.56us (1/1024)。 例如、我修改了 ADC12_max_freq_DMA。 转换仅开始一次。 但是、通过设置“Enable Repeat Mode“(启用重复模式)、它应该会重新启动。 这是什么原因?

#include "ti_msp_dl_config.h"

#define ADC_SAMPLE_SIZE (1024)
/* When FIFO is enabled 2 samples are compacted in a single word */
#define ADC_FIFO_SAMPLES (ADC_SAMPLE_SIZE >> 1)

uint16_t gADCSamples[ADC_SAMPLE_SIZE];
volatile bool gCheckADC;

int main(void)
{
    SYSCFG_DL_init();

    /* Configure DMA source, destination and size */
    DL_DMA_setSrcAddr(DMA, DMA_CH0_CHAN_ID,
        (uint32_t) DL_ADC12_getFIFOAddress(ADC12_0_INST));

    DL_DMA_setDestAddr(DMA, DMA_CH0_CHAN_ID, (uint32_t) &gADCSamples[0]);
    DL_DMA_setTransferSize(DMA, DMA_CH0_CHAN_ID, ADC_FIFO_SAMPLES);

    DL_DMA_enableChannel(DMA, DMA_CH0_CHAN_ID);

    /* Setup interrupts on device */
    NVIC_EnableIRQ(ADC12_0_INST_INT_IRQN);

    gCheckADC = false;

    DL_ADC12_startConversion(ADC12_0_INST);

    while (1) {

        while (false == gCheckADC) {
            __WFE();
        }
        gCheckADC = false;
        DL_GPIO_togglePins(GPIO_LEDS_PORT, GPIO_LEDS_USER_LED_1_PIN);
        delay_cycles(1600000); 
        DL_GPIO_togglePins(GPIO_LEDS_PORT, GPIO_LEDS_USER_LED_1_PIN);
    }
}

void ADC12_0_INST_IRQHandler(void)
{
    switch (DL_ADC12_getPendingInterrupt(ADC12_0_INST)) {
        case DL_ADC12_IIDX_DMA_DONE:
            gCheckADC = true;
            DL_DMA_enableChannel(DMA, DMA_CH0_CHAN_ID);
            DL_ADC12_enableConversions(ADC12_0_INST); 
            break;
        default:
            break;
    }
}

image.pngimage.pngimage.png

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

    确保已选择触发器将自动步进...。

    1024/6 = 170...4、当 1020 结果完成时、您将在 ADC FIFO 中剩余 4 个 ADC 结果。

    建议将 ADC 采样数设置为 5

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

    是的


    1024/16=64
    有任何缺点吗?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    and 1024/16=64
    是否有任何缺点?

    否、ADC 中没有 32 * 16 位存储器、因此您可以在 DMA 样本计数中设置如此大的值。

    最好设置 DMA 样本计数= 1、并启用 1、3、5、7、9、11 的 MEM 触发(触发 DMA 每两个 ADC 结果传输一次)

    最好设置 DMA 样本计数=  2、并启用 3、7、11 的 MEM 触发(触发 DMA 每 4 个 ADC 结果传输一次)

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

    根据我的理解、可以将 12 个样本保存在 ADC 存储器中。

    但为什么采样不继续?

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

    e2e.ti.com/.../adc12_5F00_timer_5F00_single_5F00_DMA_5F00_G3507.zip

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

    大家好、谢谢您的这个示例。 我有一些问题需要理解。 如果我的陈述有误、请予以更正。

    -采样时间 0 和 1 设置为 40us ,这将导致 32MHz 时钟的 CCR 值为 1280。
    -我认为只有采样时间 0 是必要的
    -每 1280 个时钟周期需要 1 个 ADC 样本
    -如果需要 1024 个样本并保存在用户变量 gADCSamples 中,则会发生中断 DL_ADC12_IIDX_DMA_DONE

    -这是必要的,为什么 6 ? DMA 存储器的大小是 12 个元素吗?

    // Clear ADC FIFO Data
    for(int i = 0; i < 6; i++) {
    DL_ADC12_getFIFOData(ADC12_0_INST);
    }


    - ADCGroupCount 只在 10x1024 个样本后停止代码,没有其他意义 (?)
    -组之间的延迟周期 — 为什么?
    - Implementation TimerA? 采样时间 0 的 CCR 为 1280 而不是 255。 TimerA 的意义是什么?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    -我认为只有采样时间 0 是必要的

    我仅使用此采样时间 0、1 未使用。

    -每 1280 个时钟周期需要 1 个 ADC 样本

    否、使用计时器触发 ADC 启动、ADC 采样 40us、然后进行转换。

    -如果需要 1024 个样本并保存在用户变量 gADCSamples
    中、则会发生中断 DL_ADC12_IIDX_DMA_DONE

    是的。

    [引用 userid=“680486" url="“ url="~“~/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1615788/mspm0g3507-continuous-adc-sampling-with-dma-transfer/6229349 ]-这是必要的、为什么是 6? 这是 DMA 内存的大小是 12 个元素吗?

    请删除循环代码的这一部分、这是我之前的用于清除 ADC FIFO 的调试代码。

    - ADCGroupCount 仅在 10x1024 个样本后停止代码、没有其他意义(?)

    可以停止在任何 ADC 组、10 是我的调试设置。

    -组间的延迟周期 — 为什么?

    您可以将其删除。

    - Implementation TimerA? 采样时间 0 的 CCR 为 1280 而不是 255。 TimerA 的意义是什么?

    使用计时器触发 ADC 启动、ADC 采样 40us、然后进行转换。

    ADC 和计时器之间使用事件。

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

    示例需要哪些设置才能获得每秒 1024 个样本?

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

    没有变化。

    我已将代码采样率设置为 1024SPS。

    您可以在自由运行模式下通过一些 GPIO 切换来测试它。

    下周是中国新年、如果您迫切需要支持、请提交新申请单。

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

    好的、但为了理解:

    -对于 1024S 我需要采样率 (1/1024)s=976.5625us 不是 40us?

    -采样时间 0 ist 1280(40us at 32MHz ),为什么不 31250(1/1024 / 1/ 32MHz ) 为采样时间 0 ?

    -为什么 255 计时器 0? 计时器 0 在示例中的初始值为 1280...

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

    以及使用的 ADC 通道和引脚。 我识别 ADC1 设置。 但我可以连接哪个引脚进行信号输入测试? 没有引脚选择。

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

    非 ono、我使用的是计时器 1024hz

     来触发 ADC。

    可以在 ADC 存储器中选择 ADC 输入

    可从数据表第 8 章 ADC 部分获取输入混合信息

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

    为您的测试上传另一个完全修改的代码示例:

    e2e.ti.com/.../4011.adc12_5F00_timer_5F00_single_5F00_DMA_5F00_G3507.zip

    e2e.ti.com/.../Session-0.sal

    将 PB12 切换开关用作 1s DMA 完成指示器。

    此项目的详细要求和职能建议已发送给您当地的支持团队、请尝试联系他们以了解更多信息。

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

    我想、现在采样看起来很好。

    此外、 我需要使用 1024 个样本/秒的采样速率和 2048 个 DMA 缓冲器。 1024 个样本的前半部分准备就绪后、结果可用于最终计算、DMA 可以改为将结果写入 DMA 的后半部分……

    它应该适用于早期 DMA 中断。 但只捕获 DMA 完成 IRQ。

    void ADC12_0_INST_IRQHandler(void)
    {
        switch (DL_ADC12_getPendingInterrupt(ADC12_0_INST)) {
            case DL_ADC12_IIDX_DMA_DONE:
                gCheckADC = true;
                puts("DL_ADC12_IIDX_DMA_DONE");
                break;
            default:
                break;
        }
    }
    
    void DMA_IRQHandler(void)
    {
        switch (DL_DMA_getPendingInterrupt(DMA)) {
            case DL_DMA_EVENT_IIDX_DMACH0:
                puts("DL_DMA_EVENT_IIDX_DMACH0");
                break;
            case DL_DMA_FULL_CH_EVENT_IIDX_EARLY_IRQ_DMACH0:
                puts("DL_DMA_FULL_CH_EVENT_IIDX_EARLY_IRQ_DMACH0");
                break;
            default:
                break;
        }
    }
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    是否启用 DMA 的 NVIC?

    NVIC_EnableIRQ(DMA_INT_IRQn);

    可以禁用此中断、如果您启用 ADC DMA 完成、则使用两个中的一个是 OK /。

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

    启用此功能后、我可以记录 IRQ。

    NVIC_EnableIRQ(DMA_INT_IRQn);

    DL_ADC12_IIDX_DMA_DONE 和 DL_DMA_EVENT_IIDX_DMACH0 都已满 DMA?

    但是、当 IRQ DL_DMA_FULL_CH_EVENT_IIDX_EARY_IRQ_DMACH0 出现时、我有具有 2048 个值的完整 DMA(第一个循环数组在索引 1024...2047 处应该有零)。 我需要 2048/2 处具有此 IRQ。

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

    Full/Basic DMA 通道是一种通道功能、通道 0 是一种完整的 DMA。

    数据表 www.ti.com/.../slasex6c.pdf 8.5 dma

    两个中断都是 DMASZ = 0 触发条件。

    但当出现 IRQ DL_DMA_FULL_CH_EVENT_IIDX_EARY_IRQ_DMACH0 时、我有具有 2048 个值的完整 DMA(第一个循环数组在索引 1024...2047 处应具有零)。 我需要 2048/2 处有此 IRQ。

    似乎此配置正确:

    您可以设置更长的计时器触发时间、并且可以看到早期整数以半倍大小触发。

    更长的时间!

    监视此项:

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

    为什么会更长? 1024 S/s -> 976.5625us

    如何监控 DMA_DMACHAN... ?  

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

    可能是因为 ADC 计时器 DMA 在调试停止时继续执行... 好的、然后我理解您的建议。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    更长的时间、为什么? 1024 S/s --> 976.5625us

    我使用计时器控制 ADC 采样率。

    如何监控 DMA_DMACHAN... ?  [/报价]

    在调试模式下、寄存器视图、启用刷新

    可能是因为 ADC 计时器 DMA 在调试停止时继续运行... 好的、然后我理解您的建议。

    是的、关键点是我们使用计时器来控制 ADC、但我尝试停止计时器、它不起作用、但我没有进一步 调试它。

    [/quote]