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/LAUNCHXL-F2.8377万S:来自ADC的DMA传输

Guru**** 2551110 points
Other Parts Discussed in Thread: CONTROLSUITE

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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/629166/ccs-launchxl-f28377s-dma-transfer-from-adc

部件号:LAUNCHXL-F2.8377万S

工具/软件:Code Composer Studio

伙计们,

我希望使用DMA从ADC收集数据。

我写了这个代码,你能帮我理解故障吗? 是否可以检查ADC和DMA的设置?

#include "F28x_Project.h"// Device Headerfile and examples include File
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <ctype.h>





#define RFFT_stages 11
#define RFFT_size (1<<<<<<<<<<<<stidio_stepers>#include <mation.h>#include <city.h>#include <cType.h>#include <ct><cype <cype <ct>#define RFFT_stages)#defect RFFT_step_stages 11 #def?br>阶段#define RFid_DMf_size #def_size (1void






)

//ADC,PWM
void ConfigureEPWM (void);
void SetupADCEpwm (UINT16通道);

中断void adca1_ISR(void);//ADC ISR

volatile UINT16 bufferFull;
volatile UINT16 results Index;



void main(void)

{//



步骤1. 初始化系统控制:
// PLL,看门狗,启用外设时钟
//此示例功能可在F2837xS_sysctrl.c文件中找到。
InitSysCtrl();//

步骤2. 初始化GPIO:
//此示例函数可在F2837xS_GPIO .c文件中找到,
//说明了如何将GPIO设置为其默认状态。
InitGpio();//跳过此示例


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

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

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

//使用指向shell Interrupt
//服务例程(ISR)的指针初始化PIE矢量表。
//这将填充整个表,即使在此
示例中未使用中断//。 这对于调试非常有用。
// shell ISR例程位于F2837xS_DefaultIsr.C.中
//此函数位于F2837xS_PieVect.C.中
InitPieVectorTable();





//Map ISR函数
EALLOW;
PieVectorTable.ADCA1_INT =&adca1_ISR;// ADCA中断1的函数
PieVectorTable.DMA_CH1_INT =&LOCALE_DMACH1_ISR;// DMA中断1的函数
EDIS;



//配置ADC并开机
ConfigureADC();//

配置ePWM
ConfigureEPWM();

//在通道0上设置ePWM触发转换的ADC
SetupADCEpwm(0);

DMA_CONFIG();


//启用全局中断和较高优先级的实时调试事件:
//IER || M_INT1;//启用组1中断
IER || M_INT7;
EINT;//启用全局中断INTM
ERTM;//启用全局实时中断DBGM

缓冲器全轮= 0;

EINT;//启用全局中断

//启用PIE中断
PieCtrlRegs.PIEIER1.bit.INTx1 = 1;


//sync ePWM
EALLOW;
CpuSysRegs.PCLKCR0.bit.TBCLKSYNC = 1;
EDIS;

//启动ePWM
EPwm1Regs.ETSEL.bit.SOCAEN = 1;//启用SOCA
EPwm1Regs.TBCTL.bit.CTRMODE = 0;//unfreeze,并进入UP计数模式

while (!bufferFull);
bufferFull = 0;//清除缓冲区已满标志
ASM (" ESTOP0");
while (1);

}//




写入ADC配置,并为ADC A和ADC B
void ConfigureADC(void)
{打开ADC的电源
EALLOW;

//写入配置
AdcaRegs.ADCCTL2.bit.prescale = 0b0110;//将ADCCLK除法器设置为/4
AdcSetMode (ADC_ADCA,ADC_Resolution _12位,ADC_SIGNALMODE_SINGLE);
// AdcSetMode (ADC_ADCA,ADC_Resolution _16BIT,ADC_SIGNALMODE_DIFFERENTIAL);


//将脉冲位置设置为延迟
AdcaRegs.ADCCTL1.bit.INTPULSEPOS = 1;

//打开ADC的电源
AdcaRegs.ADCCTL1.bit.ADCPWDNZ = 1;


//延迟1毫秒,以使ADC有时间开机
DELAY _US (1000);

EDIS;
}

