序言:
本博客是DSP小白根据DSP28335编写的SPWM程序,频率为10KHz,通过示波器观测ePWM1A,ePWM1B为互补对称的波形;
需要了解到的基础知识有:
1.ePWM的工作原理,主要是七个寄存器的配置,本次主要用到五个:TB,用于设置周期,计数;CC设置比较点,这一点往往是电平翻转点;AQ,动作模块,确定了占空比;DB,考虑到实际工程需要,要防直通,需要设置死区延时;ET,事件触发,触发后执行相应的中断;
2.中断的三级响应机制,主要包括:外设级,PIE级,CPU级中断;
3.了解电力电子中的规则采样法,本方法相较于不对称采样法简单易行;
SPWM其实原理简单,编程的时候主要注意初始化函数和在中断中刷新采样点,并及时清除中断标志位,迎接下一次中断的到来。
设计思路:
利用TB模块设置载波,CMPA模块设置比较点,通过中断的方式不断刷新比较点,得到SPWM波。**
程序方案:
/*
* pwm1.c
* Created on: 2021年1月5日
* Author: guo
*/
#include "DSP2833x_Device.h" // DSP2833x Headerfile Include File
#include "DSP2833x_Examples.h" // DSP2833x Examples Include File
#include "math.h"
void InitEPwm1Example(void);
interrupt void epwm1_timer_isr(void); //函数的声明,因为函数体的定义在最后,这个是自己定义的
int k,N=256;
float m=0.8;//设置调制度
int COUNT=7500; // 周期寄存器的值设置为7500,Ts=10KHz,增减计数模式下开关频率为10KHz,变量才能观测,宏定义不可以 k=150e6/10e4/2=7500
void main(void)
{ InitSysCtrl();
InitEPwm1Gpio(); //初始化gpio
DINT;
InitPieCtrl();
IER = 0x0000;
IFR = 0x0000;
InitPieVectTable(); //初始化中断向量表-主要是CMPA引发的中断
EALLOW;
PieVectTable.EPWM1_INT = &epwm1_timer_isr; //把中断的地址赋给中断向量表 //中断
EDIS;
EALLOW;
SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 0;
EDIS;
InitEPwm1Example(); //PWM
EALLOW;
SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1; //同步时钟 //启动所有同步计数器 //见课本P52
EDIS;
IER |= M_INT3;
PieCtrlRegs.PIEIER3.bit.INTx1 = 1; //外部中断 使能第三组中断的第一个小中断
EINT; //开CPU级中断响应
ERTM;
}
void InitEPwm1Example(void) //思路:载波,比较点,电平翻转,死区时间
{
EPwm1Regs.TBPRD = COUNT; //频率设置为10k
EPwm1Regs.TBPHS.half.TBPHS = 0x0000; //联合体里面包含结构体
EPwm1Regs.TBCTR = 0x0000; //时机计数器初始化值为0,从零开始计时
EPwm1Regs.CMPA.half.CMPA = 1500; //联合体里面包含结构体
EPwm1Regs.CMPB = 1500;
EPwm1Regs.TBCTL.bit.CTRMODE = 2; //上下计数模式
EPwm1Regs.TBCTL.bit.PHSEN = 0;
EPwm1Regs.TBCTL.bit.HSPCLKDIV = 0;
EPwm1Regs.TBCTL.bit.CLKDIV = 0;
EPwm1Regs.CMPCTL.bit.SHDWAMODE = 0;
EPwm1Regs.CMPCTL.bit.SHDWBMODE = 0;
EPwm1Regs.CMPCTL.bit.LOADAMODE = 2;
EPwm1Regs.CMPCTL.bit.LOADBMODE = 2; //采用影子寄存器下的装载模式2
EPwm1Regs.AQCTLA.bit.CAU = 1;
EPwm1Regs.AQCTLA.bit.CAD = 2;
EPwm1Regs.AQCTLB.bit.CAU = 2;
EPwm1Regs.AQCTLB.bit.CAD = 1; //epwm1输出为互补的PWM波形
EPwm1Regs.ETSEL.bit.INTSEL = 1; //事件触发模块寄存器ET
EPwm1Regs.ETSEL.bit.INTEN = 1;
EPwm1Regs.ETPS.bit.INTPRD = 1;//事件触发为1
EPwm1Regs.DBCTL.all = 0xb; //死区双边延时,1011 //参见课本P164 P163那个图
EPwm1Regs.DBRED = 80; //上升沿延时
EPwm1Regs.DBFED = 80; //下降沿延时
}
interrupt void epwm1_timer_isr(void) //中断服务程序
{
if(k >= N)
{
k = 0;
}
EPwm1Regs.CMPA.half.CMPA = EPwm1Regs.TBPRD*(1+m*sin(2*3.14159*k/N))/2;
EPwm1Regs.CMPB=EPwm1Regs.TBPRD*(1+m*sin(2*3.14159*k/N))/2;
k++;
EPwm1Regs.ETCLR.bit.INT = 1; //中断标志位清零才能进入下一次的中断,在PWM的ET模块中
PieCtrlRegs.PIEACK.all = PIEACK_GROUP3; //使能中断 PIEACK_GROUP3
}
代码部分做了相应的解释,不过如果和我一样是新手的话,建议注意:
1.28335的工程模板最好要选一份靠谱点的,复制进去运行基本就没啥问题,缺少头文件和源文件很难受;
2.在别人的基础上弄明白,再自己编写一个想要的程序,这样可以很好的节约时间,效率还高。
TPS2014B观测实验结果:
CCS调试,改变占空比:
占空比为0.8时的波形:
占空比为0.6时波形:
死区双边沿延时:
总结:
本博客主要讲述了双极性调试方式下利用DSP28335产生SPWM的思路和程序代码,希望对大家有用,也欢迎大家与我交流,共同进步提高。