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