TMS320F28377_SVPWM完整程序

1、主函数

/*
 * main.c
 * author: wx
 * data: 2020/1/6
 * function: generate the SVPWM wave form, and use graph to see it.
 * version: 1.0
 */
 
#include "F28x_Project.h"
#include "math.h"
#include "C28x_FPU_FastRTS.h"
#include "SVPWM_2L.h"

__interrupt void cpu_timer0_isr(void);

#define PI  3.1415926535
#define PI2 1.57079632675   // PI/2
#define Ts 1e-4  // Ts is different from T!
#define InterruptTime Ts*1e6

float table_a[200];
float table_b[200];
float table_c[200];

SVPWM_2L  SVPWM;

void parameters_init()
{
	SVPWM.T = 1; //i have per-unit the T.
	SVPWM.Tcmpa = 0.5;
	SVPWM.Tcmpb = 0.5;
	SVPWM.Tcmpc = 0.5;
	SVPWM.Ualpha = 0;
	SVPWM.Ubeta = 0;
	SVPWM.Vdc = 311;
	SVPWM.calc = svpwm_2L_calc;
}

void main(void)
{
	InitSysCtrl();
	parameters_init();
	DINT;
	InitPieCtrl();
	IER = 0x0000;
	IFR = 0x0000;
	InitPieVectTable();
	EALLOW;  // This is needed to write to EALLOW protected registers
		PieVectTable.TIMER0_INT = &cpu_timer0_isr;
	EDIS;
	InitCpuTimers();
	ConfigCpuTimer(&CpuTimer0, 200, InterruptTime);  
	CpuTimer0Regs.TCR.all = 0x4000; // Allow interrupt, start timer
	IER |= M_INT1;
	PieCtrlRegs.PIEIER1.bit.INTx7 = 1;
	EINT;  // Enable Global interrupt INTM
	ERTM;  // Enable Global realtime interrupt DBGM

    for(;;)
    {

    }
}

__interrupt void cpu_timer0_isr(void)
{
   CpuTimer0.InterruptCount++;

   static int i=0;

   SVPWM.Ualpha = 100 * sin(100 * PI * SVPWM.T * Ts * i);
   SVPWM.Ubeta = 100 * sin(100 * PI * SVPWM.T * Ts * i + PI2);

   SVPWM.calc(&SVPWM);

   table_a[i] = SVPWM.Tcmpa;
   table_b[i] = SVPWM.Tcmpb;
   table_c[i] = SVPWM.Tcmpc;
   i++;

   if (i >= 200) i=0;

   PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;
}

2、svpwm.c

/*
 * svpwm_2L_calc.c
 *
 *  Created on: 2020/1/8
 *      Author: Administrator
 */
#include "F28x_Project.h"
#include "math.h"
#include "SVPWM_2L.h"
#include "C28x_FPU_FastRTS.h"

void svpwm_2L_calc(SVPWM_2L *p)
{
	 float temp;
	 float X,Y,Z, t1,t2;
	 Uint16 A,B,C,N,Sector;
	 float Ta, Tb, Tc;
	 float K=1.73205081;//sqrt(3)/2
	 //p->T=1.0;//Normalize the whole modulation period
	 X= K*p->Ubeta/p->Vdc*p->T;
	 Y=(K*p->Ubeta+3*p->Ualpha)/(2*p->Vdc)*p->T;
	 Z=(K*p->Ubeta-3*p->Ualpha)/(2*p->Vdc)*p->T;
	//
	 if(p->Ubeta>0)
	   {A=1;}
	 else
	   {A=0;}

	 if( (K*p->Ualpha - p->Ubeta)>0 )
	   {B=1;}
	 else
	   {B=0;}

	 if((-K*p->Ualpha - p->Ubeta)>0)
	   {C=1;}
	 else
	   {C=0;}

	 N=A+2*B+4*C;
//
	 switch(N)
	 {
		case 1:{Sector=2;break;}
		case 2:{Sector=6;break;}
		case 3:{Sector=1;break;}
		case 4:{Sector=4;break;}
		case 5:{Sector=3;break;}
		case 6:{Sector=5;break;}
		 default:{;}
	 }
 //
	switch(Sector)
	{
		case 1: {t1=-Z; t2= X;break;}
		case 2: {t1= Z; t2= Y;break;}
		case 3: {t1= X; t2=-Y;break;}
		case 4: {t1=-X; t2= Z;break;}
		case 5: {t1=-Y; t2=-Z;break;}
		case 6: {t1= Y; t2=-X;break;}
		  default:{;}
	}

	if((t1+t2)>p->T)//对过调制情况进行调整
	 {
		  temp=t1+t2;
		  t1=t1*p->T/temp;
		  t2=t2*p->T/temp;
	 }

	//
	 Ta=(p->T-t1-t2)/4;//作用时间分配
	 Tb=Ta+t1/2;
	 Tc=Tb+t2/2;

	 switch(Sector)
	  {
		case 1: {p->Tcmpa=Ta; p->Tcmpb=Tb; p->Tcmpc=Tc; break;}
		case 2: {p->Tcmpa=Tb; p->Tcmpb=Ta; p->Tcmpc=Tc; break;}
		case 3: {p->Tcmpa=Tc; p->Tcmpb=Ta; p->Tcmpc=Tb; break;}
		case 4: {p->Tcmpa=Tc; p->Tcmpb=Tb; p->Tcmpc=Ta; break;}
		case 5: {p->Tcmpa=Tb; p->Tcmpb=Tc; p->Tcmpc=Ta; break;}
		case 6: {p->Tcmpa=Ta; p->Tcmpb=Tc; p->Tcmpc=Tb; break;}
		  default:{;}
	  }
}

