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.

[参考译文] MSP432P401R:为多个重复的 ADC14请求设置 DMA

Guru**** 2582405 points


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

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/612768/msp432p401r-setting-up-dma-for-multiple-repeating-adc14-requests

器件型号:MSP432P401R

您好!

我已经尝试让这个代码工作一两周了、我已经知道了一段时间了。 我可以看到、三个不同的引脚正在使用调试工具将数据写入 MEM0-MEM2位置、但只能将数据从 MEM0获取到我可以实际使用的数组中、prim_buffer0。

我已经合并了两个示例、并尝试使用正在工作的 DMA_INT1_IRQHandler 来触发其他通道的软件请求、尽管这可能不是最好的方法。 但是、这不起作用。 我在 IRQ 中有一些递增、并且只有第一个递增。

#include "msp.h"
#include 
#include 
#include "Crystalfontz128x128_ST7735.h"
#include 
#include 
#include "arm_const_structs.h"


#define test_length_samples 1024
#define SAMPLE_LENGTH 1024
//#define NUMBER_of _SAMPLE 512

/*--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
* FFT Bin 的全局变量示例
*------------------------------------------ //
uint32_t fftSize = sample_length;
uint32_t ifftFlag = 0;
uint32_t doBitReverse = 1;
volatile ARM_STATUS 状态;

//图形库上下文*/
Graphics_context g_sContext;

#define SMCLK_FREQUENCY 48000000
#define SAMPLE_FREQUENCY 24000000


/* DMA 控制表*/
#ifdef ewarm
#pragma DATA_ALIGIN=256
#else
#pragma DATA_ALIGN (controlTable、256)
#endif
uint8_t controlTable[256];


// FFT 数据/处理缓冲区*
/ float Hann[sample_length];int16_prim_int16_t bufferlength


;bufferlength[16_bufferlength]


;int16_int_int_1_bufferlength[t_int_bufferlength]
int16_t alt_buffer1[sample_length];
int16_t alt_buffer2[sample_length];

volatile int switch_data = 0;

// Timer_A PWM 配置参数*/
Timer_A_PWMConfig pwmConfig =
{
Timer_A_CLOCKSOURCE_SMCLK、
Timer_A_CLOCKSOURCE_divider _1、
(SMCLK_FREQUENCY / SAMPLE_FREQUENCY)、
Timer_A_CAPTURECOMPARE 寄存器_1、
Timer_A_OUTPUTMODE_SET_RESET、
(SMCLK_FREQUENCY /SAMPLE_FREQUENCY)/2
};

静态 uint16_t resultsBuffer[4];

volatile int adcIncrement = 0;
volatile int irq1Increment = 0;
volatile int irq2Increment = 0;
volatile int irq3Increment = 0;

