TI中文支持网
TI专业的中文技术问题搜集分享网站

F28335 ePWM AD频率设置问题

使用ePWM事件触发方式启动AD转换,转换频率为6M,请问该怎么设置啊,自己按照官网的例程修改的程序EPwm1Regs.CMPA.half.CMPA = 6; 

EPwm1Regs.TBPRD = 12,用示波器量出来只有212KHz,请问是什么原因,初始化程序如下:

EALLOW;
SysCtrlRegs.HISPCP.all = ADC_MODCLK; // HSPCLK = SYSCLKOUT/ADC_MODCLK
EDIS;

//— Peripheral Initialization
InitAdc();// Initialize the ADC (FILE: Adc.c)

// Interrupts that are used in this example are re-mapped to
// ISR functions found within this file.
EALLOW; // This is needed to write to EALLOW protected register
PieVectTable.ADCINT = &adc_isr;
EDIS;// This is needed to disable write to EALLOW protected registers

AdcRegs.ADCTRL1.bit.ACQ_PS = ADC_SHCLK;
AdcRegs.ADCTRL3.bit.ADCCLKPS = ADC_CKPS;

AdcRegs.ADCTRL1.bit.SEQ_CASC = 1;

AdcRegs.ADCTRL3.bit.SMODE_SEL = 0;

AdcRegs.ADCTRL1.bit.CONT_RUN = 0;
// Enable Sequencer override feature
AdcRegs.ADCTRL1.bit.SEQ_OVRD = 1;
// Initialize all ADC channel selects to A0
AdcRegs.ADCCHSELSEQ1.all = 0x0;
AdcRegs.ADCCHSELSEQ2.all = 0x0;
AdcRegs.ADCCHSELSEQ3.all = 0x0;
AdcRegs.ADCCHSELSEQ4.all = 0x0;

AdcRegs.ADCCHSELSEQ1.bit.CONV00 = 0;

AdcRegs.ADCMAXCONV.bit.MAX_CONV1 = 0;

AdcRegs.ADCTRL2.bit.EPWM_SOCA_SEQ1 = 1;// Enable SOCA from ePWM to start SEQ1

AdcRegs.ADCTRL2.bit.INT_ENA_SEQ1 = 1; // Enable SEQ1 interrupt (every EOS)

EPwm1Regs.ETSEL.bit.SOCAEN = 1; // Enable SOC on A group

EPwm1Regs.ETSEL.bit.SOCASEL = 4; // Select SOC from from CPMA on upcount

EPwm1Regs.ETPS.bit.SOCAPRD = 1; // Generate pulse on 1st event

EPwm1Regs.CMPA.half.CMPA = 6; // Set compare A value

EPwm1Regs.TBPRD = 12; // Set period for ePWM1

EPwm1Regs.TBCTL.bit.CTRMODE = 0; // count up and start

// Enable ADCINT in PIE
PieCtrlRegs.PIEIER1.bit.INTx6 = 1;
IER |= M_INT1; // Enable CPU Interrupt 1
EINT; // Enable Global interrupt INTM
ERTM; // Enable Global realtime interrupt DBGM

10#:

Feng Youkui Feng Youkui

EPwm1Regs.CMPA.half.CMPA = 6; EPwm1Regs.TBPRD = 12,用示波器量出来只有212KHz,请问是什么原因,初始化程序如下:

212kHz具体测量的是什么信号的频率?下面的其它配置里修改部分参数会怎样?

Feng Youkui Feng Youkui

EALLOW; SysCtrlRegs.HISPCP.all = ADC_MODCLK; // HSPCLK = SYSCLKOUT/ADC_MODCLK EDIS;

//— Peripheral Initialization InitAdc();// Initialize the ADC (FILE: Adc.c)

// Interrupts that are used in this example are re-mapped to // ISR functions found within this file. EALLOW; // This is needed to write to EALLOW protected register PieVectTable.ADCINT = &adc_isr; EDIS;// This is needed to disable write to EALLOW protected registers

AdcRegs.ADCTRL1.bit.ACQ_PS = ADC_SHCLK; AdcRegs.ADCTRL3.bit.ADCCLKPS = ADC_CKPS;

这里的ADC_MODCLK,ADC_SHCLK,ADC_CKPS宏定义的值具体是多少?

如果

EPwm1Regs.ETSEL.bit.SOCAEN = 1;

改成

EPwm1Regs.ETSEL.bit.SOCAEN = 0;

会怎样?

使用ePWM事件触发方式启动AD转换,转换频率为6M,请问该怎么设置啊,自己按照官网的例程修改的程序EPwm1Regs.CMPA.half.CMPA = 6; 

EPwm1Regs.TBPRD = 12,用示波器量出来只有212KHz,请问是什么原因,初始化程序如下:

EALLOW;
SysCtrlRegs.HISPCP.all = ADC_MODCLK; // HSPCLK = SYSCLKOUT/ADC_MODCLK
EDIS;

//— Peripheral Initialization
InitAdc();// Initialize the ADC (FILE: Adc.c)

// Interrupts that are used in this example are re-mapped to
// ISR functions found within this file.
EALLOW; // This is needed to write to EALLOW protected register
PieVectTable.ADCINT = &adc_isr;
EDIS;// This is needed to disable write to EALLOW protected registers

AdcRegs.ADCTRL1.bit.ACQ_PS = ADC_SHCLK;
AdcRegs.ADCTRL3.bit.ADCCLKPS = ADC_CKPS;

AdcRegs.ADCTRL1.bit.SEQ_CASC = 1;

AdcRegs.ADCTRL3.bit.SMODE_SEL = 0;

AdcRegs.ADCTRL1.bit.CONT_RUN = 0;
// Enable Sequencer override feature
AdcRegs.ADCTRL1.bit.SEQ_OVRD = 1;
// Initialize all ADC channel selects to A0
AdcRegs.ADCCHSELSEQ1.all = 0x0;
AdcRegs.ADCCHSELSEQ2.all = 0x0;
AdcRegs.ADCCHSELSEQ3.all = 0x0;
AdcRegs.ADCCHSELSEQ4.all = 0x0;

AdcRegs.ADCCHSELSEQ1.bit.CONV00 = 0;

AdcRegs.ADCMAXCONV.bit.MAX_CONV1 = 0;

