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

TMS320F28035: TMS320F28035 ADC采样问题

Part Number:TMS320F28035Other Parts Discussed in Thread:C2000WARE

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

#define SYSCLK 60E6 // 60MHz system clock
#define PWMFREQ 100E3 // 100kHz PWM frequency
#define DUTY_CYCLE 0.20// duty cycle
#define DEAD_BAND 0 // dead band

#define TB_PERIOD (SYSCLK / PWMFREQ) // Calculate period for up-down count mode to 100khz
//#define TB_PERIOD (SYSCLK / (2 * PWMFREQ)) // Calculate period for up-down count mode
//#define TB_PERIOD (SYSCLK / (4 * PWMFREQ)) // Calculate period for up-down count mode

#define DUTY_VALUE (TB_PERIOD * DUTY_CYCLE)
#define DB_VALUE (TB_PERIOD * DEAD_BAND)

//*********************************************************************

__interrupt void adc_isr(void);
void Adc_Config(void);

// Global variables used in this example:
Uint16 LoopCount;
Uint16 ConversionCount;
Uint16 Voltage1[10];
Uint16 Voltage2[10];
Uint16 Voltage3[10];
Uint16 Voltage4[10];
Uint16 Voltage5[10];

void SetGpio()
{EALLOW;GpioCtrlRegs.GPAMUX1.bit.GPIO0 = 1; // Configure GPIO0 as EPWM1AGpioCtrlRegs.GPADIR.bit.GPIO0 = 1; //Set as outputGpioCtrlRegs.GPAMUX1.bit.GPIO2 = 1; // Configure GPIO1 as EPWM1BGpioCtrlRegs.GPADIR.bit.GPIO2 = 1; //Set as outputGpioCtrlRegs.GPAMUX2.bit.GPIO20 = 0; //Set as GPIOGpioCtrlRegs.GPADIR.bit.GPIO20 = 1;  //Set as outputGpioCtrlRegs.GPBMUX1.bit.GPIO34 = 0; //Set as GPIOGpioCtrlRegs.GPBDIR.bit.GPIO34 = 1;  //Set as outputGpioDataRegs.GPADAT.bit.GPIO20 = 0;//Set GPIO20 to low,RED LIGHTGpioDataRegs.GPBDAT.bit.GPIO34 = 0;//Set GPIO34 to low,GREEN LIGHTEDIS;
}

void SetEPWM1(void)
{EPwm1Regs.TBPRD = TB_PERIOD; // Period = 15000 TBCLK countsEPwm1Regs.CMPA.half.CMPA = DUTY_VALUE; // Set 50% fixed duty for EPWM1AEPwm1Regs.TBPHS.half.TBPHS = 0; // Set Phase register to zeroEPwm1Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1;// Clock ratio to SYSCLKOUTEPwm1Regs.TBCTL.bit.CLKDIV = TB_DIV1;EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP; // Asymmetrical modeEPwm1Regs.TBCTL.bit.PHSEN = TB_DISABLE; // Master moduleEPwm1Regs.TBCTL.bit.PRDLD = TB_SHADOW;EPwm1Regs.TBCTL.bit.SYNCOSEL = TB_CTR_ZERO;EPwm1Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;EPwm1Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;EPwm1Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO; // load on CTR=ZeroEPwm1Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO; // load on CTR=ZeroEPwm1Regs.AQCTLA.bit.ZRO = AQ_SET; // set actions for EPWM1AEPwm1Regs.AQCTLA.bit.CAU = AQ_CLEAR;EPwm1Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE; // enable Dead-band moduleEPwm1Regs.DBCTL.bit.POLSEL = DB_ACTV_HIC; // Active Hi complementaryEPwm1Regs.DBFED = DB_VALUE; // FED = 300 TBCLKs initiallyEPwm1Regs.DBRED = DB_VALUE; // RED = 300 TBCLKs initially//EPwm1Regs.DBFED = FED1_NewValue; // Update ZVS transition interval//EPwm1Regs.DBRED = RED1_NewValue; // Update ZVS transition interval

}

