Other Parts Discussed in Thread: C2000WARE
问题1.CMPSS通过数字滤波器输出,数字滤波器的配置是怎么配置的?
问题2. CMPSS的输出通过EPWM X-BAR给DC产生DCAEVT2信号送入T1和T2事件,进而用AQ模块产生PWM,这个逻辑对吗,是否需要在TZ模块中采用CBC模式啥的,对TZ与DC模块有点理解困难,希望指导一下。
问题3. 通过配置GPIO12来判断中断计算时间,奇怪的是GPIO12一直处于低电平,没有观察到高电平,这是什么原因引起的。
// Included Files
//pin define Cmpss3 CMP3IN_P to B2 vo_sense to A1
#include "F28x_Project.h"
// Defines
//
//definitions for selecting DACH reference
#define REFERENCE_VDDA 0
#define REFERENCE_VDAC 1
//definitions for COMPH input selection
#define NEGIN_DAC 0
#define NEGIN_PIN 1
//definitions for CTRIPH/CTRIPOUTH output selection
#define CTRIP_ASYNCH 0
#define CTRIP_SYNCH 1
#define CTRIP_FILTER 2
#define CTRIP_LATCH 3
int i=0;
//ADC定义
#define Vo_ref 2460 //12
float Vo_ave=0;
#define chanel 1
#define acqps 29 //采样窗 (acqps+1)*sysclk *5ns
//斜坡定义
#define slopeval 8 /* Required slope compensation */
//
// Function Prototypes
//
void InitAdc(void);
void InitCMPSS(void);
void InitEPWM(void);
void pid_init(void);
interrupt void adc_isr(void);
//
// Main
//
void main(void)
{
//
// Step 1. Initialize System Control:
// PLL, WatchDog, enable Peripheral Clocks
// This example function is found in the F2837xD_SysCtrl.c file.
//
InitSysCtrl();
//
// Step 2. Initialize GPIO:
// This example function is found in the F2837xD_Gpio.c file and
// illustrates how to set the GPIO to it's default state.
//
InitGpio();
//
// 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 F2837xD_PieCtrl.c file.
InitPieCtrl();
// Disable CPU interrupts and clear all CPU interrupt flags:
IER = 0x0000;
IFR = 0x0000;
/* DSP28377D_PieVect.c */
InitPieVectTable();
/* Interrupt re-mapped to ISR function */
EALLOW;
PieVectTable.ADCA1_INT = &adc_isr;
EDIS;
InitAdc();
/* Enable ADCA1INT1 in PIE */
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 */
// Configure Comparator COMP3H to accept POS input from pin and NEG input
// from DAC
InitEPWM();
InitCMPSS();
// Configure GPIO5() to output OUTPUTXBAR3
//
GPIO_SetupPinMux(5, GPIO_MUX_CPU1, 3);
//
// Configure COMP3 to feed TRIP4 EPWM DC trip input
//
InitEPwm1Gpio();
pid_init();
// Enable PWM
GPIO_SetupPinMux(12, GPIO_MUX_CPU1, 0); // PWMEn1
GPIO_SetupPinOptions(12, GPIO_OUTPUT, (GPIO_OPENDRAIN | GPIO_PULLUP)); // the standard digital output
GpioDataRegs.GPACLEAR.bit.GPIO12 = 1;
// Enable PWM
// GPIO_SetupPinMux(10, GPIO_MUX_CPU1, 0); // PWMEn2
// GPIO_SetupPinOptions(10, GPIO_OUTPUT, (GPIO_OPENDRAIN | GPIO_PULLUP)); // the standard digital output
// GpioDataRegs.GPACLEAR.bit.GPIO10 = 1;
/* Configure GPIO12 pin for toggling */
EALLOW;
GpioCtrlRegs.GPAPUD.bit.GPIO12 = 1;/* Disable pull-up on GPIO12 */
GpioCtrlRegs.GPAMUX1.bit.GPIO12 = 0;/* Configure GPIO0 as GPIO */
GpioCtrlRegs.GPADIR.bit.GPIO12 = 1;/* Configure as output 1为输出 0为输入*/
EDIS;
while(1)
{
}
}
//
// InitCMPSS - Initialize CMPSS3 and configure settings
//
void InitAdc(void)
{
//ADC时钟开启
EALLOW;
CpuSysRegs.PCLKCR13.bit.ADC_A=1;
EDIS;
EALLOW;
AdcaRegs.ADCCTL2.bit.PRESCALE = 6; //set ADCCLK divider to /4
AdcSetMode(ADC_ADCA, ADC_RESOLUTION_12BIT, ADC_SIGNALMODE_SINGLE);
AdcaRegs.ADCSOC0CTL.bit.CHSEL =chanel; //SOC0 will convert ADCINA1
AdcaRegs.ADCSOC0CTL.bit.ACQPS = acqps; //SOC0 will use sample duration of 20 SYSCLK cycles
AdcaRegs.ADCSOC0CTL.bit.TRIGSEL = 5; //SOC0 will begin conversion on ePWM1 SOCA 5 EPWM1A
AdcaRegs.ADCSOC1CTL.bit.CHSEL =chanel; //SOC0 will convert ADCINA1
AdcaRegs.ADCSOC1CTL.bit.ACQPS = acqps; //SOC0 will use sample duration of 20 SYSCLK cycles
AdcaRegs.ADCSOC1CTL.bit.TRIGSEL = 5; //SOC0 will begin conversion on ePWM1 SOCA
AdcaRegs.ADCSOC2CTL.bit.CHSEL =chanel; //SOC0 will convert ADCINA1
AdcaRegs.ADCSOC2CTL.bit.ACQPS = acqps; //SOC0 will use sample duration of 20 SYSCLK cycles
AdcaRegs.ADCSOC2CTL.bit.TRIGSEL = 5; //SOC0 will begin conversion on ePWM1 SOCA
AdcaRegs.ADCSOC3CTL.bit.CHSEL =chanel; //SOC0 will convert ADCINA1
AdcaRegs.ADCSOC3CTL.bit.ACQPS = acqps; //SOC0 will use sample duration of 20 SYSCLK cycles
AdcaRegs.ADCSOC3CTL.bit.TRIGSEL = 5; //SOC0 will begin conversion on ePWM1 SOCA
AdcaRegs.ADCINTSEL1N2.bit.INT1SEL = 0; //end of SOC0 will set INT1 flag
AdcaRegs.ADCINTSEL1N2.bit.INT1E = 1; //enable INT1 flag
AdcaRegs.ADCINTFLGCLR.bit.ADCINT1 = 1; //make sure INT1 flag is cleared
//Set pulse positions to late
AdcaRegs.ADCCTL1.bit.INTPULSEPOS = 1;
//power up the ADC
AdcaRegs.ADCCTL1.bit.ADCPWDNZ = 1;
//delay for 1ms to allow ADC time to power up
DELAY_US(1000);
EDIS;
}
void InitCMPSS(void)
{
EALLOW;
CpuSysRegs.PCLKCR14.bit.CMPSS3 = 0; //禁用时钟
//将CMPSS分配给CPU1
DevCfgRegs.CPUSEL12.bit.CMPSS3 = 0;
CpuSysRegs.PCLKCR14.bit.CMPSS3 = 1; //启用时钟
EDIS;
EALLOW;
//
//Enable CMPSS
//
Cmpss3Regs.COMPCTL.bit.COMPDACE = 1;
//NEG signal comes from DAC
//
Cmpss3Regs.COMPCTL.bit.COMPHSOURCE = NEGIN_DAC;
//
//Use VDDA as the reference for DAC
//
Cmpss3Regs.COMPDACCTL.bit.SELREF = REFERENCE_VDDA; //VDDA的值是多少 3.3
//选择同步或异步比较器触发
// Cmpss3Regs.COMPCTL.bit.ASYNCHEN = 0; //High comparator asynchronous path enable. Allows asynchronous comparator output to feed into OR gate with latched digital filter signal when CTRIPHSEL=3 or CTRIPOUTHSEL=3
//
// Configure CTRIPOUT path
// Asynch output feeds CTRIPH and CTRIPOUTH
//
Cmpss3Regs.COMPCTL.bit.COMPHINV=0; // 0比较器同相输出 1 比较器反相输出
//配置数字滤波器
//最大SAMPWIN值提供最大数量的样本(5位)
Cmpss3Regs.CTRIPHFILCTL.bit.SAMPWIN = 15 ;
//最大THRESH值需要整个窗口的静态值
//(5 位 THRESH 应该大于 SAMPWIN 的一半)
Cmpss3Regs.CTRIPHFILCTL.bit.THRESH = 13 ;
//最大 CLKPRESCALE 值提供样本之间的最长时间(12 位)
Cmpss3Regs.CTRIPHFILCLKCTL.bit.CLKPRESCALE =1 ; //234
//重置过滤逻辑并开始过滤
Cmpss3Regs.CTRIPHFILCTL.bit.FILINIT = 1;
//清除锁存器
// Cmpss3Regs.COMPSTSCLR.bit.HSYNCCLREN=1; //1 EPWMSYNCPER will reset latch
Cmpss3Regs.COMPSTSCLR.bit.HLATCHCLR = 1;
//配置CTRIPOUT路径
// Cmpss3Regs.COMPCTL.bit.CTRIPHSEL = 0;
//同步清除使能
// Cmpss3Regs.COMPSTSCLR.bit.HSYNCCLREN = 1;
//COMPCTL.bit.ASYNCHEN 设置
// Cmpss3Regs.COMPCTL.bit.CTRIPHSEL = CTRIP_ASYNCH;
Cmpss3Regs.COMPCTL.bit.CTRIPHSEL = CTRIP_FILTER;
// Cmpss3Regs.COMPCTL.bit.CTRIPOUTHSEL = CTRIP_ASYNCH;
Cmpss3Regs.COMPCTL.bit.CTRIPOUTHSEL = CTRIP_FILTER;
//
// Configure CTRIPOUTH output pin
// Configure OUTPUTXBAR3 to be CTRIPOUT1H
//
OutputXbarRegs.OUTPUT3MUX0TO15CFG.bit.MUX4 = 0;
//
//Enable OUTPUTXBAR3 Mux for Output
//
OutputXbarRegs.OUTPUT3MUXENABLE.bit.MUX4 = 1;
//
//DAC source select. Determines whether DACHVALA is updated from DACHVALS or from the ramp generator
//
Cmpss3Regs.COMPDACCTL.bit.DACSOURCE = 1; // 0 DAC updated from DACHVALS, 1 DAC updated from the ramp generator
// Cmpss3Regs.COMPDACCTL.bit.RAMPLOADSEL=1; //斜坡加载模式 Ramp load select. Determines whether RAMPSTS is updated from RAMPMAXREFA or RAMPMAXREFS when COMPSTS[COMPHSTS] is triggered.
Cmpss3Regs.COMPDACCTL.bit.SWLOADSEL=1; /*Software load select. Determines whether DACxVALA is updated
from DACxVALS on SYSCLK or EPWMSYNCPER.
0 DACxVALA is updated from DACxVALS on SYSCLK
1 DACxVALA is updated from DACxVALS on EPWMSYNCPER
*/
//
//Ramp generator source select. Determines which EPWMSYNCPER signal is used within the CMPSS module
//
Cmpss3Regs.COMPDACCTL.bit.RAMPSOURCE = 0; // 0 EPWM1SYNCPER, 3 EPWM4SYNCPER 更改EPWM需要修改
EDIS;
Cmpss3Regs.RAMPDECVALS = slopeval;
Cmpss3Regs.RAMPMAXREFS = 30000; //2048==> 2048/16 *2.5(ref) /4096=dacout 0.07
}
//
// InitEPWM - Initialize EPWM1 module settings
//
void InitEPWM(void)
{
EALLOW;
// ClkCfgRegs.PERCLKDIVSEL.bit.EPWMCLKDIV=1; //EPWM分频器
CpuSysRegs.PCLKCR0.bit.TBCLKSYNC = 0;
//
//Configure EPWM to run at SYSCLK
//
// ClkCfgRegs.PERCLKDIVSEL.bit.EPWMCLKDIV = 0;
EPwm1Regs.TBCTL.bit.CLKDIV = 0;
EPwm1Regs.TBCTL.bit.HSPCLKDIV = 0;
//Initialize dummy values for EPWM CTR/PRD
//
EPwm1Regs.TBCTR = 0;
EPwm1Regs.TBPRD = 117; // 850kHz PWM
CpuSysRegs.PCLKCR0.bit.TBCLKSYNC = 1;
EPwm1Regs.TBCTL.bit.PHSEN = TB_DISABLE; // Disable phase loading禁止计数器装载相位寄存器的值
EPwm1Regs.TBPHS.bit.TBPHS= 0;/* Set Phase register to zero */
EPwm1Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_DISABLE; // Sync down-stream module
EPwm1Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW; //影子装载模式
EPwm1Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
EPwm1Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO; // Load on Zero在CTR=0时,影子寄存器装载
EPwm1Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;
//
//Configure TRIP4 to be CTRIP3H
//
EPwmXbarRegs.TRIP4MUX0TO15CFG.bit.MUX4 = 0; // 0.4 是CMPSS3的CTRIPH
//Enable TRIP4 Mux for Output
//
EPwmXbarRegs.TRIP4MUXENABLE.bit.MUX4 = 1;
// Enable PWM
//
EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP;
EPwm1Regs.CMPA.bit.CMPA =97; //max duty limit 97/117 考虑了死区 0.82最大占空比
// EPwm1Regs.CMPB.bit.CMPB =107; //max duty limit 97/117 考虑了死区 0.82最大占空比
// Set actions
//
EPwm1Regs.AQCTLA.bit.ZRO = AQ_SET; // Set PWM1A on event A, up count
EPwm1Regs.AQCTLA.bit.CAU = AQ_CLEAR; // Clear PWM1A on event A, up count 限制最大占空比防止一直高电平
EPwm1Regs.AQCTLA2.bit.T1U = AQ_CLEAR; // Action when event occurs on T2 in UP-Count
// EPwm1Regs.AQCTLB.bit.ZRO = AQ_SET; // Set PWM1B on event B, up count
// EPwm1Regs.AQCTLB.bit.CAU = AQ_CLEAR; // Set PWM1B on event B, up count
//EPwm1Regs.AQCTLB2.bit.T2U = AQ_CLEAR; // Action when event occurs on T2 in UP-Count
EPwm1Regs.AQTSRCSEL.bit.T1SEL = 1; // 0:DCAEVT1, 1:DCAEVT2, 2:DCBEVT1, 3:DCBEVT2
//
//---------------------------- Active Low PWMs - Setup Deadband
//
// EPwm1Regs.DBCTL.bit.HALFCYCLE = 1; // Half cycle clocking enabled
EPwm1Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE;
EPwm1Regs.DBCTL.bit.POLSEL = DB_ACTV_HIC;
EPwm1Regs.DBCTL.bit.DEDB_MODE=0;
EPwm1Regs.DBCTL.bit.IN_MODE = DBA_ALL;
// EPwm1Regs.DBCTL.bit.IN_MODE =DBA_RED_DBB_FED;
EPwm1Regs.DBRED.bit.DBRED = 9; //死区时间 DBFED × TTBCLK(10nS @100Mhz)
EPwm1Regs.DBFED.bit.DBFED = 9;
//-----ET------------------------触发ADC采样-----------------------
EPwm1Regs.ETSEL.bit.SOCAEN = 1; /* Enable SOC on A group */
EPwm1Regs.ETSEL.bit.SOCASEL =1; //001: Enable event time-base counter equal to zero. (TBCTR = 0x00)
EPwm1Regs.ETPS.bit.SOCPSSEL = 1; //EPWMxSOC A/B Pre-Scale Selection Bits 预分频
// EPwm1Regs.ETPS.bit.INTPSSEL=1;
// EPwm1Regs.ETPS.bit.SOCAPRD=1;
EPwm1Regs.ETSOCPS.bit.SOCAPRD2 = 6; /* Generate pulse on 6st event */
// EPwm1Regs.ETCLR.bit.SOCA=1; //清除SOCA中断标志位
// EPwm1Regs.TZSEL.bit.DCAEVT2 = 1; // Enable DCAEVT2 as a CBC trip source for this ePWM module
// EPwm1Regs.TZCBCCLR.bit.DCAEVT2 = 1; // Clear Flag for Digital Compare Output A Event 2 selected for CBC
// EPwm1Regs.TZCLR.bit.DCAEVT2=1 ; //
// EPwm1Regs.TZCLR.bit.CBCPULSE=0; //00: CTR = zero pulse clears CBC trip latch. (Same as legacy designs.)
// EPwm1Regs.TZSEL.bit.DCBEVT2 = 1; // Enable DCAEVT2 as a CBC trip source for this ePWM module
// EPwm1Regs.TZCBCCLR.bit.DCBEVT2 = 1; // Clear Flag for Digital Compare Output A Event 2 selected for CBC
// EPwm1Regs.TZCLR.bit.DCBEVT2=1 ; //
// EPwm1Regs.TZCLR.bit.CBCPULSE=0; //00: CTR = zero pulse clears CBC trip latch. (Same as legacy designs.)
// EPwm1Regs.TZCTL.bit.TZA = TZ_FORCE_LO;/* EPWM1A will go low */
// EPwm1Regs.TZCTL.bit.TZA = TZ_FORCE_LO;/* EPWM1A will go low */
// EPwm1Regs.TZCTL.bit.TZB = TZ_NO_CHANGE;/* EPWM1B has no action */
EPwm1Regs.TZCTL.bit.DCAEVT2 = TZ_FORCE_LO; // 10: Force EPWMxA to a low state
EPwm1Regs.TZCTL.bit.DCBEVT2 = TZ_NO_CHANGE; // 11: Do Nothing, trip action is disabled
// EPwm1Regs.TZCTL2.bit.ETZE = 1;
EPwm1Regs.DCTRIPSEL.bit.DCAHCOMPSEL = 3; // Trip 4
// EPwm1Regs.DCTRIPSEL.bit.DCBHCOMPSEL = 3; // Trip 4
EPwm1Regs.TZDCSEL.bit.DCAEVT2 = TZ_DCAH_HI; // 010: DCAH = high, DCAL = don't care
// EPwm1Regs.TZDCSEL.bit.DCBEVT2 =TZ_DCAH_HI;; // 010: DCBH = high, DCBL = don't care
EPwm1Regs.DCACTL.bit.EVT2SRCSEL =1; // 0: Source Is DCAEVT1 Signal; 1: Source Is DCEVTFILT Signal
EPwm1Regs.DCACTL.bit.EVT2FRCSYNCSEL = 0; // 0: Source is synchronized with EPWMCLK; 1: Source is passed through asynchronously
// EPwm1Regs.DCBCTL.bit.EVT2SRCSEL =1; // 0: Source Is DCAEVT1 Signal; 1: Source Is DCEVTFILT Signal
// EPwm1Regs.DCBCTL.bit.EVT2FRCSYNCSEL = 1; // 0: Source is synchronized with EPWMCLK; 1: Source is passed through asynchronously
//---空窗设置-------------------------------------------------------------------------------
EPwm1Regs.DCFCTL.bit.SRCSEL = 1; // 01: Source Is DCAEVT2 Signal
EPwm1Regs.DCFCTL.bit.BLANKE = 1; // 1: Blanking window is enabled
EPwm1Regs.DCFCTL.bit.BLANKINV = 0; // 0: Blanking window not inverted; 1: Blanking window inverted
EPwm1Regs.DCFCTL.bit.PULSESEL = 1; // 01: Time-base counter equal to zero
EPwm1Regs.HRPCTL.bit.PWMSYNCSELX = 0; // EPWMSYNCPER is defined by PWMSYNCSEL 0 EPWM1
EPwm1Regs.HRPCTL.bit.PWMSYNCSEL = 1; // 1:CTR = zero; 0:CTR = PRD
EDIS;
EPwm1Regs.DCFOFFSET =13;
EPwm1Regs.DCFWINDOW = 0; //DCFWINDOW*TB_WINDOW(10nS @100Mhz)
}
struct pid{
double err; //定义偏差值
double err_last; //定义上一个偏差值
double err_pre; //定义上上一个偏差值
double Kp,Ki,Kd; //定义比例,积分,微分系数
double det_err_pi;
double out_pi;
} pid;
//初始化变量
void pid_init()
{
pid.err=0;
pid.err_last=0;
pid.err_pre=0;
pid.Kp=2; //kp=0.05;ki=0.01 PI参数调节
pid.Ki=0.0015;
// pid.Kd=1;
pid.out_pi=0; //初始duty
pid.det_err_pi=0;
}
interrupt void adc_isr(void)
{
i++;
GpioDataRegs.GPASET.bit.GPIO12 = 1;/* Set GPIO12 (for timing purposes) */
AdcaRegs.ADCINTFLGCLR.bit.ADCINT1 = 1;/* Clr ADCINT1 flag for next SOC */
PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;/* Acknowledge interrupt to PIE */
Vo_ave=((AdcaResultRegs.ADCRESULT0)+(AdcaResultRegs.ADCRESULT1)+(AdcaResultRegs.ADCRESULT2)+(AdcaResultRegs.ADCRESULT3))>>2;
pid.err=Vo_ref-Vo_ave;
pid.err=0.5*(pid.err+pid.err_last);
pid.out_pi=pid.out_pi+pid.Kp*(pid.err-pid.err_last)+pid.Ki*pid.err;
pid.err_last=pid.err;
if (pid.out_pi<0)
pid.out_pi=0;
if (pid.out_pi>65530)
pid.out_pi=65530;
// Cmpss3Regs.RAMPMAXREFS=pid.out_pi;
GpioDataRegs.GPACLEAR.bit.GPIO12 = 1;/* Set GPIO12 (for timing purposes) */
// ; //观察i值,判断有无进入中断
return;
}
/****************************************************************************
// No more.
****************************************************************************/