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.
#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 EPWM1A GpioCtrlRegs.GPADIR.bit.GPIO0 = 1; //Set as output GpioCtrlRegs.GPAMUX1.bit.GPIO2 = 1; // Configure GPIO1 as EPWM1B GpioCtrlRegs.GPADIR.bit.GPIO2 = 1; //Set as output GpioCtrlRegs.GPAMUX2.bit.GPIO20 = 0; //Set as GPIO GpioCtrlRegs.GPADIR.bit.GPIO20 = 1; //Set as output GpioCtrlRegs.GPBMUX1.bit.GPIO34 = 0; //Set as GPIO GpioCtrlRegs.GPBDIR.bit.GPIO34 = 1; //Set as output GpioDataRegs.GPADAT.bit.GPIO20 = 0;//Set GPIO20 to low,RED LIGHT GpioDataRegs.GPBDAT.bit.GPIO34 = 0;//Set GPIO34 to low,GREEN LIGHT EDIS; } void SetEPWM1(void) { EPwm1Regs.TBPRD = TB_PERIOD; // Period = 15000 TBCLK counts EPwm1Regs.CMPA.half.CMPA = DUTY_VALUE; // Set 50% fixed duty for EPWM1A EPwm1Regs.TBPHS.half.TBPHS = 0; // Set Phase register to zero EPwm1Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1; // Clock ratio to SYSCLKOUT EPwm1Regs.TBCTL.bit.CLKDIV = TB_DIV1; EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP; // Asymmetrical mode EPwm1Regs.TBCTL.bit.PHSEN = TB_DISABLE; // Master module EPwm1Regs.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=Zero EPwm1Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO; // load on CTR=Zero EPwm1Regs.AQCTLA.bit.ZRO = AQ_SET; // set actions for EPWM1A EPwm1Regs.AQCTLA.bit.CAU = AQ_CLEAR; EPwm1Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE; // enable Dead-band module EPwm1Regs.DBCTL.bit.POLSEL = DB_ACTV_HIC; // Active Hi complementary EPwm1Regs.DBFED = DB_VALUE; // FED = 300 TBCLKs initially EPwm1Regs.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 config EPwm2Regs.TBPRD = TB_PERIOD; // Period = 15000 TBCLK counts EPwm2Regs.CMPA.half.CMPA = DUTY_VALUE; // Set 50% fixed duty EPWM2A EPwm2Regs.TBPHS.half.TBPHS = 0; // Set Phase register to zero initially EPwm2Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1; // Clock ratio to SYSCLKOUT EPwm2Regs.TBCTL.bit.CLKDIV = TB_DIV1; EPwm2Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP; // Asymmetrical mode EPwm2Regs.TBCTL.bit.PHSEN = TB_ENABLE; // Slave module EPwm2Regs.TBCTL.bit.PRDLD = TB_SHADOW; EPwm2Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_IN; // sync flow-through EPwm2Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW; EPwm2Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW; EPwm2Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO; // load on CTR=Zero EPwm2Regs.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 EPWM2A EPwm2Regs.AQCTLA.bit.CAU = AQ_CLEAR; EPwm2Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE; // enable Dead-band module EPwm2Regs.DBCTL.bit.POLSEL = DB_ACTV_HIC; // Active Hi complementary EPwm2Regs.DBFED = DB_VALUE; // FED = 30 TBCLKs initially EPwm2Regs.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 rev0 Voltage2[ConversionCount] = AdcResult.ADCRESULT2; Voltage3[ConversionCount] = AdcResult.ADCRESULT3; Voltage4[ConversionCount] = AdcResult.ADCRESULT4; Voltage5[ConversionCount] = AdcResult.ADCRESULT5; // If 20 conversions have been logged, start over if(ConversionCount == 9) { ConversionCount = 0; } else ConversionCount++; AdcRegs.ADCINTFLGCLR.bit.ADCINT1 = 1; //Clear ADCINT1 flag reinitialize for next SOC PieCtrlRegs.PIEACK.all = PIEACK_GROUP1; // Acknowledge interrupt to PIE return; } 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++; } }
代码在生成pwm波形的基础上,加入了基于官方例程Example_2803xAdcSoc修改而来的代码。
代码的目的是通过输入电压来改变pwm的占空比,所以需要先将pwm的代码和adc采样代码合并在一起。
adc和pwm代码作为两个独立的程序运行时是没问题的。但是两个程序合并之后adc代码就不正常了,采样值高达几万。pwm程序是正常的。
我感觉是主程序的问题:
是可以使用PWM来触发SOC中断实现周期性的启动ADC进行转换,您可以参考下这个例子:
C:\ti\c2000\C2000Ware_5_00_00_00\device_support\f2803x\examples\c28\adc_soc
如果是直接使用下面路径下的例程?例程能否运行?读数是否准确?该例程使用ePWM1来触发ADC。
C:\ti\c2000\C2000Ware_5_00_00_00\device_support\f2803x\examples\c28\adc_soc
您提供的例程能够成功运行,我把除了adc相关代码的其它的代码搬进adc_soc这个例程里,代码就正常了,虽然不知道问题发生的具体原因,不过能解决就好,赶紧赶下一个进程了,谢谢你~