void SetEPWM2(void)
{// EPWM Module 2 configEPwm2Regs.TBPRD = TB_PERIOD; // Period = 15000 TBCLK countsEPwm2Regs.CMPA.half.CMPA = DUTY_VALUE; // Set 50% fixed duty EPWM2AEPwm2Regs.TBPHS.half.TBPHS = 0; // Set Phase register to zero initiallyEPwm2Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1;// Clock ratio to SYSCLKOUTEPwm2Regs.TBCTL.bit.CLKDIV = TB_DIV1;EPwm2Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP; // Asymmetrical modeEPwm2Regs.TBCTL.bit.PHSEN = TB_ENABLE; // Slave moduleEPwm2Regs.TBCTL.bit.PRDLD = TB_SHADOW;EPwm2Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_IN; // sync flow-throughEPwm2Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;EPwm2Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;EPwm2Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO; // load on CTR=ZeroEPwm2Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO; // load on CTR=Zero

//EPwm2Regs.AQCTLA.bit.ZRO = AQ_CLEAR; // set actions for EPWM2A
//EPwm2Regs.AQCTLA.bit.CAU = AQ_SET;EPwm2Regs.AQCTLA.bit.ZRO = AQ_SET; // set actions for EPWM2AEPwm2Regs.AQCTLA.bit.CAU = AQ_CLEAR;EPwm2Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE; // enable Dead-band moduleEPwm2Regs.DBCTL.bit.POLSEL = DB_ACTV_HIC; // Active Hi complementaryEPwm2Regs.DBFED = DB_VALUE; // FED = 30 TBCLKs initiallyEPwm2Regs.DBRED = DB_VALUE; // RED = 40 TBCLKs initially// Run Time (Note: Example execution of one run-time instant)//============================================================EPwm2Regs.TBPHS.half.TBPHS = TB_PERIOD / 2;
//EPwm2Regs.TBPHS.half.TBPHS = 15000 - yixiangjiao; // Set Phase reg to 300/1200 * 360 = 90 deg
//EPwm2Regs.DBFED = FED2_NewValue; // Update ZVS transition interval
//EPwm2Regs.DBRED = RED2_NewValue; // Update ZVS transition interval

}

__interrupt void  adc_isr(void)
{Voltage1[ConversionCount] = AdcResult.ADCRESULT1; //discard ADCRESULT0 as part of the workaround to the 1st sample errata for rev0Voltage2[ConversionCount] = AdcResult.ADCRESULT2;Voltage3[ConversionCount] = AdcResult.ADCRESULT3;Voltage4[ConversionCount] = AdcResult.ADCRESULT4;Voltage5[ConversionCount] = AdcResult.ADCRESULT5;// If 20 conversions have been logged, start overif(ConversionCount == 9){ConversionCount = 0;}else ConversionCount++;AdcRegs.ADCINTFLGCLR.bit.ADCINT1 = 1;//Clear ADCINT1 flag reinitialize for next SOCPieCtrlRegs.PIEACK.all = PIEACK_GROUP1;// Acknowledge interrupt to PIEreturn;
}


