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.

[参考译文] CCS/TMS320F28379D:将 ADC_SoC_Continuous_DMA 示例扩展到四个 ADC

Guru**** 2595800 points
Other Parts Discussed in Thread: C2000WARE

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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/670138/ccs-tms320f28379d-extending-adc_soc_continuous_dma-example-to-four-adcs

器件型号:TMS320F28379D
主题中讨论的其他器件:C2000WARE

工具/软件:Code Composer Studio

我已将 c2000ware 示例 ADC_SoC_Continuous_DMA 扩展到四个 ADC (原始示例仅使用其中的两个 ADC)。 我将新代码粘贴到这里以供参考

//
//包含的文件
//
#include "F28x_Project.h"

//
函数原型
//
__interrupt void adca1_ISR (void);
__interrupt void dmach1_ISR (void);

void ConfigureEPWM (void);
void ConfigureADC (void);
void SetupADCContinuex (void struct adcadc_isr)
;void Configureadc (void anc (void);void adc (void)

//
//定义
//
#define results_buffer_size 512 //用于存储转换结果的缓冲
区//(大小必须是16的倍数)

//
Globals
//
#pragma DATA_SECTION (adcData0、"ramgs0");
#pragma DATA_SECTION (adcData1、"ramgs0");#pragma
DATA_SECTION (adcData2、"ram_SECTION) "ramgs0");
#pragma DATA_SECTION (adcData3、"ramgs0");
uint16 adcData0[results_buffer_size];
uint16 adcData1[results_buffer_size];
uint16 adcData2[results_buffer_size];
uint16 adcData3[results_buffer_size];
volatile Uint16 done;

void main (void)
{
uint16 resultsIndex;

//
//步骤1。 初始化系统控制:
// PLL、看门狗、启用外设时钟
//此示例函数位于 F2837xD_sysctrl.c 文件中。
//
InitSysCtrl();

//
//步骤2。 初始化 GPIO:
//此示例函数位于 F2837xD_GPIO.c 文件中,
//说明了如何将 GPIO 设置为其默认状态。
//
InitGpio();

////
步骤3. 清除所有中断并初始化 PIE 矢量表:
//禁用 CPU 中断
//
Dint;

//
//将 PIE 控制寄存器初始化为默认状态。
//默认状态是禁用所有 PIE 中断并
清除标志//。
//此函数位于 F2837xD_PIECTRL.c 文件中。
//
InitPieCtrl();

//
禁用 CPU 中断并清除所有 CPU 中断标志:
//
IER = 0x0000;
IFR = 0x0000;

//
//初始化 PIE 矢量表,其中包含指向 shell 中断
//服务例程(service routines,ISR)的指针。
//这将填充整个表,即使在
本示例中未使用中断//也是如此。 这对于调试很有用。
//可以在 F2837xD_DefaultIsr.c 中找到 shell ISR 例程
//此函数可在 F2837xD_PieVect.c 中找到
//
InitPieVectTable ();

//
//设置本示例使用的 ISR
//
针对 ADCA INT1的 ISR -发生在第一次转换之后
//针对 DMA CH1的 ISR -发生在 DMA 传输完成时
//
EALLOW;
PieVectTable.ADCA1_INT =&adca1_ISR;
PieVectTable.DMA_CH1_INT =&dmach1_ISR;
EDIS;

//
//启用特定的 CPU 中断:用于 ADC 的 INT1和用于 DMA
的 INT7 //
IER |= M_INT1;
IER |= M_INT7;

//
启用特定 PIE 中断
//
// ADCA INT1 -组1,中断1
// DMA 中断-组7,中断1
//
PieCtrlRegs.PIEIER1.bit.INTx1 = 1;
PieCtrlRegs.PIEIER7.bit.INTx1 = 1;

//
//停止 ePWM 时钟
//
EALLOW;
CpuSysRegs.PCLKCR0.bit.TBCLKSYNC=0;
EDIS;

//
//调用 ePWM 2的设置功能
//
ConfigureEPWM ();

//
//启动 ePWM 时钟
//
EALLOW;
CpuSysRegs.PCLKCR0.bit.TBCLKSYNC=1;
EDIS;

//
//配置 ADC 并为其加电
//
ConfigureADC();

//
//将 ADC 设置为通道 A3和 B3上的连续转换
//
SetupADCContinuimal(&AdcRegs, 3);
SetupADCContinuimal(&AdcbRegs, 3);
SetupADCContinuimal(&AdcRegs, 3);
SetupADCContinuimal(&AdcdRegs、3);

//
初始化 DMA
//
DMAInit();

//
启用全局中断和更高优先级的实时调试事件:
//
EINT;
//启用全局中断 INTM
ERTM;
//启用全局实时中断 DBGM

//
初始化结果缓冲
区//
对于(resultsIndex = 0;resultsIndex < results_buffer_size;resultsIndex++)
{
adcData0[resultsIndex]= 0;
adcData1[resultsIndex]= 0;
adcData2[resultsIndex]= 0;
adcData3[resultsIndex]= 0;
}

//
//清除所有挂起的中断标志
//
EALLOW;

DmaRegs.ch1.control.bit.PERINTCLR = 1;
DmaRegs.ch2.control.bit.PERINTCLR = 1;
DmaRegs.ch3.control.bit.PERINTCLR = 1;
DmaRegs.Ch4.control.bit.PERINTCLR = 1;
AdcaRegs.ADCINTFLGCLR.ALL = 0x3;
AdcbRegs.ADCINTFLGCLR.ALL = 0x3;
AdccRegs.ADCINTFLGCLR.ALL = 0x3;
AdcdRegs.ADCINTFLGCLR.ALL = 0x3;
EPwm2Regs.ETCNTINITCTL.bit.SOCAINITFRC= 1;
EPwm2Regs.ETCLR.bit.SOCA = 1;

//
//通过设置最后一个 SOC 来重新触发第一个//来启用连续操作

AdcaRegs.ADCINTSOCSEL1.bit.SOC0 = 2;
AdcbRegs.ADCINTSOCSEL1.bit.SOC0 = 2;
AdccRegs.ADCINTSOCSEL.bit.SOC0 = 2;
AdcdRegs.ADCINTSOCSEL.bit.SOC0 = 2;

EDIS;

//
//启动 DMA
//
完成= 0;
StartDMACH1();
StartDMACH2();
StartDMACH3();
StartDMACH4 ();

//
//最后,从 ePWM 启用 SOCA 触发。 这将在
下一个 ePWM 事件时启动//转换。
//
EPwm2Regs.ETSEL.bit.SOCAEN = 1;

//
/循环、直到 ISR 发出传输完成信号
//
while (done = 0)
{
_asm (" NOP");
}
ESTOP0;
}

////
adca1_ISR -这在第一次转换后调用并将禁用
// 以避免重新触发问题。
//
#pragma CODE_SECTION (adca1_ISR、".TI.ramfunc");
__interrupt void adca1_ISR (void)
{
//
//删除 ePWM 触发器
//
EPwm2Regs.ETSEL.bit.SOCAEN = 0;

//
//禁止再次发生此中断
//
PieCtrlRegs.PIEIER1.bit.INTx1 = 0;

//
//确认
//
PieCtrlRegs.PIEACK.all = PIEACK_Group1;
}

//
dmach1_ISR -这在 DMA 传输结束时调用,转换
// 通过从
//中删除第一个 SOC 的触发器来停止 最后一个。
//
#pragma CODE_SECTION (dmach1_ISR、".TI.ramfunc");
__interrupt void dmach1_ISR (void)
{
//
//通过移除 SOC0的触发器来停止 ADC
//
EALLOW;
AdcaRegs.ADCINTSOCSEL1.bit.SOC0 = 0;
AdcbRegs.ADCINTSOCSEL1.bit.SOC0 = 0;
AdccRegs.ADCINTSOCSEL.bit.SOC0 = 0;
AdcdRegs.ADCINTSOCSEL.bit.SOC0 = 0;
EDIS;

DONE = 1;

//
//确认
//
PieCtrlRegs.PIEACK.all = PIEACK_group7;
}

//
ConfigureEPWM -设置 ePWM2模块,以便 A 输出具有一个周期
// 占空比为50%。 SOCA 信号与
//保持一致 它的上升沿。
//
void ConfigureEPWM (void)
{
//
//使计时器计数的周期为40us
//
EPwm2Regs.TBCTL.ALL = 0x0000;
EPwm2Regs.TBPRD = 4000;

//
//将 A 输出设置为零并在 CMPA 上复位
//
EPwm2Regs.AQCTLA.bit.ZRO = AQ_SET;
EPwm2Regs.AQCTLA.bit.CAU = AQ_CLEAR;

//
//将 CMPA 设置为20us 以获得50%的占空比
//
EPwm2Regs.CMPA.bit.CMPA = 2000;

//
//在计时器等于零时启动 ADC (注:尚未启用)
//
EPwm2Regs.ETSEL.bit.SOCASEL = ET_CTR_ZERO;
EPwm2Regs.ETPS.bit.SOCAPRD = ET_1ST;

//
//启用 SOCA 事件计数器的初始化。 因为我们是这样
//禁用 ETSEL.SOCAEN 位,我们需要一种复位 SOCACNT 的方法。
// Hence、启用计数器初始化控制。
//
EPwm2Regs.ETCNTINITCTL.bit.SOCAINITEN = 1;
}

//
// ConfigureADC -写入 ADC 配置并为这两个
//都加电 ADC ADC A 和 ADC B
//
void ConfigureADC (void)
{
EALLOW;

//
//写入预分频配置
//
AdcaRegs.ADCCTL2.bit.prescale = 6;//将 ADCCLK 分频器设置为/4
AdcbRegs.ADCCTL2.bit.prescale = 6;
AdccRegs.ADCCTL2.bit.prescale = 6;
AdcdRegs.ADCCTL2.bit.prescale = 6;

//
//设置模式
//
AdcSetMode (ADC_ADCA、ADC_resolution_12位、ADC_SIGNALMODE_SINGLE);
AdcSetMode (ADC_ADCB、ADC_Resolution、12位、ADC_SIGNALMODE_SINGLE);
AdcSetMode (ADC_ADCC、ADC_Resolution、12位、ADC_SIGNALMODE_SINGLE);
AdcSetMode (ADC_ADCD、ADC_Resolution、12位、ADC_SIGNALMODE_SINGLE);

//
//将脉冲位置设置为晚期
//
AdcaRegs.ADCCTL1.bit.INTPULSEPOS=1;
AdcbRegs.ADCCTL1.bit.INTPULSEPOS = 1;
AdccRegs.ADCCTL1.bit.INTPULSEPOS = 1;
AdcdRegs.ADCCTL1.bit.INTPULSEPOS = 1;

//
//为 ADC 加电
//
AdcaRegs.ADCCTL1.bit.ADCPWDNZ = 1;
AdcbRegs.ADCCTL1.bit.ADCPWDNZ = 1;
AdccRegs.ADCCTL1.bit.ADCPWDNZ = 1;
AdcdRegs.ADCCTL1.bit.ADCPWDNZ = 1;

//
//延迟1ms 以允许 ADC 有时间上电
//
DELAY_US (1000);

EDIS;
}

//
SetupADCContinuous-设置 ADC 以在一个通道上持续转换
//
void SetupADCContinuous(volatile struct adc_regs * adcRegs、uint16 channel)
{
uint16 acqps;

//
//根据分辨率确定最小采集窗口(在 SYSCLKS 中)
//
IF (ADC_RESolution_12bit =adcRegs->ADCCTL2.bit.resolution)
{
acqps = 14;// 75ns
}
否则//分辨率为16位
{
acqps = 63;// 320ns
}

EALLOW;

//
// SOC 将在同一指定通道上转换
//
adcRegs->ADCSOC0CTL.bit.CHSEL =通道;
adcRegs->ADCSOC1CTL.bit.CHSEL =通道;
adcRegs->ADCSOC2CTL.bit.CHSEL =通道;
adcRegs->ADCSOC3CTL.bit.CHSEL =通道;
adcRegs->ADCSOC4CTL.bit.CHSEL =通道;
adcRegs->ADCSOC5CTL.bit.CHSEL =通道;
adcRegs->ADCSOC6CTL.bit.CHSEL =通道;
adcRegs->ADCSOC7CTL.bit.CHSEL =通道;
adcRegs->ADCSOC8CTL.bit.CHSEL =通道;
adcRegs->ADCSOC9CTL.bit.CHSEL =通道;
adcRegs->ADCSOC10CTL.bit.CHSEL =通道;
adcRegs->ADCSOC11CTL.bit.CHSEL =通道;
adcRegs->ADCSOC12CTL.bit.CHSEL =通道;
adcRegs->ADCSOC13CTL.bit.CHSEL =通道;
adcRegs->ADCSOC14CTL.bit.CHSEL =通道;
adcRegs->ADCSOC15CTL.bit.CHSEL =通道;

//
//采样窗口为 acqps + 1个 SYSCLK 周期
//
adcRegs->ADCSOC0CTL.bit.ACQPS = acqps;
adcRegs->ADCSOC1CTL.bit.ACQPS = acqps;
adcRegs->ADCSOC2CTL.bit.ACQPS = acqps;
adcRegs->ADCSOC3CTL.bit.ACQPS = acqps;
adcRegs->ADCSOC4CTL.bit.ACQPS = acqps;
adcRegs->ADCSOC5CTL.bit.ACQPS = acqps;
adcRegs->ADCSOC6CTL.bit.ACQPS = acqps;
adcRegs->ADCSOC7CTL.bit.ACQPS = acqps;
adcRegs->ADCSOC8CTL.bit.ACQPS = acqps;
adcRegs->ADCSOC9CTL.bit.ACQPS = acqps;
adcRegs->ADCSOC10CTL.bit.ACQPS = acqps;
adcRegs->ADCSOC11CTL.bit.ACQPS = acqps;
adcRegs->ADCSOC12CTL.bit.ACQPS = acqps;
adcRegs->ADCSOC13CTL.bit.ACQPS = acqps;
adcRegs->ADCSOC14CTL.bit.ACQPS = acqps;
adcRegs->ADCSOC15CTL.bit.ACQPS = acqps;

//
//从 EPWM2SOCA 触发 SCO0
//
adcRegs->ADCSOC0CTL.bit.TRIGSEL = 7;

//
//从 INT1触发所有其他 SOC (SOC0上的 EOC)
//
adcRegs->ADCINTSOCSEL1.bit.SOC1 = 1;
adcRegs->ADCINTSOCSEL1.bit.SOC2 = 1;
adcRegs->ADCINTSOCSEL1.bit.SOC3 = 1;
adcRegs->ADCINTSOCSEL1.bit.SOC4 = 1;
adcRegs->ADCINTSOCSEL1.bit.SOC5 = 1;
adcRegs->ADCINTSOCSEL1.bit.SOC6 = 1;
adcRegs->ADCINTSOCSEL1.bit.SOC7 = 1;
adcRegs->ADCINTSOCSEL2.bit.SOC8 = 1;
adcRegs->ADCINTSOCSEL2.bit.SOC9 = 1;
adcRegs->ADCINTSOCSEL2.bit.SOC10 = 1;
adcRegs->ADCINTSOCSEL2.bit.SOC11 = 1;
adcRegs->ADCINTSOCSEL2.bit.SOC12=1;
adcRegs->ADCINTSOCSEL2.bit.SOC13 = 1;
adcRegs->ADCINTSOCSEL2.bit.SOC14 = 1;
adcRegs->ADCINTSOCSEL2.bit.SOC15 = 1;

adcRegs->ADCINTSEL1N2.bit.INT1E = 1;//启用 INT1标志
adcRegs->ADCINTSEL1N2.bit.INT2E = 1;//启用 INT2标志
adcRegs->ADCINTSEL3N4.bit.INT3E = 0;//禁用 INT3标志
adcRegs->ADCINTSEL3N4.bit.INT4E = 0;//禁用 INT4标志

adcRegs->ADCINTSEL1N2.bit.INT1CONT = 1;
adcRegs->ADCINTSEL1N2.bit.INT2CONT = 1;

adcRegs->ADCINTSEL1N2.bit.INT1SEL = 0;// SOC0结束
adcRegs->ADCINTSEL1N2.bit.INT2SEL = 15;// SOC15结束

EDIS;
}

//
// DMAInit -初始化 DMA 通道1以将 ADCA 结果和 DMA 通道2传输到
// 传输 ADCB 结果
//
void DMAInit (void)
{
//
//初始化 DMA
//
DMAInitialize();

//
//为第一个 ADC 设置 DMA
//
DMACH1AddrConfig (adcData0、&AdcResultRegs.ADCRESULT0);

//
//执行足够的16字突发来填充结果缓冲区。 数据将是
//一次传输32位,因此地址步进如下。
//
//启用 DMA 通道1中断
//
DMACH1BurstConfig (15、2、2);
DMACH1TransferConfig ((results_buffer_size >> 4)- 1、-14、2);
DMACH1ModeConfig (
DMA_ADCAINT2、
PERINT_ENABLE、
OneShot_disable、
CONT_DISABLE、
SYNC_DISABLE、
SYNC_SRC、
OVRFLOW_DISABLE、
三十二位、
Chint_end、
Chint_enable);

//
//为第二个 ADC 设置 DMA
//
DMACH2AddrConfig (adcData1、&AdcbResultRegs.ADCRESULT0);

//
//执行足够的16字突发来填充结果缓冲区。 数据将是
//一次传输32位,因此地址步进如下。
//
DMACH2BurstConfig (15、2、2);
DMACH2TransferConfig (((results_buffer_size >> 4)- 1、-14、2);
DMACH2ModeConfig (
DMA_ADCAINT2、
PERINT_ENABLE、
OneShot_disable、
CONT_DISABLE、
SYNC_DISABLE、
SYNC_SRC、
OVRFLOW_DISABLE、
三十二位、
Chint_end、
Chint_disable);

//
//为第三个 ADC 设置 DMA
//
DMACH3AddrConfig (adcData2、&AdccResultRegs.ADCRESULT0);

//
//执行足够的16字突发来填充结果缓冲区。 数据将是
//一次传输32位,因此地址步进如下。
//
DMACH3BurstConfig (15、2、2);
DMACH3TransferConfig ((results_buffer_size >> 4)- 1、-14、2);
DMACH3ModeConfig (
DMA_ADCAINT2、
PERINT_ENABLE、
OneShot_disable、
CONT_DISABLE、
SYNC_DISABLE、
SYNC_SRC、
OVRFLOW_DISABLE、
三十二位、
Chint_end、
Chint_disable);

//
//为第四个 ADC 设置 DMA
//
DMACH4AddrConfig (adcData3、&AdcdResultRegs.ADCRESULT0);

//
//执行足够的16字突发来填充结果缓冲区。 数据将是
//一次传输32位,因此地址步进如下。
//
DMACH4BurstConfig (15、2、2);
DMACH4TransferConfig ((results_buffer_size >> 4)- 1、-14、2);
DMACH4ModeConfig (
DMA_ADCAINT2、
PERINT_ENABLE、
OneShot_disable、
CONT_DISABLE、
SYNC_DISABLE、
SYNC_SRC、
OVRFLOW_DISABLE、
三十二位、
Chint_end、
Chint_disable);
}

//
//文件结束
//

它可以毫无问题地运行、并且由 ADC a、b 和 c 获取的数据是正确的。 但在这里、当我使用 ADC d 获取正弦波时、我看到的是:

每16个样本就会出现一次毛刺脉冲、即 SOC 的数量。 我只有在同时使用四个 ADC 时才会遇到这个问题。 例如、如果我排除 ADC c、则只需注释启动 DMA CH3的代码

//
//启动 DMA
//
完成= 0;
StartDMACH1();
StartDMACH2();
//StartDMACH3();
StartDMACH4();

然后、我在 ADC d 上获得非常干净的结果。这怎么可能呢?

此致

弗朗西斯科

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

    尊敬的 Francesco:

          我认为、当前的情况是、当所有 ADC 运行时、DMA 传输和 SOC 触发的组合会导致您的代码在正确的点错过采样。  一旦从中断触发 SOC 进行转换、ADC 立即开始采样、第一步是让 S+H 电路在 ACQPS (即 SYSCLK 周期数+1)中定义的持续时间内对信号进行采样、 然后、根据使用的预分频器、ADC 宏需要几个 SYSCLK 周期来解析数字格式的采样信号。  对于您的特定代码、S+H 时间与生成数字结果的延迟时间约为58个 SYSCLK 周期。  您可以通过查看参考手册 SPRUHM8G (第1412页)中的时序图和表格来得出此结果。 这意味着、从中断激活到数字结果为每个 SOC 准备就绪、每个被转换的 SOC 将需要这个周期数。  对于15个 SOC (请注意、第一个 SOC 由 ePWM 触发)、总时间将至少为870个 SYSCLK 周期。  这意味着您的代码应该能够在这个持续时间内将4个 ADC 中的所有数据从结果寄存器传输到 SRAM、否则您将会错过一些数据的传输。  这可能是您的代码所发生的情况。

    您可以尝试或尝试以下建议:

        -尝试递增 ePWM 触发器的周期(降低频率)。  这将为 ADC 提供更多时间用于 S+H 以及转换和数据传输

        -也将 SOC 触发器分配给 ADCINT2。  当前代码仅在 ADCINT1上触发。  由于后台的数据传输以及中断生成、S+H 和转换同时发生、某些 SOC 上的采样可能会关闭。  您可以通过修改 SOC 触发器来执行此操作

    发件人:

       //
       //从 INT1触发所有其他 SOC (SOC0上的 EOC)
       //
       adcRegs->ADCINTSOCSEL1.bit.SOC1 = 1;
       adcRegs->ADCINTSOCSEL1.bit.SOC2 = 1;
       adcRegs->ADCINTSOCSEL1.bit.SOC3 = 1;
       adcRegs->ADCINTSOCSEL1.bit.SOC4 = 1;
       adcRegs->ADCINTSOCSEL1.bit.SOC5 = 1;
       adcRegs->ADCINTSOCSEL1.bit.SOC6 = 1;
       adcRegs->ADCINTSOCSEL1.bit.SOC7 = 1;
       adcRegs->ADCINTSOCSEL2.bit.SOC8 = 1;
       adcRegs->ADCINTSOCSEL2.bit.SOC9 = 1;
       adcRegs->ADCINTSOCSEL2.bit.SOC10 = 1;
       adcRegs->ADCINTSOCSEL2.bit.SOC11 = 1;
       adcRegs->ADCINTSOCSEL2.bit.SOC12=1;
       adcRegs->ADCINTSOCSEL2.bit.SOC13 = 1;
       adcRegs->ADCINTSOCSEL2.bit.SOC14 = 1;
       adcRegs->ADCINTSOCSEL2.bit.SOC15 = 1;

       adcRegs->ADCINTSEL1N2.bit.INT1E = 1;   //启用 INT1标志
       adcRegs->ADCINTSEL1N2.bit.INT2E = 1;   //启用 INT2标志
       adcRegs->ADCINTSEL3N4.bit.INT3E = 0;   //禁用 INT3标志
       adcRegs->ADCINTSEL3N4.bit.INT4E = 0;   //禁用 INT4标志

       adcRegs->ADCINTSEL1N2.bit.INT1CONT = 1;
       adcRegs->ADCINTSEL1N2.bit.INT2CONT = 1;

       adcRegs->ADCINTSEL1N2.bit.INT1SEL = 0; // SOC0结束
       adcRegs->ADCINTSEL1N2.bit.INT2SEL = 15;// SOC15结束

    至:

       //
       //触发来自 INT1 和 INT2的所有其他 SOC
       //
       adcRegs->ADCINTSOCSEL1.bit.SOC1 = 1;  // ADCINT1将触发低于 SOC (SOC1-SOC7)
       adcRegs->ADCINTSOCSEL1.bit.SOC2 = 1;
       adcRegs->ADCINTSOCSEL1.bit.SOC3 = 1;
       adcRegs->ADCINTSOCSEL1.bit.SOC4 = 1;
       adcRegs->ADCINTSOCSEL1.bit.SOC5 = 1;
       adcRegs->ADCINTSOCSEL1.bit.SOC6 = 1;
       adcRegs->ADCINTSOCSEL1.bit.SOC7 = 1;
       adcRegs->ADCINTSOCSEL2.bit.SOC8 = 2;   // ADCINT2将触发低于 SOC (SOC8-SOC15)
       adcRegs->ADCINTSOCSEL2.bit.SOC9 = 2;
       adcRegs->ADCINTSOCSEL2.bit.SOC10 = 2;
       adcRegs->ADCINTSOCSEL2.bit.SOC11 = 2;
       adcRegs->ADCINTSOCSEL2.bit.SOC12 = 2;
       adcRegs->ADCINTSOCSEL2.bit.SOC13 = 2;
       adcRegs->ADCINTSOCSEL2.bit.SOC14 = 2;
       adcRegs->ADCINTSOCSEL2.bit.SOC15 = 2;

       adcRegs->ADCINTSEL1N2.bit.INT1E = 1;   //启用 INT1标志
       adcRegs->ADCINTSEL1N2.bit.INT2E = 1;   //启用 INT2标志
       adcRegs->ADCINTSEL3N4.bit.INT3E = 0;   //禁用 INT3标志
       adcRegs->ADCINTSEL3N4.bit.INT4E = 0;   //禁用 INT4标志

       adcRegs->ADCINTSEL1N2.bit.INT1CONT = 1;
       adcRegs->ADCINTSEL1N2.bit.INT2CONT = 1;

       adcRegs->ADCINTSEL1N2.bit.INT1SEL = 0; // SOC0结束将触发 ADCINT1
       adcRegs->ADCINTSEL1N2.bit.INT2SEL = 7;// SOC7结束将触发 ADCINT2

    请告诉我这些选项中的任何一个是否适合您。

    此致、

    Joseph

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

    您好、Joseph、

    不幸的是、您的解决方案无法正常工作、但我终于设法使其正常工作。  出于某些原因我仍然不理解、DMA CH4传输错误的 ADCD 结果、就好像 SOC0没有足够的时间在 DMA 获取值并在缓冲区中传输之前完成转换一样。 我不知道这是真正的问题,但我在设计解决方案时考虑到了这一解释,它是有效的。

    使用我的第一个帖子的相同代码作为参考、我已激活 ADCINT3中断并将其设置为在 SOC7结束时激活

    adcRegs->ADCINTSEL3N4.bit.INT3E = 1;//启用 INT3标志
    adcRegs->ADCINTSEL3N4.bit.INT3CONT = 1;//将 INT3设置为晚期模式
    adcRegs->ADCINTSEL3N4.bit.INT3SEL = 7;// SOC7结束 

    然后、我修改了 DMA 通道4并添加了 DMA 通道5:

    DMACH4AddrConfig (adcData3、&AdcdResultRegs.ADCRESULT0);
    
    DMACH4BurstConfig (7、2、2);
    DMACH4TransferConfig (((results_buffer_size >> 4)- 1、-6、10);
    DMACH4ModeConfig (
    DMA_ADCDINT3、
    PERINT_ENABLE、
    OneShot_disable、
    CONT_DISABLE、
    SYNC_DISABLE、
    SYNC_SRC、
    OVRFLOW_DISABLE、
    三十二位、
    Chint_end、
    Chint_disable);
    
    DMACH5AddrConfig (adcData3 + 8、&AdcdResultRegs.ADCRESULT8);
    
    DMACH5BurstConfig (7、2、 2);
    DMACH5TransferConfig ((Results_buffer_size >> 4)- 1、-6、10);
    DMACH5ModeConfig (
    DMA_ADCDINT2、
    PERINT_ENABLE、
    OneShot_disable、
    CONT_DISABLE、
    SYNC_DISABLE、
    SYNC_SRC、
    OVRFLOW_DISABLE、
    三十二位、
    Chint_end、
    Chint_disable); 

    在该实现中、当 SOC7结束时、DMA CH4开始传输前八个值、而 SOC8到 SOC15开始采集。
    当 SOC15结束时、DMA CH5开始传输第二个八个值、而 SOC0到 SOC7再次启动。
    所有 SOC 的值都使用适当的索引以正确的顺序存储在缓冲器中。

    总之、采集和转移处于反相状态、因此它们永远不会重叠。 这样我就得到了正确的结果。

    此致

    弗朗西斯科