3、svpwm.h

/*
 * SVPWM_2L.h
 *
 *  Created on: 2020/1/8
 *      Author: Administrator
 */

#ifndef SVPWM_2L_H_
#define SVPWM_2L_H_

typedef struct  { float  Ualpha;  // Input: reference alpha-axis phase voltage
                  float  Ubeta;   // Input: reference beta-axis phase voltage
                  float  Vdc;     // Input: DC voltage
                  float  T;       // Input: PWM Modulation Period
                  float  Tcmpa; // Output: reference phase-a switching function
                  float  Tcmpb; // Output: reference phase-b switching function
                  float  Tcmpc; // Output: reference phase-c switching function
                  void (*calc)();       // Pointer to calculation function
                } SVPWM_2L;
void svpwm_2L_calc(SVPWM_2L *p);
#endif /* SVPWM_2L_H_ */

实现的效果图
在这里插入图片描述

### 使用DSP实现空间矢量脉宽调制(SVPWM) #### DSP实现SVPWM的关键要素 在现代电力电子控制系统中,数字信号处理器(DSP)因其高速运算能力和实时处理能力而成为实施复杂控制算法的理想平台。对于SVPWM而言,在DSP上的实现不仅能够提高系统的响应速度和精度,还具备良好的灵活性和支持多种复杂的控制策略。 为了有效地利用DSP执行SVPWM算法,通常需要完成以下几个方面的工作: - **初始化配置**:设置定时器中断周期、PWM模块参数以及ADC采样率等硬件资源。 - **扇区判断与计算有效作用时间**:依据当前逆变器输出电压向量的位置确定其所在的六边形区域,并据此计算各开关器件的有效导通时间和死区补偿值。 - **生成PWM波形**:根据上述得到的作用时间和设定的载频频率构建相应的PWM信号序列并发送给功率级电路中的IGBT或其他类型的全控型开关元件。 这些操作可以通过编写高效的C/C++程序来完成,下面给出一段简化版的伪代码示例[^1]。 ```c // 定义全局变量 float Vref[3]; // 参考电压向量分量 int sector; // 当前所在扇区编号(0~5) float T1, T2; // 开关状态持续时间段长度 unsigned int PWM_Timing[6]; // 各相PWM占空比数组 void svpwm_init(void){ // 初始化函数体... } void calculate_sector_and_time(float *Vref_ptr){ float theta; // 计算角度θ theta = atan2(Vref_ptr[1], Vref_ptr[0]); if(theta >= -PI/6 && theta < PI/6){sector=1;} else if(theta >= PI/6 && theta < PI*3/6){sector=2;} ... // 继续定义其他五个区间 // 根据选定的扇区计算T1,T2的具体数值 switch(sector){ case 1: T1 = ... ; T2 = ... ; break; case 2: T1 = ... ; T2 = ... ; break; // 其他情况省略... } } void generate_pwm_signal(unsigned int *duty_cycle_array){ // 设置PWM比较寄存器值以形成期望的PWM模式 } ``` 此段代码展示了如何在一个典型的嵌入式环境中组织SVPWM的核心逻辑流程。实际应用时还需要考虑更多细节问题,比如过流保护机制的设计、温度监控等功能扩展。
评论 26
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值