void main(void)
{InitSysCtrl();  // 初始化系统时钟和PLLSetGpio(); // Initialize GPIODINT;// 禁止所有中断InitPieCtrl();  // 初始化和启用CPU PIEIER = 0x0000;IFR = 0x0000;InitPieVectTable();  // 初始化PIE向量表EALLOW;SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 0;  // 停止所有ePWM时钟EDIS;SetEPWM1();  // 初始化ePWM1SetEPWM2();  // 初始化ePWM2EALLOW;SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1;  // 启动所有ePWM时钟EDIS;EALLOW;// This is needed to write to EALLOW protected registerPieVectTable.ADCINT1 = &adc_isr;EDIS;// This is needed to disable write to EALLOW protected registers//// Step 4. Initialize all the Device Peripherals://InitAdc();  // For this example, init the ADCAdcOffsetSelfCal();PieCtrlRegs.PIEIER1.bit.INTx1 = 1; // Enable INT 1.1 in the PIEIER |= M_INT1;// Enable CPU Interrupt 1EINT;// Enable Global interrupt INTMERTM;// Enable Global realtime interrupt DBGMLoopCount = 0;ConversionCount = 0;EALLOW;AdcRegs.ADCCTL1.bit.INTPULSEPOS = 1; //ADCINT1 trips after AdcResults latchAdcRegs.INTSEL1N2.bit.INT1E= 1; // Enabled ADCINT1AdcRegs.INTSEL1N2.bit.INT1CONT  = 0; // Disable ADCINT1 Continuous modeAdcRegs.INTSEL1N2.bit.INT1SEL= 2;  // setup EOC2 to trigger ADCINT1 to fireAdcRegs.ADCSOC0CTL.bit.CHSEL= 1;//set SOC0 channel select to ADCINA1(dummy sample for rev0 errata workaround)AdcRegs.ADCSOC1CTL.bit.CHSEL= 1;//set SOC1 channel select to ADCINA1AdcRegs.ADCSOC2CTL.bit.CHSEL= 2;//set SOC2 channel select to ADCINA2AdcRegs.ADCSOC3CTL.bit.CHSEL= 3;//set SOC3 channel select to ADCINA3AdcRegs.ADCSOC4CTL.bit.CHSEL= 4;//set SOC4 channel select to ADCINA4AdcRegs.ADCSOC5CTL.bit.CHSEL= 6;//set SOC5 channel select to ADCINA6AdcRegs.ADCSOC0CTL.bit.TRIGSEL  = 9;//set SOC0 start trigger on EPwm3A, due to round-robin SOC0 converts first then SOC1, then SOC2AdcRegs.ADCSOC1CTL.bit.TRIGSEL  = 9;//set SOC1 start trigger on EPwm3A, due to round-robin SOC0 converts first then SOC1, then SOC2AdcRegs.ADCSOC2CTL.bit.TRIGSEL  = 9;//set SOC2 start trigger on EPwm3A, due to round-robin SOC0 converts first then SOC1, then SOC2AdcRegs.ADCSOC3CTL.bit.TRIGSEL  = 9;//set SOC3 start trigger on EPwm3A, due to round-robin SOC0 converts first then SOC1, then SOC2AdcRegs.ADCSOC4CTL.bit.TRIGSEL  = 9;//set SOC4 start trigger on EPwm3A, due to round-robin SOC0 converts first then SOC1, then SOC2AdcRegs.ADCSOC5CTL.bit.TRIGSEL  = 9;//set SOC5 start trigger on EPwm3A, due to round-robin SOC0 converts first then SOC1, then SOC2AdcRegs.ADCSOC0CTL.bit.ACQPS= 6;//set SOC0 S/H Window to 7 ADC Clock Cycles, (9 ACQPS plus 1)AdcRegs.ADCSOC1CTL.bit.ACQPS= 6;//set SOC1 S/H Window to 7 ADC Clock Cycles, (9 ACQPS plus 1)AdcRegs.ADCSOC2CTL.bit.ACQPS= 6;//set SOC2 S/H Window to 7 ADC Clock Cycles, (9 ACQPS plus 1)AdcRegs.ADCSOC3CTL.bit.ACQPS= 6;//set SOC3 S/H Window to 7 ADC Clock Cycles, (9 ACQPS plus 1)AdcRegs.ADCSOC4CTL.bit.ACQPS= 6;//set SOC4 S/H Window to 7 ADC Clock Cycles, (9 ACQPS plus 1)AdcRegs.ADCSOC5CTL.bit.ACQPS= 6;//set SOC5 S/H Window to 7 ADC Clock Cycles, (9 ACQPS plus 1)EDIS;//// Assumes ePWM1 clock is already enabled in InitSysCtrl();//EPwm3Regs.ETSEL.bit.SOCAEN  = 1;// Enable SOC on A groupEPwm3Regs.ETSEL.bit.SOCASEL = 4;// Select SOC from from CPMA on upcountEPwm3Regs.ETPS.bit.SOCAPRD  = 1;// Generate pulse on 1st eventEPwm3Regs.CMPA.half.CMPA= 0x0080;// Set compare A valueEPwm3Regs.TBPRD= 0xFFFF;// Set period for ePWM1EPwm3Regs.TBCTL.bit.CTRMODE= 0;// count up and start//// Wait for ADC interrupt//for(;;){LoopCount++;}

}

