求DSP28335产生SPWM波形程序
#include "DSP2833x_Device.h" // DSP2833x Headerfile Include File#include "DSP2833x_Examples.h" // DSP2833x Examples Include File
double sin_180[]={0.000000,0.034899,0.069756,0.104528,0.139173,0.173648,0.207911,0.241921,0.275637,0.309016, 0.342020,0.374606,0.406736,0.438371,0.469471,0.500000,0.529919,0.559192,0.587785,0.615661, 0.642787,0.669130,0.694658,0.719339,0.743144,0.766044,0.788010,0.809016,0.829037,0.848048, 0.866025,0.882947,0.898794,0.913545,0.927183,0.939692,0.951056,0.961261,0.970295,0.978147, 0.984807,0.990268,0.994521,0.997564,0.999390,1.000000,0.999390,0.997564,0.994521,0.990268, 0.984807,0.978147,0.970295,0.961261,0.951056,0.939692,0.927183,0.913545,0.898794,0.882947, 0.866025,0.848048,0.829037,0.809016,0.788010,0.766044,0.743144,0.719339,0.694658,0.669130, 0.642787,0.615661,0.587785,0.559919,0.529919,0.500000,0.469471,0.438371,0.406736,0.374606, 0.342020,0.309016,0.275637,0.241921,0.207911,0.173648,0.139173,0.104528,0.069756,0.034899, 0.000000,-0.034899,-0.069756,-0.104528,-0.139173,-0.173648,-0.207911,-0.241921,-0.275637,-0.309016, -0.342020,-0.374606,-0.406736,-0.438371,-0.469471,-0.500000,-0.529919,-0.559192,-0.587785,-0.615661, -0.642787,-0.669130,-0.694658,-0.719339,-0.743144,-0.766044,-0.788010,-0.809016,-0.829037,-0.848048, -0.866025,-0.882947,-0.898794,-0.913545,-0.927183,-0.939692,-0.951056,-0.961261,-0.970295,-0.978147, -0.984807,-0.990268,-0.994521,-0.997564,-0.999390,-1.000000,-0.999390,-0.997564,-0.994521,-0.990268, -0.984807,-0.978147,-0.970295,-0.961261,-0.951056,-0.939692,-0.927183,-0.913545,-0.898794,-0.882947, -0.866025,-0.848048,-0.829037,-0.809016,-0.788010,-0.766044,-0.743144,-0.719339,-0.694658,-0.669130, -0.642787,-0.615661,-0.587785,-0.559919,-0.529919,-0.500000,-0.469471,-0.438371,-0.406736,-0.374606, -0.342020,-0.309016,-0.275637,-0.241921,-0.207911,-0.173648,-0.139173,-0.104528,-0.069756,-0.034899, };typedef struct{ volatile struct EPWM_REGS *EPwmRegHandle; Uint16 EPwm_CMPA_Direction; Uint16 EPwm_CMPB_Direction; Uint16 EPwmTimerIntCount; Uint16 EPwmMaxCMPA; Uint16 EPwmMinCMPA; Uint16 EPwmMaxCMPB; Uint16 EPwmMinCMPB;}EPWM_INFO;// Global variables used in this exampleEPWM_INFO epwm1_info;EPWM_INFO epwm2_info;EPWM_INFO epwm3_info;// Configure the period for each timer#define EPWM1_TIMER_TBPRD 1024 // Period register 0~2^16/*#define EPWM1_MAX_CMPA 8000#define EPWM1_MIN_CMPA 500#define EPWM1_MAX_CMPB 8000#define EPWM1_MIN_CMPB 500#define EPWM2_TIMER_TBPRD 2000 // Period register#define EPWM2_MAX_CMPA 1950#define EPWM2_MIN_CMPA 50#define EPWM2_MAX_CMPB 1950#define EPWM2_MIN_CMPB 50#define EPWM3_TIMER_TBPRD 2000 // Period register#define EPWM3_MAX_CMPA 1950#define EPWM3_MIN_CMPA 50#define EPWM3_MAX_CMPB 1950#define EPWM3_MIN_CMPB 50*/#define EPWM_CMP_UP 1#define EPWM_CMP_DOWN 0void InitEPWM1(void);interrupt void epwm1_isr(void);interrupt void epwm2_isr(void);interrupt void epwm3_isr(void);void update_compare(EPWM_INFO*);void main(void){ InitSysCtrl(); //系统时钟初始化 InitXintf16Gpio(); //外设端口初始化 16位数据线 20位地址线 DINT; InitPieCtrl(); //PIE 控制寄存器初始化 IER = 0x0000; //关中断 IFR = 0x0000; //清除中断标志 InitPieVectTable(); //初始化pie映射向量表 EALLOW; // This is needed to write to EALLOW protected registers PieVectTable.EPWM1_INT = &epwm1_isr;// PieVectTable.EPWM2_INT = &epwm2_isr;// PieVectTable.EPWM3_INT = &epwm3_isr; EDIS; // This is needed to disable write to EALLOW protected registers EALLOW; SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 0; EDIS; InitEPWM1(); EALLOW; SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1; EDIS; // Step 5. User specific code, enable interrupts: // Enable CPU INT3 which is connected to EPWM1-3 INT: IER |= M_INT3; // Enable EPWM INTn in the PIE: Group 3 interrupt 1-3 PieCtrlRegs.PIEIER3.bit.INTx1 = 1; PieCtrlRegs.PIEIER3.bit.INTx2 = 1; PieCtrlRegs.PIEIER3.bit.INTx3 = 1; // Enable global Interrupts and higher priority real-time debug events: EINT; // Enable Global interrupt INTM ERTM; // Enable Global realtime interrupt DBGM for(;;) { asm(" NOP"); }}interrupt void epwm1_isr(void){ // Update the CMPA and CMPB values update_compare(&epwm1_info); // Clear INT flag for this timer EPwm1Regs.ETCLR.bit.INT = 1; // Acknowledge this interrupt to receive more interrupts from group 3 PieCtrlRegs.PIEACK.all = PIEACK_GROUP3;}interrupt void epwm2_isr(void){ // Update the CMPA and CMPB values update_compare(&epwm2_info); // Clear INT flag for this timer EPwm2Regs.ETCLR.bit.INT = 1; // Acknowledge this interrupt to receive more interrupts from group 3 PieCtrlRegs.PIEACK.all = PIEACK_GROUP3;}interrupt void epwm3_isr(void){ // Update the CMPA and CMPB values update_compare(&epwm3_info); // Clear INT flag for this timer EPwm3Regs.ETCLR.bit.INT = 1; // Acknowledge this interrupt to receive more interrupts from group 3 PieCtrlRegs.PIEACK.all = PIEACK_GROUP3;} void InitEPWM1(void){InitEPwm1Gpio(); // Setup TBCLK EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP; // 时基计数器计数模式 EPwm1Regs.TBPRD = EPWM1_TIMER_TBPRD; // 计数次数 T=TB*TBPRD EPwm1Regs.TBCTL.bit.PHSEN = TB_DISABLE; // Disable phase loading EPwm1Regs.TBPHS.half.TBPHS = 0x0000; // Phase is 0 EPwm1Regs.TBCTR = 0x0000; // Clear counter EPwm1Regs.TBCTL.bit.HSPCLKDIV = TB_DIV4; // TB=1/SYSCLKOUT*[CLKDIV]*[HSPCLKDIV] EPwm1Regs.TBCTL.bit.CLKDIV = TB_DIV2; // Setup shadow register load on ZERO EPwm1Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW; EPwm1Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW; EPwm1Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO; EPwm1Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO; // Set Compare values EPwm1Regs.CMPA.half.CMPA = 10; // Set compare A value // EPwm1Regs.CMPB = 1500; // Set Compare B value EPwm1Regs.AQCTLA.bit.ZRO = AQ_SET; // Set PWM1A on Zero EPwm1Regs.AQCTLA.bit.CAU = AQ_CLEAR; // Clear PWM1A on event A, up count EPwm1Regs.AQCTLB.bit.ZRO = AQ_SET; // Set PWM1B on Zero EPwm1Regs.AQCTLB.bit.CBU = AQ_CLEAR; // Clear PWM1B on event B, up countEPwm1Regs.DBCTL.all=0xb; // EPWMxB is invertedEPwm1Regs.DBRED=70; //CHANNEL EPWMA 0~1023 (死区时间>momsfet上升时间+驱动上升时间+分布电容)EPwm1Regs.DBFED=50; //CHANNEL EPWMB 0~1023EPwm1Regs.TZSEL.all=0;EPwm1Regs.TZCTL.all=0;EPwm1Regs.TZEINT.all=0;EPwm1Regs.TZFLG.all=0;EPwm1Regs.TZCLR.all=0;EPwm1Regs.TZFRC.all=0;// Interrupt where we will change the Compare ValuesEPwm1Regs.ETSEL.bit.INTSEL = ET_CTR_ZERO; // Select INT on Zero event EPwm1Regs.ETSEL.bit.INTEN = 1; // Enable INT EPwm1Regs.ETPS.bit.INTPRD = ET_2ND; // Generate INT on 2rd event epwm1_info.EPwm_CMPA_Direction = EPWM_CMP_UP; // Start by increasing CMPA & CMPB epwm1_info.EPwm_CMPB_Direction = EPWM_CMP_UP; epwm1_info.EPwmTimerIntCount = 0; // Zero the interrupt counter epwm1_info.EPwmRegHandle = &EPwm1Regs; // Set the pointer to the ePWM module/* epwm1_info.EPwmMaxCMPA = EPWM1_MAX_CMPA; // Setup min/max CMPA/CMPB values epwm1_info.EPwmMinCMPA = EPWM1_MIN_CMPA; epwm1_info.EPwmMaxCMPB = EPWM1_MAX_CMPB; epwm1_info.EPwmMinCMPB = EPWM1_MIN_CMPB;*/} void update_compare(EPWM_INFO *epwm_info) { unsigned int temp; // Every 10'th interrupt, change the CMPA/CMPB values if(epwm_info->EPwmTimerIntCount < 179) { epwm_info->EPwmTimerIntCount++; } else { epwm_info->EPwmTimerIntCount = 0; } temp=(EPWM1_TIMER_TBPRD)*(0.85*(sin_180[epwm_info->EPwmTimerIntCount]+sin_180[epwm_info->EPwmTimerIntCount+1])*0.25+0.5);// if(temp>=0.95*EPWM1_TIMER_TBPRD)// temp=0.98*EPWM1_TIMER_TBPRD; // else // if(temp<=0.05*EPWM1_TIMER_TBPRD) // temp=0.02*EPWM1_TIMER_TBPRD; EPwm1Regs.CMPA.half.CMPA = temp; return; }