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程序是正常的。
我感觉是主程序的问题:
不知道是不是配置的步骤有问题还是怎么的,求大神帮忙看一下。
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