void ConfigureEPWM (void)
{
EALLOW;
//假定ePWM时钟已启用

EPwm1Regs.ETSEL.bit.SOCAEN = 0; //禁用组上的SOC
EPwm1Regs.ETSEL.bit.SOCASEL = 4; //在计数时选择SOC
EPwm1Regs.ETPS.bit.SOCAPRD = 1; //在第一个事件上生成脉冲
EPwm1Regs.CMPA.bit.CMPA = 311;
EPwm1Regs.TBPRD = 624;
EPwm1Regs.TBCTL.bit.CTRMODE = 3; //冻结计数器
EDIS;
}

void SetupADCEpwm (UINT16通道)
{
UINT16 acqps;

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

//选择要转换的通道和转换结束标志
EALLOW;
AdcaRegs.ADCSOC0CTL.bit.CHSEL =通道;//SOC0将转换针A0

AdcaRegs.ADCSOC0CTL.bit.ACQPS = acqps;//样例窗口为100 SYSCLK周期

AdcaRegs.ADCSOC0CTL.bit.TRIGSEL = 5;// ePWM1 SOCA/C上的触发器

AdcaRegs.ADCINTSEL1N2.bit.INT1SEL = 0;//SOC0的结尾将设置INT1标志

AdcaRegs.ADCINTSEL1N2.bit.INT1E = 1;//启用INT1标志

AdcaRegs.ADCINTFLGCLL.bit.ADCINT1 =1;//确保INT1标志已清除
}


中断无效adca1_ISR(void){


ADCin1Buff[resultsIndex+]=(AddaResultRegs.ADCRESULT0);
IF (RFFT_Size<=resultsIndex)
{
结果索引=0;
缓冲区完全= 1;
}

ADcaRegs.ADCINTFLGCLL.bit.ADCINT1 = 1;//清除INT1标志
PieCtrlRegs.PIEACK_ALL = PIEACK_Group1;
}

中断void local_DMACH1_ISR(void)
{
//dma_done = 0x0001;
EALLOW;
PieCtrlRegs.PIEACK.ALL = PIEACK_group7;
//DmaRegs.CH1.control.bit.TRANSFERSTS = 1;
//DmaRegs.CH1.control.bit.run = 1;
缓冲器全轮= 1;
EDIS;
// ESTOP0;
}

void dma_configure(void)
{

DMAInitialize();

DMACH1AddrConfig(((volatile UINT16 *)ADCin1Buff,&AdcaResultRegs.ADCRESULT0);

DMACH1BurstConfig(15,0,2);

DMACH1TransferConfig((RFFT_Size >>4)-1),0,2);

DMACH1ModeConfig( DMA_ADCAINT1,
PERINT_ENABLE,
OneShot_disable,
con_disable,
SYNC_DISABLE,
SYNC_SRC,
OVRFLOW_DISABLE,
32位,
Chint_End,
Chint_enable);
StartDMACH1();}

非常感谢。

此致

Paolo Marsilia

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

    抱歉,我们不支持在论坛上审核/调试您的代码。 您是否有一个尖锐的问题(或)解释故障是什么?

    我希望您已经完成了我们的controlSUITE示例。

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

    抱歉,我不知道您不支持代码审查/调试。
    我想使用DMA将数据从ADC传输到RAM,然后在缓冲区满后处理;换言之,我想替换ADC_SOC_ePWM_cpu01示例的技术,使用DMA避免等待缓冲区填充,从而增加带宽。

    有人可以帮助正确配置DMA?

    谢谢你
    此致

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

    Paolo,

    controlSUITE中有多个示例解释如何配置DMA。 请检查它们。 这将帮助您入门并为您提供如何在ADC上下文中使用DMA的想法。

    此致,

    Manoj

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

    此致