AdcRegs.ADCTRL2.bit.EPWM_SOCA_SEQ1 = 1;// Enable SOCA from ePWM to start SEQ1

AdcRegs.ADCTRL2.bit.INT_ENA_SEQ1 = 1; // Enable SEQ1 interrupt (every EOS)

EPwm1Regs.ETSEL.bit.SOCAEN = 1; // Enable SOC on A group

EPwm1Regs.ETSEL.bit.SOCASEL = 4; // Select SOC from from CPMA on upcount

EPwm1Regs.ETPS.bit.SOCAPRD = 1; // Generate pulse on 1st event

EPwm1Regs.CMPA.half.CMPA = 6; // Set compare A value

EPwm1Regs.TBPRD = 12; // Set period for ePWM1

EPwm1Regs.TBCTL.bit.CTRMODE = 0; // count up and start

// Enable ADCINT in PIE
PieCtrlRegs.PIEIER1.bit.INTx6 = 1;
IER |= M_INT1; // Enable CPU Interrupt 1
EINT; // Enable Global interrupt INTM
ERTM; // Enable Global realtime interrupt DBGM

Feng Youkui Feng Youkui:

回复 10#:

212kHz具体测量的是进入中断后在中断函数里翻转GPIO口 用示波器测量得到的 2*106KHz

#if (CPU_FRQ_150MHZ) // Default – 150 MHz SYSCLKOUT #define ADC_MODCLK 0x3 // HSPCLK = SYSCLKOUT/2*ADC_MODCLK2 = 150/(2*3) = 25.0 MHz#endif

#define ADC_CKPS 0x0 // ADC module clock = HSPCLK/1 = 25.5MHz/(1) = 25.0 MHz#define ADC_SHCLK 0x1 // S/H width in ADC module periods

EPwm1Regs.ETSEL.bit.SOCAEN = 1;

改成

EPwm1Regs.ETSEL.bit.SOCAEN = 0;后不能正常进入adc_isr中断函数

使用ePWM事件触发方式启动AD转换,转换频率为6M,请问该怎么设置啊,自己按照官网的例程修改的程序EPwm1Regs.CMPA.half.CMPA = 6; 

EPwm1Regs.TBPRD = 12,用示波器量出来只有212KHz,请问是什么原因,初始化程序如下:

EALLOW;
SysCtrlRegs.HISPCP.all = ADC_MODCLK; // HSPCLK = SYSCLKOUT/ADC_MODCLK
EDIS;

//— Peripheral Initialization
InitAdc();// Initialize the ADC (FILE: Adc.c)

// Interrupts that are used in this example are re-mapped to
// ISR functions found within this file.
EALLOW; // This is needed to write to EALLOW protected register
PieVectTable.ADCINT = &adc_isr;
EDIS;// This is needed to disable write to EALLOW protected registers

AdcRegs.ADCTRL1.bit.ACQ_PS = ADC_SHCLK;
AdcRegs.ADCTRL3.bit.ADCCLKPS = ADC_CKPS;

AdcRegs.ADCTRL1.bit.SEQ_CASC = 1;

AdcRegs.ADCTRL3.bit.SMODE_SEL = 0;

AdcRegs.ADCTRL1.bit.CONT_RUN = 0;
// Enable Sequencer override feature
AdcRegs.ADCTRL1.bit.SEQ_OVRD = 1;
// Initialize all ADC channel selects to A0
AdcRegs.ADCCHSELSEQ1.all = 0x0;
AdcRegs.ADCCHSELSEQ2.all = 0x0;
AdcRegs.ADCCHSELSEQ3.all = 0x0;
AdcRegs.ADCCHSELSEQ4.all = 0x0;

AdcRegs.ADCCHSELSEQ1.bit.CONV00 = 0;

AdcRegs.ADCMAXCONV.bit.MAX_CONV1 = 0;

AdcRegs.ADCTRL2.bit.EPWM_SOCA_SEQ1 = 1;// Enable SOCA from ePWM to start SEQ1

AdcRegs.ADCTRL2.bit.INT_ENA_SEQ1 = 1; // Enable SEQ1 interrupt (every EOS)

EPwm1Regs.ETSEL.bit.SOCAEN = 1; // Enable SOC on A group

EPwm1Regs.ETSEL.bit.SOCASEL = 4; // Select SOC from from CPMA on upcount

EPwm1Regs.ETPS.bit.SOCAPRD = 1; // Generate pulse on 1st event

EPwm1Regs.CMPA.half.CMPA = 6; // Set compare A value

EPwm1Regs.TBPRD = 12; // Set period for ePWM1

EPwm1Regs.TBCTL.bit.CTRMODE = 0; // count up and start

// Enable ADCINT in PIE
PieCtrlRegs.PIEIER1.bit.INTx6 = 1;
IER |= M_INT1; // Enable CPU Interrupt 1
EINT; // Enable Global interrupt INTM
ERTM; // Enable Global realtime interrupt DBGM

10#:

回复 Feng Youkui Feng Youkui:

所以你是在每次ADC转换后进入ADC中断?这样看,你的程序设计可能存在问题,因为你的采样时间设置的太短(ADCCLK=25MHz, ACQ_PS=1),也就是每个信号仅用时2个时钟,即80ns,达到最高的12.5MHz的采样速度,这个本身是没有问题的,因为F28335的ADC模块支持这么高的转换速度,但是,你每次只采样一个信号(MAX_CONV1 = 0),然后每次都进入中断(INT_ENA_SEQ1 = 1),这个是CPU处理不过来的:80ns/6.67ns=12,也就是要求中断必须在12个指令周期内完成 — 这显然是不可能的:参考下面内容,进入中断进行现场保护就至少需要16个时钟,更何况你还需要处理数据,清除标志位等等。

http://processors.wiki.ti.com/index.php/Interrupt_FAQ_for_C2000#ISR_Latency

建议你可以调整方式测试一下,比如多采样几个通道,或者增大采样窗口,或者稍微调低转换速度,或者每两次转换进一次中断等等(根据上方括号里引用的配置简单修改即可),而在实际应用场景里,通常都是采样多个信号后产生一次中断,进行数据读取,因此既可以达到12.5MH在的采样速度,也不会影响数据的处理。

最后,既然你也配置了级联模式(SEQ_CASC = 1),为什么不多采样几个信号呢?

