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.
在 controlSUITE 中有关 ADC_DMA 的新版本示例中。 我有一个问题。如果我想在重复按 RESUME button.no时连续刷新缓冲区中的数据、而不是只执行一次。我该怎么办?谢谢
您好、Jiang、
您能给我指一下您所指的示例吗?
谢谢
Vasudha
谢谢、以下是代码
//######################################################################################################################
//
//文件: adc_soc _continuous_dma_cpu01.c
//
//标题: ADC 连续转换由 DMA 为 F2837xD 读取。
//
//! addtogroup cpu01_example_list
//!
//!
//! 此示例设置两个 ADC 通道以同时转换。 。
//! 结果将由 DMA 传输到 RAM 中的缓冲区中。
//!
//! 程序运行后、存储器将包含:
//!
//! -\b adcData0 \b:引脚 A3\n 上电压的数字表示
//! -\b adcData1 \b:引脚 B3\n 上电压的数字表示
//!
//
//######################################################################################################################
//$TI 发行版:F2837xD 支持库 v3.04.00.00 $
//$Release Date:Sun Mar 25 13:26:04 CDT 2018 $
//版权所有:
//版权所有(C) 2013-2018 Texas Instruments Incorporated -
//
//以源代码和二进制形式重新分发和使用,有无
//如果满足以下条件,则允许进行修改
//满足:
//
// 重新分发源代码必须保留上述版权
// 注意、此条件列表和以下免责声明。
//
// 二进制形式的重新分发必须复制上述版权
// 注意、中的条件列表和以下免责声明
// 随提供的文档和/或其他材料
// 分布。
//
// 德州仪器公司的名称和的名称都不是
// 其贡献者可用于认可或推广衍生产品
// 未经特定的事先书面许可,从该软件下载。
//
//本软件由版权所有者和作者提供
//“原样”以及任何明示或暗示的保证,包括但不包括
//限于对适销性和适用性的暗示保证
//一个特定的目的是免责的。 在任何情况下、版权均不得
//所有者或贡献者应对任何直接、间接、偶然、
//特殊、典型或必然的损害(包括但不包括)
//仅限于采购替代货物或服务;
//数据或利润;或业务中断)
//责任理论,无论是合同责任、严格责任还是侵权行为
//(包括疏忽或其他)以任何方式因使用而产生
//此软件,即使已被告知可能会发生此类损坏。
//$
//######################################################################################################################
//
//包含的文件
//
#include "F28x_Project.h"
//
//函数原型
//
_interrupt void adca1_ISR (void);
_interrupt void dmach1_isr (void);
void ConfigureEPWM (void);
void ConfigureADC (void);
void SetupADCContinuid (volatile struct adc_regs * adcRegs、uint16通道);
void DMAInit (void);
//
//定义
//
#define Results_buffer_size 1024 //用于存储转换结果的缓冲器
//(大小必须是16的倍数)
//
//全局
//
#pragma DATA_SECTION (adcData0、"ramgs0");
#pragma DATA_SECTION (adcData1、"ramgs0");
uint16 adcData0[results_buffer_size];
uint16 adcData1[results_buffer_size];
易失性 uint16完成;
void main (void)
{
uint16结果索引;
//
//步骤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;
//
//使用指向 shell 中断的指针初始化 PIE 矢量表
//服务例程(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();
//
//在通道 A3和 B3上设置用于连续转换的 ADC
//
SetupADCContinuimal(&AdcRegs, 3);
SetupADCContinuimal(&AdcbRegs, 3);
//
//初始化 DMA
//
DMAInit();
//
//启用全局中断和更高优先级的实时调试事件:
//
EINT; //启用全局中断 INTM
ERTM; //启用全局实时中断 DBGM
//
//初始化结果缓冲区
//
for (resultsIndex = 0;resultsIndex < results_buffer_size;resultsIndex++)
{
adcData0[resultsIndex]= 0;
adcData1[resultsIndex]= 0;
}
//
//清除所有挂起的中断标志
//
EALLOW;
DmaRegs.ch1.control.bit.PERINTCLR = 1;
DmaRegs.ch2.control.bit.PERINTCLR = 1;
AdcaRegs.ADCINTFLGCLR.ALL = 0x3;
AdcbRegs.ADCINTFLGCLR.ALL = 0x3;
EPwm2Regs.ETCNTINITCTL.bit.SOCAINITFRC= 1;
EPwm2Regs.ETCLR.bit.SOCA = 1;
//
//通过将最后一个 SOC 设置为重新触发第一个 SOC 来启用连续操作
//
AdcaRegs.ADCINTSOCSEL1.bit.SOC0 = 2;
AdcbRegs.ADCINTSOCSEL1.bit.SOC0 = 2;
EDIS;
//
//启动 DMA
//
完成= 0;
StartDMACH1();
StartDMACH2();
//
//最后,从 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.PIEACX.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;
EDIS;
DONE = 1;
//
//确认
//
PieCtrlRegs.PIEACX.ALL = PIEACK_group7;
}
//
// ConfigureEPWM -设置 ePWM2模块,使 A 输出具有一个周期
// 占空比为50%。 SOCA 信号与保持一致
// 它的上升沿。
//
空配置 EPWM (空)
{
//
//使计时器计数的周期为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 A 和 ADC B
//
空配置 ADC (空)
{
EALLOW;
//
//写入预分频配置
//
AdcaRegs.ADCCTL2.bit.prescale = 6;//将 ADCCLK 分频器设置为/4
AdcbRegs.ADCCTL2.bit.prescale = 6;
//
//设置模式
//
AdcSetMode (ADC_ADCA、ADC_resolution_12位、ADC_SIGNALMODE_SINGLE);
AdcSetMode (ADC_ADCB、ADC_Resolution、12位、ADC_SIGNALMODE_SINGLE);
//
//将脉冲位置设置为晚期
//
AdcaRegs.ADCCTL1.bit.INTPULSEPOS=1;
AdcbRegs.ADCCTL1.bit.INTPULSEPOS = 1;
//
//为 ADC 加电
//
AdcaRegs.ADCCTL1.bit.ADCPWDNZ = 1;
AdcbRegs.ADCCTL1.bit.ADCPWDNZ = 1;
//
//延迟1ms 以允许 ADC 有时间上电
//
DELAY_US (1000);
EDIS;
}
//
// SetupADCContinuously -设置 ADC 在一个通道上持续转换
//
void SetupADCContinuid (volatile struct adc_regs * adcRegs、uint16通道)
{
uint16 acqps;
//
//根据分辨率确定最小采集窗口(在 SYSCLKS 中)
//
if (adc_resolution_12bit = AdcaRegs.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->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 结果
//
空 DMAInit (空)
{
//
//初始化 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
);
}
//
//文件结束
//
e2e.ti.com/.../continous_5F00_adc_5F00_dma_5F00_capture.c
您好、Jiang、
很抱歉耽误你的回答。 请查找随附的用于执行连续转换的更新代码。 基本上、当前示例删除了 DMA ISR 中的 SOC0触发器并将 DONE 置为1、应从示例中删除该触发器。 此外、还应为 DMA 启用连续模式。 请告诉我这是否解决了您的问题。
此示例是 C2000Ware 的一部分、因此会造成混淆。
谢谢
Vasudha
Vasudha.非常感谢。它工作正常。我可以在 DMA 中更新数组中的值。但我遇到了另一个问题。当我在 ADC 中调整16位模式的代码时。该值始终定期在特殊位中保持相同的值。例如 adcResultx[8] adcResultx[24] adcultx[40] adcResultx[72] adcResultrx[56] 、 Resultrx[56] adcResultx[72] 始终为42286。因此数组的图形不能是 continuous.it、这不是一个平滑的图形、每16个数字就会损坏一次。顺便说一下、我只能在" AdcSetMode (ADC_ADCA、ADC_Resolution _12bit、 ADC_SIGNALMODE_SINGLE);"对于16位 ADC、我将12位更改为16位、将 SIGNALMODE 更改为 DIFFRERNTMODE。我认为是在12位 ADC 上探测 caused.no。所以我有 confused.ca、您会给我一些建议吗?