代码在生成pwm波形的基础上,加入了基于官方例程Example_2803xAdcSoc修改而来的代码。

代码的目的是通过输入电压来改变pwm的占空比,所以需要先将pwm的代码和adc采样代码合并在一起。

adc和pwm代码作为两个独立的程序运行时是没问题的。但是两个程序合并之后adc代码就不正常了,采样值高达几万。pwm程序是正常的。

我感觉是主程序的问题:

void main(void)
{
InitSysCtrl(); // 初始化系统时钟和PLL

SetGpio(); // Initialize GPIO

DINT; // 禁止所有中断

InitPieCtrl(); // 初始化和启用CPU PIE

IER = 0x0000;
IFR = 0x0000;

InitPieVectTable(); // 初始化PIE向量表

EALLOW;
SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 0; // 停止所有ePWM时钟
EDIS;

SetEPWM1(); // 初始化ePWM1
SetEPWM2(); // 初始化ePWM2

EALLOW;
SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1; // 启动所有ePWM时钟
EDIS;

EALLOW; // This is needed to write to EALLOW protected register
PieVectTable.ADCINT1 = &adc_isr;
EDIS; // This is needed to disable write to EALLOW protected registers

//
// Step 4. Initialize all the Device Peripherals:
//
InitAdc(); // For this example, init the ADC
AdcOffsetSelfCal();

PieCtrlRegs.PIEIER1.bit.INTx1 = 1; // Enable INT 1.1 in the PIE
IER |= M_INT1; // Enable CPU Interrupt 1
EINT; // Enable Global interrupt INTM
ERTM; // Enable Global realtime interrupt DBGM

LoopCount = 0;
ConversionCount = 0;
EALLOW;
AdcRegs.ADCCTL1.bit.INTPULSEPOS = 1; //ADCINT1 trips after AdcResults latch
AdcRegs.INTSEL1N2.bit.INT1E = 1; // Enabled ADCINT1
AdcRegs.INTSEL1N2.bit.INT1CONT = 0; // Disable ADCINT1 Continuous mode
AdcRegs.INTSEL1N2.bit.INT1SEL = 2; // setup EOC2 to trigger ADCINT1 to fire
AdcRegs.ADCSOC0CTL.bit.CHSEL = 1; //set SOC0 channel select to ADCINA1(dummy sample for rev0 errata workaround)
AdcRegs.ADCSOC1CTL.bit.CHSEL = 1; //set SOC1 channel select to ADCINA1
AdcRegs.ADCSOC2CTL.bit.CHSEL = 2; //set SOC2 channel select to ADCINA2
AdcRegs.ADCSOC3CTL.bit.CHSEL = 3; //set SOC3 channel select to ADCINA3
AdcRegs.ADCSOC4CTL.bit.CHSEL = 4; //set SOC4 channel select to ADCINA4
AdcRegs.ADCSOC5CTL.bit.CHSEL = 6; //set SOC5 channel select to ADCINA6

AdcRegs.ADCSOC0CTL.bit.TRIGSEL = 9; //set SOC0 start trigger on EPwm3A, due to round-robin SOC0 converts first then SOC1, then SOC2
AdcRegs.ADCSOC1CTL.bit.TRIGSEL = 9; //set SOC1 start trigger on EPwm3A, due to round-robin SOC0 converts first then SOC1, then SOC2
AdcRegs.ADCSOC2CTL.bit.TRIGSEL = 9; //set SOC2 start trigger on EPwm3A, due to round-robin SOC0 converts first then SOC1, then SOC2
AdcRegs.ADCSOC3CTL.bit.TRIGSEL = 9; //set SOC3 start trigger on EPwm3A, due to round-robin SOC0 converts first then SOC1, then SOC2
AdcRegs.ADCSOC4CTL.bit.TRIGSEL = 9; //set SOC4 start trigger on EPwm3A, due to round-robin SOC0 converts first then SOC1, then SOC2
AdcRegs.ADCSOC5CTL.bit.TRIGSEL = 9; //set SOC5 start trigger on EPwm3A, due to round-robin SOC0 converts first then SOC1, then SOC2

AdcRegs.ADCSOC0CTL.bit.ACQPS = 6; //set SOC0 S/H Window to 7 ADC Clock Cycles, (9 ACQPS plus 1)
AdcRegs.ADCSOC1CTL.bit.ACQPS = 6; //set SOC1 S/H Window to 7 ADC Clock Cycles, (9 ACQPS plus 1)
AdcRegs.ADCSOC2CTL.bit.ACQPS = 6; //set SOC2 S/H Window to 7 ADC Clock Cycles, (9 ACQPS plus 1)
AdcRegs.ADCSOC3CTL.bit.ACQPS = 6; //set SOC3 S/H Window to 7 ADC Clock Cycles, (9 ACQPS plus 1)
AdcRegs.ADCSOC4CTL.bit.ACQPS = 6; //set SOC4 S/H Window to 7 ADC Clock Cycles, (9 ACQPS plus 1)
AdcRegs.ADCSOC5CTL.bit.ACQPS = 6; //set SOC5 S/H Window to 7 ADC Clock Cycles, (9 ACQPS plus 1)

EDIS;

//
// Assumes ePWM1 clock is already enabled in InitSysCtrl();
//
EPwm3Regs.ETSEL.bit.SOCAEN = 1; // Enable SOC on A group
EPwm3Regs.ETSEL.bit.SOCASEL = 4; // Select SOC from from CPMA on upcount
EPwm3Regs.ETPS.bit.SOCAPRD = 1; // Generate pulse on 1st event
EPwm3Regs.CMPA.half.CMPA = 0x0080; // Set compare A value
EPwm3Regs.TBPRD = 0xFFFF; // Set period for ePWM1
EPwm3Regs.TBCTL.bit.CTRMODE = 0; // count up and start

//
// Wait for ADC interrupt
//
for(;;)
{
LoopCount++;
}

}