使用ePWM事件触发方式启动AD转换,转换频率为6M,请问该怎么设置啊,自己按照官网的例程修改的程序EPwm1Regs.CMPA.half.CMPA = 6; 

EPwm1Regs.TBPRD = 12,用示波器量出来只有212KHz,请问是什么原因,初始化程序如下:

EALLOW;
SysCtrlRegs.HISPCP.all = ADC_MODCLK; // HSPCLK = SYSCLKOUT/ADC_MODCLK
EDIS;

//— Peripheral Initialization
InitAdc();// Initialize the ADC (FILE: Adc.c)

// Interrupts that are used in this example are re-mapped to
// ISR functions found within this file.
EALLOW; // This is needed to write to EALLOW protected register
PieVectTable.ADCINT = &adc_isr;
EDIS;// This is needed to disable write to EALLOW protected registers

AdcRegs.ADCTRL1.bit.ACQ_PS = ADC_SHCLK;
AdcRegs.ADCTRL3.bit.ADCCLKPS = ADC_CKPS;

AdcRegs.ADCTRL1.bit.SEQ_CASC = 1;

AdcRegs.ADCTRL3.bit.SMODE_SEL = 0;

AdcRegs.ADCTRL1.bit.CONT_RUN = 0;
// Enable Sequencer override feature
AdcRegs.ADCTRL1.bit.SEQ_OVRD = 1;
// Initialize all ADC channel selects to A0
AdcRegs.ADCCHSELSEQ1.all = 0x0;
AdcRegs.ADCCHSELSEQ2.all = 0x0;
AdcRegs.ADCCHSELSEQ3.all = 0x0;
AdcRegs.ADCCHSELSEQ4.all = 0x0;

AdcRegs.ADCCHSELSEQ1.bit.CONV00 = 0;

AdcRegs.ADCMAXCONV.bit.MAX_CONV1 = 0;

AdcRegs.ADCTRL2.bit.EPWM_SOCA_SEQ1 = 1;// Enable SOCA from ePWM to start SEQ1

AdcRegs.ADCTRL2.bit.INT_ENA_SEQ1 = 1; // Enable SEQ1 interrupt (every EOS)

EPwm1Regs.ETSEL.bit.SOCAEN = 1; // Enable SOC on A group

EPwm1Regs.ETSEL.bit.SOCASEL = 4; // Select SOC from from CPMA on upcount

EPwm1Regs.ETPS.bit.SOCAPRD = 1; // Generate pulse on 1st event

EPwm1Regs.CMPA.half.CMPA = 6; // Set compare A value

EPwm1Regs.TBPRD = 12; // Set period for ePWM1

EPwm1Regs.TBCTL.bit.CTRMODE = 0; // count up and start

// Enable ADCINT in PIE
PieCtrlRegs.PIEIER1.bit.INTx6 = 1;
IER |= M_INT1; // Enable CPU Interrupt 1
EINT; // Enable Global interrupt INTM
ERTM; // Enable Global realtime interrupt DBGM

Feng Youkui Feng Youkui:

回复 10#:

请问AN0引脚采样2M的输入信号 程序该如何编写?根据采样定理需要大于2倍的采样速率才可以 也就是说AD采样要达到4M,这要怎么设置呢?

使用ePWM事件触发方式启动AD转换,转换频率为6M,请问该怎么设置啊,自己按照官网的例程修改的程序EPwm1Regs.CMPA.half.CMPA = 6; 

EPwm1Regs.TBPRD = 12,用示波器量出来只有212KHz,请问是什么原因,初始化程序如下:

EALLOW;
SysCtrlRegs.HISPCP.all = ADC_MODCLK; // HSPCLK = SYSCLKOUT/ADC_MODCLK
EDIS;

//— Peripheral Initialization
InitAdc();// Initialize the ADC (FILE: Adc.c)

// Interrupts that are used in this example are re-mapped to
// ISR functions found within this file.
EALLOW; // This is needed to write to EALLOW protected register
PieVectTable.ADCINT = &adc_isr;
EDIS;// This is needed to disable write to EALLOW protected registers

AdcRegs.ADCTRL1.bit.ACQ_PS = ADC_SHCLK;
AdcRegs.ADCTRL3.bit.ADCCLKPS = ADC_CKPS;

AdcRegs.ADCTRL1.bit.SEQ_CASC = 1;

AdcRegs.ADCTRL3.bit.SMODE_SEL = 0;

AdcRegs.ADCTRL1.bit.CONT_RUN = 0;
// Enable Sequencer override feature
AdcRegs.ADCTRL1.bit.SEQ_OVRD = 1;
// Initialize all ADC channel selects to A0
AdcRegs.ADCCHSELSEQ1.all = 0x0;
AdcRegs.ADCCHSELSEQ2.all = 0x0;
AdcRegs.ADCCHSELSEQ3.all = 0x0;
AdcRegs.ADCCHSELSEQ4.all = 0x0;

AdcRegs.ADCCHSELSEQ1.bit.CONV00 = 0;

AdcRegs.ADCMAXCONV.bit.MAX_CONV1 = 0;

AdcRegs.ADCTRL2.bit.EPWM_SOCA_SEQ1 = 1;// Enable SOCA from ePWM to start SEQ1

AdcRegs.ADCTRL2.bit.INT_ENA_SEQ1 = 1; // Enable SEQ1 interrupt (every EOS)

EPwm1Regs.ETSEL.bit.SOCAEN = 1; // Enable SOC on A group

EPwm1Regs.ETSEL.bit.SOCASEL = 4; // Select SOC from from CPMA on upcount

EPwm1Regs.ETPS.bit.SOCAPRD = 1; // Generate pulse on 1st event

EPwm1Regs.CMPA.half.CMPA = 6; // Set compare A value

EPwm1Regs.TBPRD = 12; // Set period for ePWM1

EPwm1Regs.TBCTL.bit.CTRMODE = 0; // count up and start

// Enable ADCINT in PIE
PieCtrlRegs.PIEIER1.bit.INTx6 = 1;
IER |= M_INT1; // Enable CPU Interrupt 1
EINT; // Enable Global interrupt INTM
ERTM; // Enable Global realtime interrupt DBGM

10#:

回复 Feng Youkui Feng Youkui:

上面提到,采样速度达到12.5MHz都没有问题呀,关键是你不能每次都进中断,因为CPU响应不过来。

请仔细阅读并理解我上面的分析,将ADC采样转换和CPU执行中断代码这两件事情分开,你就不会困惑了。

使用ePWM事件触发方式启动AD转换,转换频率为6M,请问该怎么设置啊,自己按照官网的例程修改的程序EPwm1Regs.CMPA.half.CMPA = 6; 

EPwm1Regs.TBPRD = 12,用示波器量出来只有212KHz,请问是什么原因,初始化程序如下:

EALLOW;
SysCtrlRegs.HISPCP.all = ADC_MODCLK; // HSPCLK = SYSCLKOUT/ADC_MODCLK
EDIS;

//— Peripheral Initialization
InitAdc();// Initialize the ADC (FILE: Adc.c)

// Interrupts that are used in this example are re-mapped to
// ISR functions found within this file.
EALLOW; // This is needed to write to EALLOW protected register
PieVectTable.ADCINT = &adc_isr;
EDIS;// This is needed to disable write to EALLOW protected registers

AdcRegs.ADCTRL1.bit.ACQ_PS = ADC_SHCLK;
AdcRegs.ADCTRL3.bit.ADCCLKPS = ADC_CKPS;

AdcRegs.ADCTRL1.bit.SEQ_CASC = 1;

AdcRegs.ADCTRL3.bit.SMODE_SEL = 0;

AdcRegs.ADCTRL1.bit.CONT_RUN = 0;
// Enable Sequencer override feature
AdcRegs.ADCTRL1.bit.SEQ_OVRD = 1;
// Initialize all ADC channel selects to A0
AdcRegs.ADCCHSELSEQ1.all = 0x0;
AdcRegs.ADCCHSELSEQ2.all = 0x0;
AdcRegs.ADCCHSELSEQ3.all = 0x0;
AdcRegs.ADCCHSELSEQ4.all = 0x0;

AdcRegs.ADCCHSELSEQ1.bit.CONV00 = 0;

AdcRegs.ADCMAXCONV.bit.MAX_CONV1 = 0;

AdcRegs.ADCTRL2.bit.EPWM_SOCA_SEQ1 = 1;// Enable SOCA from ePWM to start SEQ1

AdcRegs.ADCTRL2.bit.INT_ENA_SEQ1 = 1; // Enable SEQ1 interrupt (every EOS)

EPwm1Regs.ETSEL.bit.SOCAEN = 1; // Enable SOC on A group

EPwm1Regs.ETSEL.bit.SOCASEL = 4; // Select SOC from from CPMA on upcount

EPwm1Regs.ETPS.bit.SOCAPRD = 1; // Generate pulse on 1st event

EPwm1Regs.CMPA.half.CMPA = 6; // Set compare A value

EPwm1Regs.TBPRD = 12; // Set period for ePWM1

EPwm1Regs.TBCTL.bit.CTRMODE = 0; // count up and start

// Enable ADCINT in PIE
PieCtrlRegs.PIEIER1.bit.INTx6 = 1;
IER |= M_INT1; // Enable CPU Interrupt 1
EINT; // Enable Global interrupt INTM
ERTM; // Enable Global realtime interrupt DBGM

Feng Youkui Feng Youkui:

回复 10#:

如果用查询方式 如何确定采样频率?如下面的程序如何确定采样频率是多少???

#include "DSP28x_Project.h" // Device Headerfile and Examples Include File

// Determine when the shift to right justify the data takes place// Only one of these should be defined as 1.// The other two should be defined as 0.#define POST_SHIFT 0 // Shift results after the entire sample table is full#define INLINE_SHIFT 1 // Shift results as the data is taken from the results regsiter#define NO_SHIFT 0 // Do not shift the results

// ADC start parameters#if (CPU_FRQ_150MHZ) // Default – 150 MHz SYSCLKOUT #define ADC_MODCLK 0x3 // HSPCLK = SYSCLKOUT/2*ADC_MODCLK2 = 150/(2*3) = 25.0 MHz#endif#if (CPU_FRQ_100MHZ) #define ADC_MODCLK 0x2 // HSPCLK = SYSCLKOUT/2*ADC_MODCLK2 = 100/(2*2) = 25.0 MHz#endif#define ADC_CKPS 0x0 // ADC module clock = HSPCLK/1 = 25.5MHz/(1) = 25.0 MHz#define ADC_SHCLK 16 // S/H width in ADC module periods = 2 ADC cycle#define AVG 1000 // Average sample limit#define ZOFFSET 0x00 // Average Zero offset#define BUF_SIZE 1024 // Sample buffer size

// Global variable for this exampleUint16 SampleTable[BUF_SIZE];