void main (void)
{
/*停止 WDT 并禁用主中断*/
MAP_WDT_A_HOLDTimer();
MAP_Interrupt_disableMaster();

//memset (resultsBuffer、0x00、4);

/*将内核电压电平设置为 VCORE1 */
MAP_PCM_setCoreVoltageLevel (PCM_VCORE1);

//为闪存组0和1*/设置2个闪存等待状态
MAP_FlashCtl_setWaitState (FLASH_BANK0、2);
MAP_FlashCtl_setWaitState (FLASH_BANK1、2);

/*初始化时钟系统*/
MAP_CS_setDCOCenteredFrequency (CS_DCO_FREQUENCY 48);
MAP_CS_initClockSignal (CS_MCLK、CS_DCOCLK_SELECT、CS_Clock_divider _1);
MAP_CS_initClockSignal (CS_HSMCLK、CS_DCOCLK_SELECT、CS_Clock_divider _1);
MAP_CS_initClockSignal (CS_SMCLK、CS_DCOCLK_SELECT、CS_Clock_divider _1);
MAP_CS_initClockSignal (CS_ACLK、CS_REFOCLK_SELECT、CS_CLOCK_DELUGER_1);

/*将 Timer_A 配置为具有大约500ms 的周期和
*初始占空比为其10%(3200个节拍)*/
Timer_A_generatePWM (timer_A0_BASE、&pwmConfig);

/*初始化 ADC (MCLK/1/1)*/
ADC14_enableModule();
ADC14_initModule (ADC_CLOCKSOURCE_MCLK、ADC_PREDIVIDER_1、ADC_DIVIDER_1、0);

ADC14_setSampleHoldTrigger (ADC_TRIGGER_SOURCE1、false);

////////*配置 GPIO *

MAP_GPIO_setPeripheralModuleFunctionInputPin (GPIO_PORT_P5、GPIO_PIN5、
GPIO_TICE_MODULE_FUNCTION);
MAP_GPIO_setPeripheralModuleFunctionInputPin (GPIO_PORT_P5、GPIO_PIN4、
GPIO_TICE_MODULE_FUNCTION);
MAP_GPIO_setPeripheralModuleFunctionInputPin (GPIO_PORT_P4、GPIO_PIN3、
GPIO_TICE_MODULE_FUNCTION);


/*配置 ADC 内存*/
MAP_ADC14_configureMultiSequenceMode (ADC_MEM0、ADC_MEM2、TRUE);
MAP_ADC14_configureConversionMemory (ADC_MEM0、ADC_VREFPS_AVCC_VREFNEG_VSS、
ADC_INPUT_A0、false);
MAP_ADC14_configureConversionMemory (ADC_MEM1、ADC_VREFPS_AVCC_VREFNEG_VSS、
ADC_INPUT_A1、false);
MAP_ADC14_configureConversionMemory (ADC_MEM2、ADC_VREFPS_AVCC_VREFNEG_VSS、
ADC_INPUT_A10、false);


/*将 ADC 结果格式设置为带符号的二进制数*/
ADC14_setResultFormat (ADC_signed_binary);

/*配置 DMA 模块*/
DMA_enableModule();
DMA_setControlBase (controlTable);


DMA_disableChannelAttribute (DMA_CH7_ADC14、
UDMA_ATTR_ALTSELECT | UDMA_ATTR_USEBURST |
UDMA_ATTR_HIGH_PRIOR|
UDMA_ATTR_REQMASK);
/*设置控制索引。 在本例中、我们将设置的源
* DMA 传输到 ADC14存储器0
*和目标到
*目的数据数组。 *
MAP_DMA_setChannelControl (UDMA_PRI_SELECT | DMA_CH7_ADC14、
UDMA_SIZE_16 | UDMA_SRC_INC_NONE | UDMA_DST_INC_16 | UDMA_ARB_1);
MAP_DMA_setChannelTransfer (UDMA_PRI_SELECT | DMA_CH7_ADC14、
UDMA_MODE_pingpong、(void*)&ADC14->MEM[0]、
prim_buffer0、sample_length);

MAP_DMA_setChannelControl (UDMA_ALT_SELECT | DMA_CH7_ADC14、 UDMA_SIZE_16 | UDMA_SRC_INC_NONE | UDMA_DST_INC_16 | UDMA_ARB_1); MAP_DMA_setChannelTransfer (UDMA_ALT_SELECT | DMA_CH7_ADC14、 UDMA_MODE_pingpong、(void*)&ADC14->MEM[0]、 alt_buffer0、sample_length); /*分配/启用中断*/ MAP_DMA_赋 值中断(DMA_INT1、7); MAP_Interrupt_enableInterrupt (INT_DMA_INT1); MAP_DMA_赋 值通道(DMA_CH7_ADC14); MAP_DMA_clearInterruptFlag (7); MAP_Interrupt_enableMaster (); // MAP_ADC14_enableInterrupt (ADC_INT2); // MAP_Interrupt_enableInterrupt (INT_ADC14); MAP_DMA_赋 值中断(DMA_INT2、1); MAP_Interrupt_enableInterrupt (INT_DMA_INT2); MAP_DMA_assignChannel (DMA_CH1_RESERVED0); MAP_DMA_clearInterruptFlag (1); MAP_DMA_赋 值中断(DMA_INT3、2); MAP_Interrupt_enableInterrupt (INT_DMA_INT3); MAP_DMA_assignChannel (DMA_CH2_RESERVED0); MAP_DMA_clearInterruptFlag (2); MAP_DMA_enableChannel (1); MAP_DMA_enableChannel (2); /*现在 DMA 已启动并已设置,从而启用通道。 ADC14 *硬件应接管并传输/接收所有字节*/ MAP_DMA_enableChannel (7); MAP_ADC14_enableConversion(); /*强制在 DMA 通道1上进行软件传输*/ MAP_DMA_requestSoftwareTransfer (1); /*强制在 DMA 通道2上进行软件传输*/ MAP_DMA_requestSoftwareTransfer (2);
while (1) { MAP_PCM_gotoLPM0 (); } } //void ADC14_IRQHandler (void) //{ // adcIncrement++; // uint64_t status; // status = MAP_ADC14_getEnabableInterruptStatus (void); // MAP_ADC14_clearInterruptFlag (status); // if (status & adc_int2) MAP_ADC14_getMultiSequenceResult (resultsBuffer); //} // //} // ADC14 MEM0的// 完成中断*/ void DMA_INT1_IRQHandler (void) { irq1Increment++; /*使用 DMA 的交替模式在主缓冲器和备用缓冲器之间切换*/ IF (DMA_getChannelAttribute (7)& UDMA_ATTR_ALTSELECT) { DMA_setChannelControl (UDMA_PRI_SELECT | DMA_CH7_ADC14、 UDMA_SIZE_16 | UDMA_SRC_INC_NONE | UDMA_DST_INC_16 | UDMA_ARB_1); DMA_setChannelTransfer (UDMA_PRI_SELECT | DMA_CH7_ADC14、 UDMA_MODE_pingpong、(void*)&ADC14->MEM[0]、 prim_buffer0、sample_length); switch_data = 1; } 其他 { DMA_setChannelControl (UDMA_ALT_SELECT | DMA_CH7_ADC14、 UDMA_SIZE_16 | UDMA_SRC_INC_NONE | UDMA_DST_INC_16 | UDMA_ARB_1); DMA_setChannelTransfer (UDMA_ALT_SELECT | DMA_CH7_ADC14、 UDMA_MODE_pingpong、(void*)&ADC14->MEM[0]、 alt_buffer0、sample_length); switch_data = 0; } MAP_DMA_requestSoftwareTransfer (1); MAP_DMA_requestSoftwareTransfer (2); ADC14 MEM7的}/*完成中断*/ _属性_((ramfunc) ) void DMA_INT2_IRQHandler (void) { irq2Increment++; /*使用 DMA 的交替模式在主缓冲器和备用缓冲器之间切换*/ IF (DMA_getChannelAttribute (1)& UDMA_ATTR_ALTSELECT) { DMA_setChannelControl (UDMA_PRI_SELECT | DMA_CH1_RESERVED0、 UDMA_SIZE_16 | UDMA_SRC_INC_NONE | UDMA_DST_INC_16 | UDMA_ARB_1); DMA_setChannelTransfer (UDMA_PRI_SELECT | DMA_CH1_RESERVED0、 UDMA_MODE_pingpong、(void*)&ADC14->MEM[1]、 prim_buffer1、sample_length); } 其他 { DMA_setChannelControl (UDMA_ALT_SELECT | DMA_CH1_RESERVED0、 UDMA_SIZE_16 | UDMA_SRC_INC_NONE | UDMA_DST_INC_16 | UDMA_ARB_1); DMA_setChannelTransfer (UDMA_ALT_SELECT | DMA_CH1_RESERVED0、 UDMA_MODE_pingpong、(void*)&ADC14->MEM[1]、 alt_buffer1、sample_length); } } // ADC14 MEM8的完成中断*/ __attribute__((ramfunc) void dma_int3_IRQHandler (void) { irq3Increment++; /*使用 DMA 的交替模式在主缓冲器和备用缓冲器之间切换*/ IF (DMA_getChannelAttribute (2)& UDMA_ATTR_ALTSELECT) { DMA_setChannelControl (UDMA_PRI_SELECT | DMA_CH2_RESERVED0、 UDMA_SIZE_16 | UDMA_SRC_INC_NONE | UDMA_DST_INC_16 | UDMA_ARB_1); DMA_setChannelTransfer (UDMA_PRI_SELECT | DMA_CH2_RESERVED0、 UDMA_MODE_pingpong、(void*)&ADC14->MEM[2]、 prim_buffer2、sample_length); switch_data = 1; } 其他 { DMA_setChannelControl (UDMA_ALT_SELECT | DMA_CH2_RESERVED0、 UDMA_SIZE_16 | UDMA_SRC_INC_NONE | UDMA_DST_INC_16 | UDMA_ARB_1); DMA_setChannelTransfer (UDMA_ALT_SELECT | DMA_CH2_RESERVED0、 UDMA_MODE_pingpong、(void*)&ADC14->MEM[2]、 alt_buffer2、sample_length); switch_data = 0; } //map_Interrupt_disableSlepOnIsrExit(); SCB->SCR &=~SCB_SCR_SLEEPDEEP_Pos; }