不知道是不是配置的步骤有问题还是怎么的,求大神帮忙看一下。

Ben Qin:

你好,我查看下相关资料后回复您。

,

Ben Qin:

建议您使用单步调试看问题出在哪。分开配置没问题,合并就出现问题,你是如何合并的?

,

chenzheng:

代码我已全部给出在问题描述里,就是把pwm和adc的主函数合并了一下,然后adc的读数就不正常了,高达好几万这样

,

chenzheng:

单步调试我没试过,请问单步调试要怎么操作呢

,

Ben Qin:

使用单步调试,看看问题是出在ADC上,还是出在PWM上,或者在两者的连接上,以及找出具体是哪里那条语句出错。

,

chenzheng:

两者的连接是什么意思,pwm和adc不是分开的两个功能吗

,

Ben Qin:

是可以使用PWM来触发SOC中断实现周期性的启动ADC进行转换,您可以参考下这个例子:

C:\ti\c2000\C2000Ware_5_00_00_00\device_support\f2803x\examples\c28\adc_soc

,

chenzheng:

我是想根据输入电压和负载来动态调整pwm波形的占空比,现在adc采集的输入电压读数不准确,所以就一直卡在这了

,

Ben Qin:

如果是直接使用下面路径下的例程?例程能否运行?读数是否准确?该例程使用ePWM1来触发ADC。

C:\ti\c2000\C2000Ware_5_00_00_00\device_support\f2803x\examples\c28\adc_soc

赞(0)
未经允许不得转载:TI中文支持网 » TMS320F28035: TMS320F28035 ADC采样问题
分享到: 更多 (0)

© 2024 TI中文支持网   网站地图 鲁ICP备2022002796号-1