main(){ Uint16 i; Uint16 array_index;

// Step 1. Initialize System Control:// PLL, WatchDog, enable Peripheral Clocks// This example function is found in the DSP2833x_SysCtrl.c file. InitSysCtrl();

// Specific clock setting for this example: EALLOW; SysCtrlRegs.HISPCP.all = ADC_MODCLK; // HSPCLK = SYSCLKOUT/ADC_MODCLK EDIS;

// Step 2. Initialize GPIO:// This example function is found in the DSP2833x_Gpio.c file and// illustrates how to set the GPIO to it's default state.// InitGpio(); // Skipped for this example// Enable the pin GPIO34 as output EALLOW; GpioCtrlRegs.GPBMUX1.bit.GPIO34 = 0; // GPIO pin GpioCtrlRegs.GPBDIR.bit.GPIO34 = 1; // Output pin EDIS;

// Step 3. Clear all interrupts and initialize PIE vector table:// Disable CPU interrupts DINT;

// Initialize the PIE control registers to their default state.// The default state is all PIE interrupts disabled and flags// are cleared.// This function is found in the DSP2833x_PieCtrl.c file. InitPieCtrl();

// Disable CPU interrupts and clear all CPU interrupt flags: IER = 0x0000; IFR = 0x0000;

// Initialize the PIE vector table with pointers to the shell Interrupt// Service Routines (ISR).// This will populate the entire table, even if the interrupt// is not used in this example. This is useful for debug purposes.// The shell ISR routines are found in DSP2833x_DefaultIsr.c.// This function is found in DSP2833x_PieVect.c. InitPieVectTable();

// Step 4. Initialize all the Device Peripherals:// This function is found in DSP2833x_InitPeripherals.c// InitPeripherals(); // Not required for this example InitAdc(); // For this example, init the ADC

// Specific ADC setup for this example: AdcRegs.ADCTRL1.bit.ACQ_PS = ADC_SHCLK; // Sequential mode: Sample rate = 1/[(2+ACQ_PS)*ADC clock in ns] // = 1/(3*40ns) =8.3MHz (for 150 MHz SYSCLKOUT) // = 1/(3*80ns) =4.17MHz (for 100 MHz SYSCLKOUT) // If Simultaneous mode enabled: Sample rate = 1/[(3+ACQ_PS)*ADC clock in ns] AdcRegs.ADCTRL3.bit.ADCCLKPS = ADC_CKPS; AdcRegs.ADCTRL1.bit.SEQ_CASC = 1; // 1 Cascaded mode AdcRegs.ADCCHSELSEQ1.bit.CONV00 = 0x0; AdcRegs.ADCTRL1.bit.CONT_RUN = 1; // Setup continuous run

AdcRegs.ADCTRL1.bit.SEQ_OVRD = 1; // Enable Sequencer override feature AdcRegs.ADCCHSELSEQ1.all = 0x0; // Initialize all ADC channel selects to A0 AdcRegs.ADCCHSELSEQ2.all = 0x0; AdcRegs.ADCCHSELSEQ3.all = 0x0; AdcRegs.ADCCHSELSEQ4.all = 0x0; AdcRegs.ADCMAXCONV.bit.MAX_CONV1 = 0x7; // convert and store in 8 results registers

// Step 5. User specific code, enable interrupts:

// Clear SampleTable for (i=0; i<BUF_SIZE; i++) { SampleTable[i] = 0; }

// Start SEQ1 AdcRegs.ADCTRL2.all = 0x2000;

for(;;) { // Take ADC data and log them in SampleTable array

// Initialize the array index. This points to the current // location within the SampleTable array_index = 0;

for (i=0; i<(BUF_SIZE/16); i++) { // Wait for int1 while (AdcRegs.ADCST.bit.INT_SEQ1== 0){} GpioDataRegs.GPBSET.bit.GPIO34 = 1; // Set GPIO34 for monitoring -optional

AdcRegs.ADCST.bit.INT_SEQ1_CLR = 1;

#if INLINE_SHIFT SampleTable[array_index++]= ( (AdcRegs.ADCRESULT0)>>4); SampleTable[array_index++]= ( (AdcRegs.ADCRESULT1)>>4); SampleTable[array_index++]= ( (AdcRegs.ADCRESULT2)>>4); SampleTable[array_index++]= ( (AdcRegs.ADCRESULT3)>>4); SampleTable[array_index++]= ( (AdcRegs.ADCRESULT4)>>4); SampleTable[array_index++]= ( (AdcRegs.ADCRESULT5)>>4); SampleTable[array_index++]= ( (AdcRegs.ADCRESULT6)>>4); SampleTable[array_index++]= ( (AdcRegs.ADCRESULT7)>>4);

#endif //– INLINE_SHIFT

#if NO_SHIFT || POST_SHIFT

SampleTable[array_index++]= ( (AdcRegs.ADCRESULT0)); SampleTable[array_index++]= ( (AdcRegs.ADCRESULT1)); SampleTable[array_index++]= ( (AdcRegs.ADCRESULT2)); SampleTable[array_index++]= ( (AdcRegs.ADCRESULT3)); SampleTable[array_index++]= ( (AdcRegs.ADCRESULT4)); SampleTable[array_index++]= ( (AdcRegs.ADCRESULT5)); SampleTable[array_index++]= ( (AdcRegs.ADCRESULT6)); SampleTable[array_index++]= ( (AdcRegs.ADCRESULT7));

#endif //– NO_SHIFT || POST_SHIFT

while (AdcRegs.ADCST.bit.INT_SEQ1== 0){} GpioDataRegs.GPBCLEAR.bit.GPIO34 = 1; // Clear GPIO34 for monitoring -optional AdcRegs.ADCST.bit.INT_SEQ1_CLR = 1;

#if INLINE_SHIFT

SampleTable[array_index++]= ( (AdcRegs.ADCRESULT8)>>4); SampleTable[array_index++]= ( (AdcRegs.ADCRESULT9)>>4); SampleTable[array_index++]= ( (AdcRegs.ADCRESULT10)>>4); SampleTable[array_index++]= ( (AdcRegs.ADCRESULT11)>>4); SampleTable[array_index++]= ( (AdcRegs.ADCRESULT12)>>4); SampleTable[array_index++]= ( (AdcRegs.ADCRESULT13)>>4); SampleTable[array_index++]= ( (AdcRegs.ADCRESULT14)>>4); SampleTable[array_index++]= ( (AdcRegs.ADCRESULT15)>>4);

#endif //– INLINE_SHIFT

#if NO_SHIFT || POST_SHIFT

SampleTable[array_index++]= ( (AdcRegs.ADCRESULT8)); SampleTable[array_index++]= ( (AdcRegs.ADCRESULT9)); SampleTable[array_index++]= ( (AdcRegs.ADCRESULT10)); SampleTable[array_index++]= ( (AdcRegs.ADCRESULT11)); SampleTable[array_index++]= ( (AdcRegs.ADCRESULT12)); SampleTable[array_index++]= ( (AdcRegs.ADCRESULT13)); SampleTable[array_index++]= ( (AdcRegs.ADCRESULT14)); SampleTable[array_index++]= ( (AdcRegs.ADCRESULT15));#endif // — NO_SHIFT || POST_SHIFT

}

#if POST_SHIFT // For post shifting, shift the ADC results // in the SampleTable buffer after the buffer is full. for (i=0; i<BUF_SIZE; i++) { SampleTable[i] = ((SampleTable[i]) >>4); }#endif // — POST_SHIFT

GpioDataRegs.GPBCLEAR.bit.GPIO34 = 1; // Clear GPIO34 for monitoring -optional }}

使用ePWM事件触发方式启动AD转换,转换频率为6M,请问该怎么设置啊,自己按照官网的例程修改的程序EPwm1Regs.CMPA.half.CMPA = 6; 

EPwm1Regs.TBPRD = 12,用示波器量出来只有212KHz,请问是什么原因,初始化程序如下:

EALLOW;
SysCtrlRegs.HISPCP.all = ADC_MODCLK; // HSPCLK = SYSCLKOUT/ADC_MODCLK
EDIS;

//— Peripheral Initialization
InitAdc();// Initialize the ADC (FILE: Adc.c)

// Interrupts that are used in this example are re-mapped to
// ISR functions found within this file.
EALLOW; // This is needed to write to EALLOW protected register
PieVectTable.ADCINT = &adc_isr;
EDIS;// This is needed to disable write to EALLOW protected registers

AdcRegs.ADCTRL1.bit.ACQ_PS = ADC_SHCLK;
AdcRegs.ADCTRL3.bit.ADCCLKPS = ADC_CKPS;

AdcRegs.ADCTRL1.bit.SEQ_CASC = 1;

AdcRegs.ADCTRL3.bit.SMODE_SEL = 0;

AdcRegs.ADCTRL1.bit.CONT_RUN = 0;
// Enable Sequencer override feature
AdcRegs.ADCTRL1.bit.SEQ_OVRD = 1;
// Initialize all ADC channel selects to A0
AdcRegs.ADCCHSELSEQ1.all = 0x0;
AdcRegs.ADCCHSELSEQ2.all = 0x0;
AdcRegs.ADCCHSELSEQ3.all = 0x0;
AdcRegs.ADCCHSELSEQ4.all = 0x0;

AdcRegs.ADCCHSELSEQ1.bit.CONV00 = 0;

AdcRegs.ADCMAXCONV.bit.MAX_CONV1 = 0;

AdcRegs.ADCTRL2.bit.EPWM_SOCA_SEQ1 = 1;// Enable SOCA from ePWM to start SEQ1

AdcRegs.ADCTRL2.bit.INT_ENA_SEQ1 = 1; // Enable SEQ1 interrupt (every EOS)

EPwm1Regs.ETSEL.bit.SOCAEN = 1; // Enable SOC on A group

EPwm1Regs.ETSEL.bit.SOCASEL = 4; // Select SOC from from CPMA on upcount

EPwm1Regs.ETPS.bit.SOCAPRD = 1; // Generate pulse on 1st event

EPwm1Regs.CMPA.half.CMPA = 6; // Set compare A value

EPwm1Regs.TBPRD = 12; // Set period for ePWM1

EPwm1Regs.TBCTL.bit.CTRMODE = 0; // count up and start

// Enable ADCINT in PIE
PieCtrlRegs.PIEIER1.bit.INTx6 = 1;
IER |= M_INT1; // Enable CPU Interrupt 1
EINT; // Enable Global interrupt INTM
ERTM; // Enable Global realtime interrupt DBGM

10#:

回复 Feng Youkui Feng Youkui:

采样或转换频率与是否使用查询或中断方式无关。

采样频率是你设定用于触发SEQ的频率,也就是EPWM的SOCA产生的频率,即每隔多长时间让ADC进行一次采样和转换。

转换速度通常说的是每次采样和转换所需要的时间,这个跟ADCCLK有关,跟采样窗口大小有关。如我之前回复的,ADCCLK=25MHz,ACQ_PS=1时,这个时间是80ns ((1+1)/25MHz).

可以参考早些时候的相关讨论。

http://www.deyisupport.com/question_answer/microcontrollers/c2000/f/56/p/25637/86547.aspx#86547

使用ePWM事件触发方式启动AD转换,转换频率为6M,请问该怎么设置啊,自己按照官网的例程修改的程序EPwm1Regs.CMPA.half.CMPA = 6; 

EPwm1Regs.TBPRD = 12,用示波器量出来只有212KHz,请问是什么原因,初始化程序如下:

EALLOW;
SysCtrlRegs.HISPCP.all = ADC_MODCLK; // HSPCLK = SYSCLKOUT/ADC_MODCLK
EDIS;

//— Peripheral Initialization
InitAdc();// Initialize the ADC (FILE: Adc.c)

// Interrupts that are used in this example are re-mapped to
// ISR functions found within this file.
EALLOW; // This is needed to write to EALLOW protected register
PieVectTable.ADCINT = &adc_isr;
EDIS;// This is needed to disable write to EALLOW protected registers

AdcRegs.ADCTRL1.bit.ACQ_PS = ADC_SHCLK;
AdcRegs.ADCTRL3.bit.ADCCLKPS = ADC_CKPS;

AdcRegs.ADCTRL1.bit.SEQ_CASC = 1;

AdcRegs.ADCTRL3.bit.SMODE_SEL = 0;

AdcRegs.ADCTRL1.bit.CONT_RUN = 0;
// Enable Sequencer override feature
AdcRegs.ADCTRL1.bit.SEQ_OVRD = 1;
// Initialize all ADC channel selects to A0
AdcRegs.ADCCHSELSEQ1.all = 0x0;
AdcRegs.ADCCHSELSEQ2.all = 0x0;
AdcRegs.ADCCHSELSEQ3.all = 0x0;
AdcRegs.ADCCHSELSEQ4.all = 0x0;

AdcRegs.ADCCHSELSEQ1.bit.CONV00 = 0;

AdcRegs.ADCMAXCONV.bit.MAX_CONV1 = 0;

AdcRegs.ADCTRL2.bit.EPWM_SOCA_SEQ1 = 1;// Enable SOCA from ePWM to start SEQ1

AdcRegs.ADCTRL2.bit.INT_ENA_SEQ1 = 1; // Enable SEQ1 interrupt (every EOS)

EPwm1Regs.ETSEL.bit.SOCAEN = 1; // Enable SOC on A group

EPwm1Regs.ETSEL.bit.SOCASEL = 4; // Select SOC from from CPMA on upcount

EPwm1Regs.ETPS.bit.SOCAPRD = 1; // Generate pulse on 1st event

EPwm1Regs.CMPA.half.CMPA = 6; // Set compare A value

EPwm1Regs.TBPRD = 12; // Set period for ePWM1

EPwm1Regs.TBCTL.bit.CTRMODE = 0; // count up and start

// Enable ADCINT in PIE
PieCtrlRegs.PIEIER1.bit.INTx6 = 1;
IER |= M_INT1; // Enable CPU Interrupt 1
EINT; // Enable Global interrupt INTM
ERTM; // Enable Global realtime interrupt DBGM

Feng Youkui Feng Youkui:

回复 10#:

如果使用连续转换 是不是采样速率等于转换频率?

如果 

HSPCLK = SYSCLKOUT/2*ADC_MODCLK2 = 150/(2*3)   = 25.0 MHz

AdcRegs.ADCTRL1.bit.ACQ_PS = 15;

AdcRegs.ADCTRL1.bit.CPS = 0; 

AdcRegs.ADCTRL3.bit.ADCCLKPS =15;

那么转换时间是(15+1)/(25MHz/(30+1))=19.84us 频率就是1/19.84us=50.40KHz

采样的频率也是50.40KHz  这样理解对吗?

使用ePWM事件触发方式启动AD转换,转换频率为6M,请问该怎么设置啊,自己按照官网的例程修改的程序EPwm1Regs.CMPA.half.CMPA = 6; 

EPwm1Regs.TBPRD = 12,用示波器量出来只有212KHz,请问是什么原因,初始化程序如下:

EALLOW;
SysCtrlRegs.HISPCP.all = ADC_MODCLK; // HSPCLK = SYSCLKOUT/ADC_MODCLK
EDIS;

//— Peripheral Initialization
InitAdc();// Initialize the ADC (FILE: Adc.c)

// Interrupts that are used in this example are re-mapped to
// ISR functions found within this file.
EALLOW; // This is needed to write to EALLOW protected register
PieVectTable.ADCINT = &adc_isr;
EDIS;// This is needed to disable write to EALLOW protected registers

AdcRegs.ADCTRL1.bit.ACQ_PS = ADC_SHCLK;
AdcRegs.ADCTRL3.bit.ADCCLKPS = ADC_CKPS;

AdcRegs.ADCTRL1.bit.SEQ_CASC = 1;

AdcRegs.ADCTRL3.bit.SMODE_SEL = 0;

AdcRegs.ADCTRL1.bit.CONT_RUN = 0;
// Enable Sequencer override feature
AdcRegs.ADCTRL1.bit.SEQ_OVRD = 1;
// Initialize all ADC channel selects to A0
AdcRegs.ADCCHSELSEQ1.all = 0x0;
AdcRegs.ADCCHSELSEQ2.all = 0x0;
AdcRegs.ADCCHSELSEQ3.all = 0x0;
AdcRegs.ADCCHSELSEQ4.all = 0x0;

AdcRegs.ADCCHSELSEQ1.bit.CONV00 = 0;

AdcRegs.ADCMAXCONV.bit.MAX_CONV1 = 0;

AdcRegs.ADCTRL2.bit.EPWM_SOCA_SEQ1 = 1;// Enable SOCA from ePWM to start SEQ1

AdcRegs.ADCTRL2.bit.INT_ENA_SEQ1 = 1; // Enable SEQ1 interrupt (every EOS)

EPwm1Regs.ETSEL.bit.SOCAEN = 1; // Enable SOC on A group

EPwm1Regs.ETSEL.bit.SOCASEL = 4; // Select SOC from from CPMA on upcount

EPwm1Regs.ETPS.bit.SOCAPRD = 1; // Generate pulse on 1st event

EPwm1Regs.CMPA.half.CMPA = 6; // Set compare A value

EPwm1Regs.TBPRD = 12; // Set period for ePWM1

EPwm1Regs.TBCTL.bit.CTRMODE = 0; // count up and start

// Enable ADCINT in PIE
PieCtrlRegs.PIEIER1.bit.INTx6 = 1;
IER |= M_INT1; // Enable CPU Interrupt 1
EINT; // Enable Global interrupt INTM
ERTM; // Enable Global realtime interrupt DBGM

10#:

回复 Feng Youkui Feng Youkui:

Feng Youkui Feng Youkui

如果使用连续转换 是不是采样速率等于转换频率?

对。连续采样建议使用软件和硬件触发第一次采样,然后第一次采样的EOC产生中断,由中断触发后面的SEQ.

Feng Youkui Feng Youkui

如果 

HSPCLK = SYSCLKOUT/2*ADC_MODCLK2 = 150/(2*3)   = 25.0 MHz

AdcRegs.ADCTRL1.bit.ACQ_PS = 15;

AdcRegs.ADCTRL1.bit.CPS = 0; 

AdcRegs.ADCTRL3.bit.ADCCLKPS =15;

那么转换时间是(15+1)/(25MHz/(30+1))=19.84us 频率就是1/19.84us=50.40KHz

采样的频率也是50.40KHz  这样理解对吗?

有点小错误,请参考ADC用户手册的1.4.1 ADC-module Clock and Sample Rate章节进行计算。

(15+1)/(25MHz/(30*(0+1)))=18us,也就是55.5kHz.

使用ePWM事件触发方式启动AD转换,转换频率为6M,请问该怎么设置啊,自己按照官网的例程修改的程序EPwm1Regs.CMPA.half.CMPA = 6; 

EPwm1Regs.TBPRD = 12,用示波器量出来只有212KHz,请问是什么原因,初始化程序如下:

EALLOW;
SysCtrlRegs.HISPCP.all = ADC_MODCLK; // HSPCLK = SYSCLKOUT/ADC_MODCLK
EDIS;

//— Peripheral Initialization
InitAdc();// Initialize the ADC (FILE: Adc.c)

// Interrupts that are used in this example are re-mapped to
// ISR functions found within this file.
EALLOW; // This is needed to write to EALLOW protected register
PieVectTable.ADCINT = &adc_isr;
EDIS;// This is needed to disable write to EALLOW protected registers

AdcRegs.ADCTRL1.bit.ACQ_PS = ADC_SHCLK;
AdcRegs.ADCTRL3.bit.ADCCLKPS = ADC_CKPS;

AdcRegs.ADCTRL1.bit.SEQ_CASC = 1;

AdcRegs.ADCTRL3.bit.SMODE_SEL = 0;

AdcRegs.ADCTRL1.bit.CONT_RUN = 0;
// Enable Sequencer override feature
AdcRegs.ADCTRL1.bit.SEQ_OVRD = 1;
// Initialize all ADC channel selects to A0
AdcRegs.ADCCHSELSEQ1.all = 0x0;
AdcRegs.ADCCHSELSEQ2.all = 0x0;
AdcRegs.ADCCHSELSEQ3.all = 0x0;
AdcRegs.ADCCHSELSEQ4.all = 0x0;

AdcRegs.ADCCHSELSEQ1.bit.CONV00 = 0;

AdcRegs.ADCMAXCONV.bit.MAX_CONV1 = 0;

AdcRegs.ADCTRL2.bit.EPWM_SOCA_SEQ1 = 1;// Enable SOCA from ePWM to start SEQ1

AdcRegs.ADCTRL2.bit.INT_ENA_SEQ1 = 1; // Enable SEQ1 interrupt (every EOS)

EPwm1Regs.ETSEL.bit.SOCAEN = 1; // Enable SOC on A group

EPwm1Regs.ETSEL.bit.SOCASEL = 4; // Select SOC from from CPMA on upcount

EPwm1Regs.ETPS.bit.SOCAPRD = 1; // Generate pulse on 1st event

EPwm1Regs.CMPA.half.CMPA = 6; // Set compare A value

EPwm1Regs.TBPRD = 12; // Set period for ePWM1

EPwm1Regs.TBCTL.bit.CTRMODE = 0; // count up and start

// Enable ADCINT in PIE
PieCtrlRegs.PIEIER1.bit.INTx6 = 1;
IER |= M_INT1; // Enable CPU Interrupt 1
EINT; // Enable Global interrupt INTM
ERTM; // Enable Global realtime interrupt DBGM

Feng Youkui Feng Youkui:

回复 10#:

如果使用查询方式 采样频率是否可以达到12.5M,主要担心程序在flash中的执行时间没有那么快,如果达不到改怎么处理才可以达到12.5M, 程序如下

AdcRegs.ADCTRL1.bit.ACQ_PS = 0; // Sequential mode: Sample rate = 1/[(2+ACQ_PS)*ADC clock in ns] // = 1/(3*40ns) =8.3MHz (for 150 MHz SYSCLKOUT) // = 1/(3*80ns) =4.17MHz (for 100 MHz SYSCLKOUT) // If Simultaneous mode enabled: Sample rate = 1/[(3+ACQ_PS)*ADC clock in ns] AdcRegs.ADCTRL3.bit.ADCCLKPS = 0; AdcRegs.ADCTRL1.bit.SEQ_CASC = 1; // 1 Cascaded mode AdcRegs.ADCCHSELSEQ1.bit.CONV00 = 0; AdcRegs.ADCTRL1.bit.CONT_RUN = 1; // Setup continuous run

AdcRegs.ADCTRL1.bit.SEQ_OVRD = 0; // Enable Sequencer override feature AdcRegs.ADCCHSELSEQ1.all = 0x0; // Initialize all ADC channel selects to A0 AdcRegs.ADCCHSELSEQ2.all = 0x0; AdcRegs.ADCCHSELSEQ3.all = 0x0; AdcRegs.ADCCHSELSEQ4.all = 0x0; AdcRegs.ADCMAXCONV.bit.MAX_CONV1 = 0x0; // convert and store in 8 results registers

// Start SEQ1 AdcRegs.ADCTRL2.all = 0x2000;

for(;;) { // Take ADC data and log them in SampleTable array

array_index = 0; for (i=0; i<(BUF_SIZE); i++) { while (AdcRegs.ADCST.bit.INT_SEQ1== 0){}

AdcRegs.ADCST.bit.INT_SEQ1_CLR = 1;

AdcBuf[array_index++]= ( (AdcRegs.ADCRESULT0)>>4);

} }

还有一个问题 如果设置多通道连续采样,采样频率是如何计算的,比如设置采样频率是12.5M 8通道连续采样,

AdcRegs.ADCTRL1.bit.ACQ_PS = 0; // Sequential mode: Sample rate = 1/[(2+ACQ_PS)*ADC clock in ns]// = 1/(3*40ns) =8.3MHz (for 150 MHz SYSCLKOUT)// = 1/(3*80ns) =4.17MHz (for 100 MHz SYSCLKOUT)// If Simultaneous mode enabled: Sample rate = 1/[(3+ACQ_PS)*ADC clock in ns]AdcRegs.ADCTRL3.bit.ADCCLKPS = 0;AdcRegs.ADCTRL1.bit.SEQ_CASC = 1; // 1 Cascaded modeAdcRegs.ADCCHSELSEQ1.bit.CONV00 = 0;AdcRegs.ADCTRL1.bit.CONT_RUN = 1; // Setup continuous run

AdcRegs.ADCTRL1.bit.SEQ_OVRD = 0; // Enable Sequencer override featureAdcRegs.ADCCHSELSEQ1.all = 0x0; // Initialize all ADC channel selects to A0AdcRegs.ADCCHSELSEQ2.all = 0x0;AdcRegs.ADCCHSELSEQ3.all = 0x0;AdcRegs.ADCCHSELSEQ4.all = 0x0;AdcRegs.ADCMAXCONV.bit.MAX_CONV1 = 0x7; // convert and store in 8 results registers

// Start SEQ1AdcRegs.ADCTRL2.all = 0x2000;

for(;;){ // Take ADC data and log them in SampleTable array

array_index = 0;for (i=0; i<(BUF_SIZE); i++){while (AdcRegs.ADCST.bit.INT_SEQ1== 0){}//在这里是12.5MHz/8的时间吗?

AdcRegs.ADCST.bit.INT_SEQ1_CLR = 1;

AdcBuf[array_index++]= ( (AdcRegs.ADCRESULT0)>>4);

AdcBuf[array_index++]= ( (AdcRegs.ADCRESULT1)>>4);

AdcBuf[array_index++]= ( (AdcRegs.ADCRESULT2)>>4);

AdcBuf[array_index++]= ( (AdcRegs.ADCRESULT3)>>4);

AdcBuf[array_index++]= ( (AdcRegs.ADCRESULT4)>>4);

AdcBuf[array_index++]= ( (AdcRegs.ADCRESULT5)>>4);

AdcBuf[array_index++]= ( (AdcRegs.ADCRESULT6)>>4);

AdcBuf[array_index++]= ( (AdcRegs.ADCRESULT7)>>4);

}}

赞(0)
未经允许不得转载:TI中文支持网 » F28335 ePWM AD频率设置问题
分享到: 更多 (0)