是否有人能让我深入了解我需要做些什么才能正确设置通道、从而分别从 ADC14MEM1和 ADC14MEM2将数据输入 prim_buffer1和 prim_buffer2? 几天以来、我一直在用这个代码敲我的头、用30种不同的方式对它进行了重新调制、至今没有取得任何进展。

此致、

Julian

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    尊敬的 Julian:
    我将查看这一点、但我需要逐行浏览、这将需要一些时间。

    (1)您包含许多与 ARM CMSIS-DSPLIB 相关的内容、但我实际上看不到您使用的是 API。 您是否打算使用 ARM DSPLIB?
    (2)采样频率与 smclk 频率一起用于计算 ADC 的计时器触发、设置为24000000 (24Msps)。 在14位模式下、您将得到的最大值为1Msps。 请注意、您正在转换3个通道、因此您能够完成此操作的最快速度是1Msps/3。
    (3)可以使用修订版 C 芯片将闪存等待状态的数量设置为"1"。 如果您使用的是修订版 B 芯片并且需要使用2个闪存等待状态、那么您所做的工作将不起作用、因为修订版 B 芯片针对 DMA 的多通道转换触发结束进行了勘误。 请验证您正在使用版本 C (红色 LaunchPad)并将闪存等待状态更改为"1"。
    (4) ADC 时钟源选为 MCLK、即48Mhz。 请将其更改为小于或等于25MHz 的源。
    (5) DMA 的配置使得通道7由 ADC 触发、并且当主通道进行1024次传输时、该 DMA 通道将触发一个中断(DMA1)、然后由副通道再次进行。 DMA2和 DMA3是分配的通道、但这些通道并未定义。 我不知道 DMA 会做什么、因为没有定义大小。

    我建议从一个简单的示例开始、该示例只测量三个 ADC 通道、然后在 ISR 中将数据(无 DMA)从 ADCMEM 位置移动到所需的存储器位置。

    Chris

    dev.ti.com/.../

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

    尊敬的 Chris:

    感谢您查看此内容!

    1) 1)否、我不打算使用 DSPLIB;这可能是我使用的初始示例的一部分。 我将对其进行一点反馈。

    2) 2)好的、这是有道理的;最后、我要对3个引脚进行采样、每个引脚上的波形变化相同、以寻找相位角;因此我希望采样非常快。 理想情况下、我希望尽快同时抓取3个引脚、例如1000个样本、 对一个位进行坐标和拉取、然后重复。 顺便提一下、当我更改这些采样频率时、我的分辨率-采样连接在引脚5.5上的函数发生器-在 prim_buffer0中、看起来会显著下降;它的波形几乎为10kHz、并且会细分大约50kHz。

    3) 3)我正在使用红色 LaunchPad;因此我将 FlashBank0和1都更改为1?

    4) 4)好的、可以

    5) 5)啊、好的、我不是很清楚这是怎么工作的。 我已经用与 ADC 几乎相同的设置设置来设置 DMA2和 DMA3、但它似乎会有所中断。

    这是我在进行这些调整后得到的代码:

    #include "msp.h"
    #include 
    #include 
    
    #define SAMPLE_LENGTH 1024
    
    #define SMCLK_FREQUENCY 25000000
    #define SAMPLE_FREQUENCY 333333
    
    
    /* DMA 控制表*/
    #ifdef ewarm
    #pragma DATA_ALIGNing=256
    #else
    #pragma DATA_ALIGN (controlTable、256)
    #endif
    uint8_t controlTable[256];
    
    int16_t prim_buffer0[sample_length];
    int16_t bufferlength;int16_t_bufferlength int1_t_1_sample_sample_length
    
    
    ;int16_int_bufferlength
    int16_t alt_buffer1[sample_length];
    int16_t alt_buffer2[sample_length];
    
    volatile int switch_data = 0;
    
    
    // Timer_A PWM 配置参数*/
    Timer_A_PWMConfig pwmConfig =
    {
    Timer_A_CLOCKSOURCE_SMCLK、
    Timer_A_CLOCKSOURCE_divider _1、
    (SMCLK_FREQUENCY / SAMPLE_FREQUENCY)、
    Timer_A_CAPTURECOMPARE 寄存器_1、
    Timer_A_OUTPUTMODE_SET_RESET、
    (SMCLK_FREQUENCY /SAMPLE_FREQUENCY)/2
    };
    
    volatile int adcincrement = 0;
    volatile int irq1Increment = 0;
    volatile int irq2Increment = 0;
    volatile int irq3Increment = 0;
    
    void main (void)
    {
    /*停止 WDT 并禁用主中断*/
    MAP_WDT_A_HOLDTimer();
    MAP_Interrupt_disableMaster();
    
    //memset (resultsBuffer、0x00、4);
    
    /*将内核电压电平设置为 VCORE1 */
    MAP_PCM_setCoreVoltageLevel (PCM_VCORE1);
    
    //为闪存组0和1*/设置2个闪存等待状态
    MAP_FlashCtl_setWaitState (FLASH_BANK0、1);
    MAP_FlashCtl_setWaitState (FLASH_BANK1、1);
    
    /*初始化时钟系统*/
    MAP_CS_setDCOCenteredFrequency (CS_DCO_FREQUENCY 48);
    MAP_CS_initClockSignal (CS_MCLK、CS_DCOCLK_SELECT、CS_Clock_divider _1);
    MAP_CS_initClockSignal (CS_HSMCLK、CS_DCOCLK_SELECT、CS_Clock_divider _1);
    MAP_CS_initClockSignal (CS_SMCLK、CS_DCOCLK_SELECT、CS_Clock_divider _1);
    MAP_CS_initClockSignal (CS_ACLK、CS_REFOCLK_SELECT、CS_CLOCK_DELUGER_1);
    
    /*将 Timer_A 配置为具有大约500ms 的周期和
    *初始占空比为其10%(3200个节拍)*/
    Timer_A_generatePWM (timer_A0_BASE、&pwmConfig);
    
    /*初始化 ADC (MCLK/1/1)*/
    ADC14_enableModule();
    ADC14_initModule (ADC_CLOCKSOURCE_SMCLK、ADC_PREDIVIDER_1、ADC_DIVIDER_1、0);
    
    ADC14_setSampleHoldTrigger (ADC_TRIGGER_SOURCE1、false);
    
    //////配置 GPIO (4.3 A10)*//
    GPIO_setPeripheralModuleFunctionInputPin (GPIO_PORT_P4、GPIO_PIN3、
    // GPIO_TIVE_MODULE_FUNCTION);
    
    MAP_GPIO_setPeripheralModuleFunctionInputPin (GPIO_PORT_P5、GPIO_PIN5、
    GPIO_TICE_MODULE_FUNCTION);
    MAP_GPIO_setPeripheralModuleFunctionInputPin (GPIO_PORT_P5、GPIO_PIN4、
    GPIO_TICE_MODULE_FUNCTION);
    MAP_GPIO_setPeripheralModuleFunctionInputPin (GPIO_PORT_P4、GPIO_PIN3、
    GPIO_TICE_MODULE_FUNCTION);
    
    
    //配置 ADC 内存*//
    ADC14_configureSingleSampleMode (ADC_MEM0、TRUE);
    // ADC14_configureConversionMemory (ADC_MEM0、ADC_VREFPS_AVCC_VREFNEG_VSS、
    // ADC_INPUT_A10、 false);
    
    MAP_ADC14_configureMultiSequenceMode (ADC_MEM0、ADC_MEM2、TRUE);
    MAP_ADC14_configureConversionMemory (ADC_MEM0、ADC_VREFPS_AVCC_VREFNEG_VSS、
    ADC_INPUT_A0、false);
    MAP_ADC14_configureConversionMemory (ADC_MEM1、ADC_VREFPS_AVCC_VREFNEG_VSS、
    ADC_INPUT_A1、false);
    MAP_ADC14_configureConversionMemory (ADC_MEM2、ADC_VREFPS_AVCC_VREFNEG_VSS、
    ADC_INPUT_A10、false);
    
    
    /*将 ADC 结果格式设置为带符号的二进制数*/
    ADC14_setResultFormat (ADC_signed_binary);
    
    /*配置 DMA 模块*/
    DMA_enableModule();
    DMA_setControlBase (controlTable);
    
    
    DMA_disableChannelAttribute (DMA_CH7_ADC14、
    UDMA_ATTR_ALTSELECT | UDMA_ATTR_USEBURST |
    UDMA_ATTR_HIGH_PRIOR|
    UDMA_ATTR_REQMASK);
    /*设置控制索引。 在本例中、我们将设置的源
    * DMA 传输到 ADC14存储器0
    *和目标到
    *目的数据数组。 *
    MAP_DMA_setChannelControl (UDMA_PRI_SELECT | DMA_CH7_ADC14、
    UDMA_SIZE_16 | UDMA_SRC_INC_NONE | UDMA_DST_INC_16 | UDMA_ARB_1);
    MAP_DMA_setChannelTransfer (UDMA_PRI_SELECT | DMA_CH7_ADC14、
    UDMA_MODE_pingpong、(void*)&ADC14->MEM[0]、
    prim_buffer0、sample_length);
    
    MAP_DMA_setChannelControl (UDMA_ALT_SELECT | DMA_CH7_ADC14、
    UDMA_SIZE_16 | UDMA_SRC_INC_NONE | UDMA_DST_INC_16 | UDMA_ARB_1);
    MAP_DMA_setChannelTransfer (UDMA_ALT_SELECT | DMA_CH7_ADC14、
    UDMA_MODE_pingpong、(void*)&ADC14->MEM[0]、
    alt_buffer0、sample_length);
    
    //取消注释此段使 irq1Increment 停止为1023 *//
    dma_disableChannelAttribute (dma_ch1_RESERVED0、
    // UDMA_ATTR_ALTSELECT | UDMA_ATTR_USEBURST |
    // UDMA_ATTR_HIGH_PRIOR|
    // uDMA_ATTR_REQMASK);
    //
    
    //// dma_setChannelControl (uDMA_PRI_SELECT | dma_CH1_RESERVED0、
    // UDMA_SIZE_16 | UDMA_SRC_INC_NONE | UDMA_DST_INC_16 | UDMA_ARB_1);
    // DMA_setChannelTransfer (UDMA_PRI_SELECT | DMA_CH1_RESERVED0、
    // UDMA_MODE_pingpong、(void*)&ADC14->MEM[1]、
    // prim_buffer1、sample_length);
    //
    dma_setChannelControl (udma_ALT_select | dma_ch1_RESERVED0、
    // UDMA_SIZE_16 | UDMA_SRC_INC_NONE | UDMA_DST_INC_16 | UDMA_ARB_1);
    // DMA_setChannelTransfer (UDMA_ALT_SELECT | DMA_CH1_RESERVED0、
    // UDMA_MODE_pingpong、(void*)&ADC14->MEM[1]、
    // alt_buffer1、sample_length);
    //
    dma_disableChannelAttribute (dma_ch2_RESERVED0、
    // UDMA_ATTR_ALTSELECT | UDMA_ATTR_USEBURST |
    // UDMA_ATTR_HIGH_PRIOR|
    // uDMA_attr_REQMASK);
    //
    dma_setChannelControl (uDMA_PRI_SELECT | dma_CH2_RESERVED0、
    // UDMA_SIZE_16 | UDMA_SRC_INC_NONE | UDMA_DST_INC_16 | UDMA_ARB_1);
    // DMA_setChannelTransfer (UDMA_PRI_SELECT | DMA_CH2_RESERVED0、
    // UDMA_MODE_pingpong、(void*)&ADC14->MEM[2]、
    // prim_buffer2、sample_length);
    //
    dma_setChannelControl (udma_ALT_select | dma_ch2_RESERVED0、
    // UDMA_SIZE_16 | UDMA_SRC_INC_NONE | UDMA_DST_INC_16 | UDMA_ARB_1);
    // DMA_setChannelTransfer (UDMA_ALT_SELECT | DMA_CH2_RESERVED0、
    // UDMA_MODE_pingpong、(void*)&ADC14->MEM[2]、
    // alt_buffer2、sample_length);
    
    
    /*分配/启用中断*/
    MAP_DMA_赋 值中断(DMA_INT1、7);
    MAP_Interrupt_enableInterrupt (INT_DMA_INT1);
    MAP_DMA_赋 值通道(DMA_CH7_ADC14);
    MAP_DMA_clearInterruptFlag (7);
    
    MAP_DMA_赋 值中断(DMA_INT2、1);
    MAP_Interrupt_enableInterrupt (INT_DMA_INT2);
    MAP_DMA_assignChannel (DMA_CH1_RESERVED0);
    MAP_DMA_clearInterruptFlag (1);
    
    MAP_DMA_赋 值中断(DMA_INT3、2);
    MAP_Interrupt_enableInterrupt (INT_DMA_INT3);
    MAP_DMA_assignChannel (DMA_CH2_RESERVED0);
    MAP_DMA_clearInterruptFlag (2);
    
    map_Interrupt_enableMaster ();
    
    // map_ADC14_enableSampleTimer (adc_automatic_iteration);
    
    MAP_DMA_enableChannel (1);
    MAP_DMA_enableChannel (2);
    
    
    /*现在 DMA 已启动并已设置,从而启用通道。 ADC14
    *硬件应接管并传输/接收所有字节*/
    MAP_DMA_enableChannel (7);
    MAP_ADC14_enableConversion ();
    // MAP_ADC14_toggleConversionTrigger ();
    
    //////*强制在 DMA 通道1上进行软件传输*/
    MAP_DMA_requestSoftwareTransfer (1);
    //////*强制在 DMA 通道2上进行软件传输*/
    MAP_DMA_requestSoftwareTransfer (2);
    
    while (1)
    {
    MAP_PCM_gotoLPM0 ();
    
    }
    }
    
    //void ADC14_IRQHandler (void)
    //{
    // adcIncrement++;
    //
    uint64_t status;
    //
    status = MAP_ADC14_getEnabableInterruptStatus (void);
    // MAP_ADC14_clearInterruptFlag (status);
    //
    if (status & adc_int2)
    
    MAP_ADC14_getMultiSequenceResult (resultsBuffer);
    //}
    //
    //}
    
    //
    //针对 ADC14 MEM0的//
    完成中断*/ void DMA_INT1_IRQHandler (void)
    {
    irq1Increment++;
    /*使用 DMA 的交替模式在主缓冲器和备用缓冲器之间切换*/
    IF (DMA_getChannelAttribute (7)& UDMA_ATTR_ALTSELECT)
    {
    DMA_setChannelControl (UDMA_PRI_SELECT | DMA_CH7_ADC14、
    UDMA_SIZE_16 | UDMA_SRC_INC_NONE | UDMA_DST_INC_16 | UDMA_ARB_1);
    DMA_setChannelTransfer (UDMA_PRI_SELECT | DMA_CH7_ADC14、
    UDMA_MODE_pingpong、(void*)&ADC14->MEM[0]、
    prim_buffer0、sample_length);
    switch_data = 1;
    }
    其他
    {
    DMA_setChannelControl (UDMA_ALT_SELECT | DMA_CH7_ADC14、
    UDMA_SIZE_16 | UDMA_SRC_INC_NONE | UDMA_DST_INC_16 | UDMA_ARB_1);
    DMA_setChannelTransfer (UDMA_ALT_SELECT | DMA_CH7_ADC14、
    UDMA_MODE_pingpong、(void*)&ADC14->MEM[0]、
    alt_buffer0、sample_length);
    switch_data = 0;
    }
    
    MAP_DMA_requestSoftwareTransfer (1);
    MAP_DMA_requestSoftwareTransfer (2);
    ADC14
    
    
    MEM7的}/*完成中断*/
    _属性_((ramfunc)
    ) void DMA_INT2_IRQHandler (void)
    {
    irq2Increment++;
    /*使用 DMA 的交替模式在主缓冲器和备用缓冲器之间切换*/
    IF (DMA_getChannelAttribute (1)& UDMA_ATTR_ALTSELECT)
    {
    DMA_setChannelControl (UDMA_PRI_SELECT | DMA_CH1_RESERVED0、
    UDMA_SIZE_16 | UDMA_SRC_INC_NONE | UDMA_DST_INC_16 | UDMA_ARB_1);
    DMA_setChannelTransfer (UDMA_PRI_SELECT | DMA_CH1_RESERVED0、
    UDMA_MODE_pingpong、(void*)&ADC14->MEM[1]、
    prim_buffer1、sample_length);
    }
    其他
    {
    DMA_setChannelControl (UDMA_ALT_SELECT | DMA_CH1_RESERVED0、
    UDMA_SIZE_16 | UDMA_SRC_INC_NONE | UDMA_DST_INC_16 | UDMA_ARB_1);
    DMA_setChannelTransfer (UDMA_ALT_SELECT | DMA_CH1_RESERVED0、
    UDMA_MODE_pingpong、(void*)&ADC14->MEM[1]、
    alt_buffer1、sample_length);
    }
    }
    
    // ADC14 MEM8的完成中断*/
    __attribute__((ramfunc)
    void dma_int3_IRQHandler (void)
    {
    irq3Increment++;
    /*使用 DMA 的交替模式在主缓冲器和备用缓冲器之间切换*/
    IF (DMA_getChannelAttribute (2)& UDMA_ATTR_ALTSELECT)
    {
    DMA_setChannelControl (UDMA_PRI_SELECT | DMA_CH2_RESERVED0、
    UDMA_SIZE_16 | UDMA_SRC_INC_NONE | UDMA_DST_INC_16 | UDMA_ARB_1);
    DMA_setChannelTransfer (UDMA_PRI_SELECT | DMA_CH2_RESERVED0、
    UDMA_MODE_pingpong、(void*)&ADC14->MEM[2]、
    prim_buffer2、sample_length);
    switch_data = 1;
    }
    其他
    {
    DMA_setChannelControl (UDMA_ALT_SELECT | DMA_CH2_RESERVED0、
    UDMA_SIZE_16 | UDMA_SRC_INC_NONE | UDMA_DST_INC_16 | UDMA_ARB_1);
    DMA_setChannelTransfer (UDMA_ALT_SELECT | DMA_CH2_RESERVED0、
    UDMA_MODE_pingpong、(void*)&ADC14->MEM[2]、
    alt_buffer2、sample_length);
    switch_data = 0;
    }
    //map_Interrupt_disableSlepOnIsrExit();
    SCB->SCR &=~SCB_SCR_SLEEPDEEP_Pos;
    }
    

    或多或少、它的工作方式相同;如果我取消注释尝试的 CH1和 CH2设置、它会导致 irq1increment 在1023停止、但无论 IRQ2或 IRQ3函数如何都不运行。

    我很快将在一个正常的多引脚重复 ADC 示例上尝试一下、但我可能需要在末尾使用 DMA、因为我想尽可能快地进行采样、以解析100kHz 波形。

    再次感谢您查看此内容!

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

    我在正常的多引脚重复 ADC 上尝试了一下、并设法使其以我所需的方式工作、但我需要它的速度提高大约50%。

    /* DriverLib 包括*/
    #include 
    
    /*标准包括*/
    #include 
    #include 
    #include 
    
    
    /* static */
    static volatile int index = 0;
    static volatile int value1[1000];
    static volatile int value2[1000];
    static volatile int value3[1000];
    
    
    int main (void)
    {
    /*停止看门狗*/
    MAP_WDT_A_HOLDTimer();
    
    /*设置闪存等待状态*/
    MAP_FlashCtl_setWaitState (FLASH_BANK0、1);
    MAP_FlashCtl_setWaitState (FLASH_BANK1、1);
    
    /*将 DCO 设置为48MHz */
    MAP_PCM_setPowerState (PCM_AM_LDO_VCORE1);
    MAP_CS_setDCOCenteredFrequency (CS_DCO_FREQUENCY 48);
    
    /*启用 FPU 进行浮点运算*/
    map_fpu_enableModule();
    MAP_FPU_enableLazyStacking();
    
    
    //![单个采样模式配置]
    /*初始化 ADC (MCLK/1/4)*/
    MAP_ADC14_enableModule();
    MAP_ADC14_initModule (ADC_CLOCKSOURCE_MCLK、ADC_PREDIVIDER_1、ADC_DIVIDER_2、0);
    
    MAP_ADC14_setResolution (ADC_8位);
    
    /*配置 GPIO (5.5 A0)*/
    MAP_GPIO_setPeripheralModuleFunctionInputPin (GPIO_PORT_P5、GPIO_PIN5、
    GPIO_TICE_MODULE_FUNCTION);
    MAP_GPIO_setPeripheralModuleFunctionInputPin (GPIO_PORT_P5、GPIO_PIN4、
    GPIO_TICE_MODULE_FUNCTION);
    MAP_GPIO_setPeripheralModuleFunctionInputPin (GPIO_PORT_P4、GPIO_PIN3、
    GPIO_TICE_MODULE_FUNCTION);
    
    /*配置 ADC 内存*/
    MAP_ADC14_configureMultiSequenceMode (ADC_MEM0、ADC_MEM2、TRUE);
    MAP_ADC14_configureConversionMemory (ADC_MEM0、ADC_VREFPS_AVCC_VREFNEG_VSS、
    ADC_INPUT_A0、false);
    MAP_ADC14_configureConversionMemory (ADC_MEM1、ADC_VREFPS_AVCC_VREFNEG_VSS、
    ADC_INPUT_A1、false);
    MAP_ADC14_configureConversionMemory (ADC_MEM2、ADC_VREFPS_AVCC_VREFNEG_VSS、
    ADC_INPUT_A10、false);
    
    
    /*配置采样计时器*/
    MAP_ADC14_enableSampleTimer (ADC_AUTOMATE_DIOTIVation);
    
    /*启用/切换转换*/
    MAP_ADC14_enableConversion();
    MAP_ADC14_toggleConversionTrigger ();
    //![单个采样模式配置]
    
    /*启用中断*/
    MAP_ADC14_enableInterrupt (ADC_INT0);
    MAP_Interrupt_enableInterrupt (INT_ADC14);
    MAP_Interrupt_enableMaster();
    
    while (1)
    {
    MAP_PCM_gotoLPM0 ();
    }
    
    }/*
    
    ADC 中断处理程序。 每当
    ADC_MEM0完成转换*时、就会调用此处理程序。
    */
    void ADC14_IRQHandler (void)
    {
    uint64_t status = MAP_ADC14_getEnabableInterruptStatus();
    MAP_ADC14_clearInterruptFlag (status);
    
    IF (ADC_INT0和状态)
    {
    //NB:getMultiSequenceResult 较慢
    //map_ADC14_getResultArray (ADC_MEM0、ADC_MEM2、resultsBuffer);//???? 不工作?
    
    value1[index]= MAP_ADC14_getResult (ADC_MEM0);
    value2[索引]= map_ADC14_getResult (ADC_MEM1);
    value3[index+]= MAP_ADC14_getResult (ADC_MEM2);
    
    if (索引>= 1000){ 索引= 0; } }

    索引= 1000时、我正在进行一些串行打印、它在高达70kHz 波形的情况下工作正常;另50%的时间将超过我需要的100kHz;是否有任何方法、DMA 或其他方法可以加快此速度?

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

    Julian、

      我看到您在尝试做什么时遇到了一些挑战。  具体而言、由于您正在执行一系列通道、我可以看到移动数据的两个选项。

    (1) 您可以在散聚模式下使用 DMA。  这是一个复杂的实现方案、您可以在这里看到一个示例、SLAA741:  

    www.ti.com/.../slaa741a.pdf

    (2) 您可以像之前那样使用 ADC IRQ。  您遇到的问题是为中断提供服务所需的时间。   我附上了一个尝试使用 DMA 来缩短时间的示例。  这样、我就不会实际移动数据、而只是触发 DMA 来移动数据。  我测量了大约4us 以处理中断并触发 DMA。  假设 ADC 测量所有三个通道大约需要3us、我会将 DMA 触发器保守地设置为120kHz。

    如果您有任何其他问题、请告诉我。

    Chris  

    e2e.ti.com/.../adc14_5F00_multiple_5F00_channel_5F00_no_5F00_repeat_5F00_timera_5F00_source_5F00_03.c