DSP28335产生SPWM信号

序言:
本博客是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调试,改变占空比:
DSP28335产生SPWM信号_第1张图片
占空比为0.8时的波形:
DSP28335产生SPWM信号_第2张图片
占空比为0.6时波形:
DSP28335产生SPWM信号_第3张图片
死区双边沿延时:
DSP28335产生SPWM信号_第4张图片
总结:
本博客主要讲述了双极性调试方式下利用DSP28335产生SPWM的思路和程序代码,希望对大家有用,也欢迎大家与我交流,共同进步提高。

你可能感兴趣的:(DSP28335,嵌入式,单片机)