DSP28335实现三相SVPWM整流控制程序
基于TI DSP28335的三相SVPWM整流控制系统的程序实现,包含主程序、PWM配置、ADC采样、坐标变换、PI控制和SVPWM生成等模块。
一、系统总体架构
1.1 文件结构
SVPWM_Rectifier/
├── main.c # 主程序
├── DSP2833x_Device.h # 器件头文件
├── DSP2833x_GlobalPrototypes.h
├── SVPWM.h # SVPWM算法头文件
├── SVPWM.c # SVPWM算法实现
├── ADC.h # ADC模块头文件
├── ADC.c # ADC模块实现
├── PI_Controller.h # PI控制器头文件
├── PI_Controller.c # PI控制器实现
├── CLARK_PARK.h # 坐标变换头文件
├── CLARK_PARK.c # 坐标变换实现
├── math.h # 数学运算
└── DSP2833x_Examples.h
二、主程序实现
2.1 主程序框架 (main.c)
#include "DSP2833x_Device.h"
#include "DSP2833x_Examples.h"
#include "SVPWM.h"
#include "ADC.h"
#include "PI_Controller.h"
#include "CLARK_PARK.h"
#include "math.h"
// 系统变量定义
volatile struct {
float Va, Vb, Vc; // 三相电压采样值
float Ia, Ib, Ic; // 三相电流采样值
float Vdc; // 直流母线电压
float Vdc_ref; // 直流电压参考值
float Id_ref, Iq_ref; // dq轴电流参考
float Id_fb, Iq_fb; // dq轴电流反馈
float Vd_ref, Vq_ref; // dq轴电压参考
float Valpha, Vbeta; // αβ轴电压
float theta; // 电网电压角度
float sin_theta, cos_theta;
float frequency; // 电网频率
Uint16 ADC_index; // ADC采样索引
} SVPWM_System;
// PI控制器实例
PI_Controller DC_PI; // 直流电压PI控制器
PI_Controller Id_PI; // d轴电流PI控制器
PI_Controller Iq_PI; // q轴电流PI控制器
// 系统初始化函数
void System_Init(void)
{
// 关闭看门狗
DisableDog();
// 初始化PLL,设置系统时钟150MHz
InitPll(0xA);
// 初始化GPIO
InitGpio();
// 初始化PIE向量表
InitPieCtrl();
// 禁用所有中断
IER = 0x0000;
IFR = 0x0000;
// 初始化PIE向量表
InitPieVectTable();
// 初始化外设
InitEPwm(); // 初始化PWM模块
InitAdc(); // 初始化ADC模块
InitSci(); // 初始化SCI通信(可选)
// 初始化控制变量
SVPWM_System.Vdc_ref = 400.0; // 直流电压参考400V
SVPWM_System.Id_ref = 0.0; // 初始d轴电流参考
SVPWM_System.Iq_ref = 0.0; // 初始q轴电流参考
SVPWM_System.frequency = 50.0; // 电网频率50Hz
SVPWM_System.theta = 0.0;
// 初始化PI控制器参数
PI_Init(&DC_PI, 0.1, 0.01, 100.0, -100.0); // 直流电压环
PI_Init(&Id_PI, 0.5, 0.05, 200.0, -200.0); // d轴电流环
PI_Init(&Iq_PI, 0.5, 0.05, 200.0, -200.0); // q轴电流环
// 使能全局中断
EINT;
ERTM;
}
// 主循环
void main(void)
{
// 系统初始化
System_Init();
// 主循环
while(1)
{
// 后台任务
// 1. 读取SCI指令(如果有)
// 2. 更新参考值
// 3. 故障检测与处理
// 4. 状态监控
}
}
三、PWM模块配置
3.1 PWM初始化函数
// PWM配置 (ePWM.h/c)
#include "DSP2833x_Device.h"
#define PWM_FREQUENCY 10000.0 // PWM频率10kHz
#define SYSTEM_FREQ 150000000.0 // 系统频率150MHz
#define TB_CLK SYSTEM_FREQ/2 // 时基时钟75MHz
#define TB_PRSC 1 // 预分频
#define PWM_PERIOD (Uint16)(TB_CLK/(PWM_FREQUENCY*TB_PRSC))
void InitEPwm(void)
{
// EPWM1配置 - A相上桥臂
EPwm1Regs.TBPRD = PWM_PERIOD; // 设置周期
EPwm1Regs.TBPHS.half.TBPHS = 0; // 相位为0
EPwm1Regs.TBCTR = 0; // 计数器清零
// 时基控制寄存器
EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // 增减计数模式
EPwm1Regs.TBCTL.bit.PHSEN = TB_DISABLE; // 禁止相位加载
EPwm1Regs.TBCTL.bit.PRDLD = TB_SHADOW; // 周期寄存器影子加载
EPwm1Regs.TBCTL.bit.SYNCOSEL = TB_CTR_ZERO; // 同步输出
EPwm1Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1; // 高速时钟分频
EPwm1Regs.TBCTL.bit.CLKDIV = TB_DIV1; // 时钟分频
// 比较控制寄存器
EPwm1Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW; // CMPA影子模式
EPwm1Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW; // CMPB影子模式
EPwm1Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO; // 零时加载
EPwm1Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO; // 零时加载
// 动作限定寄存器
EPwm1Regs.AQCTLA.bit.CAU = AQ_CLEAR; // 计数器等于CMPA时清零
EPwm1Regs.AQCTLA.bit.CAD = AQ_SET; // 计数器等于CMPA时置位
EPwm1Regs.AQCTLB.bit.CAU = AQ_CLEAR; // 计数器等于CMPB时清零
EPwm1Regs.AQCTLB.bit.CAD = AQ_SET; // 计数器等于CMPB时置位
// 死区控制
EPwm1Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE; // 使能死区
EPwm1Regs.DBCTL.bit.POLSEL = DB_ACTV_HIC; // 主动高互补
EPwm1Regs.DBRED = 100; // 上升沿死区100ns
EPwm1Regs.DBFED = 100; // 下降沿死区100ns
// 事件触发配置
EPwm1Regs.ETSEL.bit.INTSEL = ET_CTR_ZERO; // 零时中断
EPwm1Regs.ETSEL.bit.INTEN = 1; // 使能中断
EPwm1Regs.ETPS.bit.INTPRD = ET_1ST; // 第一次事件触发中断
// 复制配置到EPWM2和EPWM3(B相和C相)
EPwm2Regs = EPwm1Regs;
EPwm3Regs = EPwm1Regs;
// 设置不同相位
EPwm2Regs.TBPHS.half.TBPHS = PWM_PERIOD/3; // 相位差120°
EPwm3Regs.TBPHS.half.TBPHS = 2*PWM_PERIOD/3; // 相位差240°
}
四、ADC采样模块
4.1 ADC配置
// ADC.h
#ifndef ADC_H
#define ADC_H
#include "DSP2833x_Device.h"
// ADC通道定义
#define ADC_CH_VA 0 // 通道A0: A相电压
#define ADC_CH_VB 1 // 通道A1: B相电压
#define ADC_CH_VC 2 // 通道A2: C相电压
#define ADC_CH_IA 3 // 通道A3: A相电流
#define ADC_CH_IB 4 // 通道A4: B相电流
#define ADC_CH_IC 5 // 通道A5: C相电流
#define ADC_CH_VDC 6 // 通道A6: 直流母线电压
#define ADC_CH_TEMP 7 // 通道A7: 温度采样
// 函数声明
void InitAdc(void);
void ConfigADC(void);
void ReadADCValues(void);
float GetADCScaledValue(Uint16 raw_value, float v_ref, float gain);
void ADC_Calibration(void);
#endif
4.2 ADC实现
// ADC.c
#include "ADC.h"
#include "math.h"
// ADC采样缓冲区
volatile Uint16 ADC_Result[8];
volatile Uint16 ADC_Conversion_Done = 0;
// ADC初始化
void InitAdc(void)
{
// 上电ADC模块
AdcRegs.ADCTRL1.bit.RESET = 1;
asm(" RPT #10 || NOP");
AdcRegs.ADCTRL1.bit.RESET = 0;
// ADC控制寄存器1
AdcRegs.ADCTRL1.bit.ACQ_PS = 0xF; // 采样窗口15个ADC时钟
AdcRegs.ADCTRL1.bit.SEQ_CASC = 1; // 级联序列模式
AdcRegs.ADCTRL1.bit.CONT_RUN = 0; // 启动/停止模式
AdcRegs.ADCTRL1.bit.CPS = 0; // 内核时钟分频
AdcRegs.ADCTRL1.bit.SEQ_OVRD = 0; // 不使能序列覆盖
// ADC控制寄存器3
AdcRegs.ADCTRL3.bit.ADCCLKPS = 0xF; // ADC时钟分频
AdcRegs.ADCTRL3.bit.SMODE_SEL = 0; // 顺序采样模式
AdcRegs.ADCTRL3.bit.ADCBGRFDN = 0x3; // 带隙和参考上电
AdcRegs.ADCTRL3.bit.ADCPWDN = 0x1FF; // 所有模拟电路上电
// 配置最大转换通道数
AdcRegs.ADCMAXCONV.bit.MAX_CONV1 = 0x7; // 8个转换
// 配置通道选择序列
AdcRegs.ADCCHSELSEQ1.bit.CONV00 = ADC_CH_VA; // 通道A0
AdcRegs.ADCCHSELSEQ1.bit.CONV01 = ADC_CH_VB; // 通道A1
AdcRegs.ADCCHSELSEQ1.bit.CONV02 = ADC_CH_VC; // 通道A2
AdcRegs.ADCCHSELSEQ1.bit.CONV03 = ADC_CH_IA; // 通道A3
AdcRegs.ADCCHSELSEQ2.bit.CONV04 = ADC_CH_IB; // 通道A4
AdcRegs.ADCCHSELSEQ2.bit.CONV05 = ADC_CH_IC; // 通道A5
AdcRegs.ADCCHSELSEQ2.bit.CONV06 = ADC_CH_VDC; // 通道A6
AdcRegs.ADCCHSELSEQ2.bit.CONV07 = ADC_CH_TEMP;// 通道A7
// 中断配置
AdcRegs.ADCTRL2.bit.INT_ENA_SEQ1 = 1; // 使能SEQ1中断
AdcRegs.ADCTRL2.bit.INT_MOD_SEQ1 = 0; // 每个SEQ1结束中断
AdcRegs.ADCTRL2.bit.EVA_SOC_SEQ1 = 0; // 禁止事件管理器触发
AdcRegs.ADCTRL2.bit.EXT_SOC_SEQ1 = 0; // 禁止外部触发
AdcRegs.ADCTRL2.bit.RST_SEQ1 = 0; // 不复位序列
AdcRegs.ADCTRL2.bit.SOC_SEQ1 = 0; // 清除触发
// 校准
ADC_Calibration();
}
// ADC校准
void ADC_Calibration(void)
{
Uint16 i;
volatile Uint16 *p = &AdcRegs.ADC_STAMP.bit.STAMP_LSW;
// 自校准
asm(" MOVW DP, #0x3800"); // 设置DP为ADC寄存器基址
asm(" OR @0x6, #0x4000"); // 设置ADCTRL3寄存器的自校准位
// 等待校准完成
for(i=0; i<10000; i++);
asm(" AND @0x6, #0xBFFF"); // 清除自校准位
}
// 读取ADC值
void ReadADCValues(void)
{
// 启动ADC转换
AdcRegs.ADCTRL2.bit.SOC_SEQ1 = 1;
// 等待转换完成
while(AdcRegs.ADCST.bit.INT_SEQ1 == 0);
// 读取转换结果
ADC_Result[0] = AdcRegs.ADCRESULT0 >> 4; // A相电压
ADC_Result[1] = AdcRegs.ADCRESULT1 >> 4; // B相电压
ADC_Result[2] = AdcRegs.ADCRESULT2 >> 4; // C相电压
ADC_Result[3] = AdcRegs.ADCRESULT3 >> 4; // A相电流
ADC_Result[4] = AdcRegs.ADCRESULT4 >> 4; // B相电流
ADC_Result[5] = AdcRegs.ADCRESULT5 >> 4; // C相电流
ADC_Result[6] = AdcRegs.ADCRESULT6 >> 4; // 直流电压
ADC_Result[7] = AdcRegs.ADCRESULT7 >> 4; // 温度
// 清除中断标志
AdcRegs.ADCST.bit.INT_SEQ1 = 1;
AdcRegs.ADCTRL2.bit.RST_SEQ1 = 1;
AdcRegs.ADCTRL2.bit.SOC_SEQ1 = 0;
ADC_Conversion_Done = 1;
}
// 将ADC原始值转换为实际值
float GetADCScaledValue(Uint16 raw_value, float v_ref, float gain)
{
float result;
// ADC为12位,参考电压v_ref
result = ((float)raw_value / 4096.0) * v_ref;
// 考虑传感器变比
result = result * gain;
return result;
}
五、坐标变换模块
5.1 Clark和Park变换
// CLARK_PARK.h
#ifndef CLARK_PARK_H
#define CLARK_PARK_H
typedef struct {
float alpha; // α轴分量
float beta; // β轴分量
} Clarke_Components;
typedef struct {
float d; // d轴分量
float q; // q轴分量
} Park_Components;
// 函数声明
Clarke_Components Clarke_Transform(float a, float b, float c);
Park_Components Park_Transform(float alpha, float beta, float sin_theta, float cos_theta);
Clarke_Components Inverse_Park_Transform(float d, float q, float sin_theta, float cos_theta);
void Inverse_Clarke_Transform(float alpha, float beta, float* a, float* b, float* c);
void Calculate_SVPWM(float alpha, float beta, float Vdc,
float* Ta, float* Tb, float* Tc);
#endif
5.2 坐标变换实现
// CLARK_PARK.c
#include "CLARK_PARK.h"
#include "math.h"
// Clarke变换 (3/2变换)
Clarke_Components Clarke_Transform(float a, float b, float c)
{
Clarke_Components clarke;
// 等幅值变换
clarke.alpha = a;
clarke.beta = (a + 2.0f * b) * 0.5773502691896f; // 1/√3 ≈ 0.57735
return clarke;
}
// Park变换
Park_Components Park_Transform(float alpha, float beta,
float sin_theta, float cos_theta)
{
Park_Components park;
park.d = alpha * cos_theta + beta * sin_theta;
park.q = -alpha * sin_theta + beta * cos_theta;
return park;
}
// 逆Park变换
Clarke_Components Inverse_Park_Transform(float d, float q,
float sin_theta, float cos_theta)
{
Clarke_Components clarke;
clarke.alpha = d * cos_theta - q * sin_theta;
clarke.beta = d * sin_theta + q * cos_theta;
return clarke;
}
// 逆Clark变换 (2/3变换)
void Inverse_Clarke_Transform(float alpha, float beta,
float* a, float* b, float* c)
{
*a = alpha;
*b = -0.5f * alpha + 0.8660254037844f * beta; // √3/2 ≈ 0.86603
*c = -0.5f * alpha - 0.8660254037844f * beta;
}
六、PI控制器模块
6.1 PI控制器定义
// PI_Controller.h
#ifndef PI_CONTROLLER_H
#define PI_CONTROLLER_H
typedef struct {
float Kp; // 比例系数
float Ki; // 积分系数
float Ts; // 采样时间
float Limit_Upper; // 输出上限
float Limit_Lower; // 输出下限
float Integral; // 积分项
float Error_Prev; // 上次误差
float Output; // 控制器输出
} PI_Controller;
// 函数声明
void PI_Init(PI_Controller* pi, float kp, float ki, float ts,
float limit_upper, float limit_lower);
float PI_Update(PI_Controller* pi, float reference, float feedback);
void PI_Reset(PI_Controller* pi);
void PI_Set_Parameters(PI_Controller* pi, float kp, float ki);
#endif
6.2 PI控制器实现
// PI_Controller.c
#include "PI_Controller.h"
#include "math.h"
// PI控制器初始化
void PI_Init(PI_Controller* pi, float kp, float ki, float ts,
float limit_upper, float limit_lower)
{
pi->Kp = kp;
pi->Ki = ki;
pi->Ts = ts;
pi->Limit_Upper = limit_upper;
pi->Limit_Lower = limit_lower;
pi->Integral = 0.0f;
pi->Error_Prev = 0.0f;
pi->Output = 0.0f;
}
// PI控制器更新
float PI_Update(PI_Controller* pi, float reference, float feedback)
{
float error = reference - feedback;
float p_term, i_term;
// 比例项
p_term = pi->Kp * error;
// 积分项
pi->Integral += pi->Ki * pi->Ts * error;
// 积分限幅
if(pi->Integral > pi->Limit_Upper)
pi->Integral = pi->Limit_Upper;
else if(pi->Integral < pi->Limit_Lower)
pi->Integral = pi->Limit_Lower;
i_term = pi->Integral;
// 计算输出
pi->Output = p_term + i_term;
// 输出限幅
if(pi->Output > pi->Limit_Upper)
pi->Output = pi->Limit_Upper;
else if(pi->Output < pi->Limit_Lower)
pi->Output = pi->Limit_Lower;
// 保存当前误差
pi->Error_Prev = error;
return pi->Output;
}
// PI控制器重置
void PI_Reset(PI_Controller* pi)
{
pi->Integral = 0.0f;
pi->Error_Prev = 0.0f;
pi->Output = 0.0f;
}
// 设置PI参数
void PI_Set_Parameters(PI_Controller* pi, float kp, float ki)
{
pi->Kp = kp;
pi->Ki = ki;
}
七、SVPWM算法模块
7.1 SVPWM算法实现
// SVPWM.h
#ifndef SVPWM_H
#define SVPWM_H
#include "DSP2833x_Device.h"
// 扇区定义
typedef enum {
SECTOR_I = 1,
SECTOR_II = 2,
SECTOR_III = 3,
SECTOR_IV = 4,
SECTOR_V = 5,
SECTOR_VI = 6
} SVPWM_SECTOR;
// 函数声明
SVPWM_SECTOR SVPWM_GetSector(float alpha, float beta);
void SVPWM_CalculateTime(float alpha, float beta, float Vdc,
float* T1, float* T2, SVPWM_SECTOR sector);
void SVPWM_GeneratePWM(float T1, float T2, SVPWM_SECTOR sector,
float* Ta, float* Tb, float* Tc);
void Update_PWM_Duty(float Ta, float Tb, float Tc);
#endif
7.2 SVPWM算法实现
// SVPWM.c
#include "SVPWM.h"
#include "math.h"
#define SQRT3 1.7320508075688772f
#define ONE_BY_SQRT3 0.5773502691896257f
#define TWO_THIRDS 0.6666666666666666f
#define PWM_PERIOD 1500.0f // 对应10kHz PWM频率
// 判断扇区
SVPWM_SECTOR SVPWM_GetSector(float alpha, float beta)
{
float a, b, c;
Uint16 sector = 0;
// 计算判断条件
a = beta;
b = SQRT3/2.0f * alpha - 0.5f * beta;
c = -SQRT3/2.0f * alpha - 0.5f * beta;
if(a > 0.0f) sector |= 0x01;
if(b > 0.0f) sector |= 0x02;
if(c > 0.0f) sector |= 0x04;
switch(sector)
{
case 0x01: // 001
case 0x05: // 101
return SECTOR_I;
case 0x03: // 011
case 0x07: // 111
return SECTOR_II;
case 0x02: // 010
case 0x06: // 110
return SECTOR_III;
case 0x04: // 100
return SECTOR_IV;
case 0x0C: // 1100
return SECTOR_V;
case 0x08: // 1000
return SECTOR_VI;
default:
return SECTOR_I;
}
}
// 计算T1, T2
void SVPWM_CalculateTime(float alpha, float beta, float Vdc,
float* T1, float* T2, SVPWM_SECTOR sector)
{
float X, Y, Z;
float T = PWM_PERIOD; // PWM周期
// 计算中间变量
X = (SQRT3 * beta * T) / Vdc;
Y = (1.5f * alpha + SQRT3/2.0f * beta) * T / Vdc;
Z = (-1.5f * alpha + SQRT3/2.0f * beta) * T / Vdc;
switch(sector)
{
case SECTOR_I:
*T1 = -Z;
*T2 = X;
break;
case SECTOR_II:
*T1 = Z;
*T2 = Y;
break;
case SECTOR_III:
*T1 = X;
*T2 = -Y;
break;
case SECTOR_IV:
*T1 = -X;
*T2 = Z;
break;
case SECTOR_V:
*T1 = -Y;
*T2 = -Z;
break;
case SECTOR_VI:
*T1 = Y;
*T2 = -X;
break;
default:
*T1 = 0;
*T2 = 0;
break;
}
// 限制在0-T之间
if(*T1 < 0) *T1 = 0;
if(*T1 > T) *T1 = T;
if(*T2 < 0) *T2 = 0;
if(*T2 > T) *T2 = T;
}
// 生成三相占空比
void SVPWM_GeneratePWM(float T1, float T2, SVPWM_SECTOR sector,
float* Ta, float* Tb, float* Tc)
{
float T0, T7;
float T = PWM_PERIOD;
// 计算零矢量时间
T0 = (T - T1 - T2) / 2.0f;
T7 = T0;
switch(sector)
{
case SECTOR_I:
*Ta = T1 + T2 + T0;
*Tb = T2 + T0;
*Tc = T0;
break;
case SECTOR_II:
*Ta = T1 + T0;
*Tb = T1 + T2 + T0;
*Tc = T0;
break;
case SECTOR_III:
*Ta = T0;
*Tb = T1 + T2 + T0;
*Tc = T2 + T0;
break;
case SECTOR_IV:
*Ta = T0;
*Tb = T1 + T0;
*Tc = T1 + T2 + T0;
break;
case SECTOR_V:
*Ta = T2 + T0;
*Tb = T0;
*Tc = T1 + T2 + T0;
break;
case SECTOR_VI:
*Ta = T1 + T2 + T0;
*Tb = T0;
*Tc = T1 + T0;
break;
default:
*Ta = T/2;
*Tb = T/2;
*Tc = T/2;
break;
}
}
// 更新PWM占空比
void Update_PWM_Duty(float Ta, float Tb, float Tc)
{
// 设置比较值
EPwm1Regs.CMPA.half.CMPA = (Uint16)Ta; // A相
EPwm2Regs.CMPA.half.CMPA = (Uint16)Tb; // B相
EPwm3Regs.CMPA.half.CMPA = (Uint16)Tc; // C相
// 更新互补通道
EPwm1Regs.CMPB = PWM_PERIOD - (Uint16)Ta;
EPwm2Regs.CMPB = PWM_PERIOD - (Uint16)Tb;
EPwm3Regs.CMPB = PWM_PERIOD - (Uint16)Tc;
}
八、中断服务程序
8.1 定时器中断(控制周期)
// interrupt.h
#ifndef INTERRUPT_H
#define INTERRUPT_H
// 函数声明
interrupt void cpu_timer0_isr(void);
interrupt void adc_isr(void);
void InitInterrupt(void);
#endif
8.2 定时器中断实现
// interrupt.c
#include "DSP2833x_Device.h"
#include "SVPWM.h"
#include "ADC.h"
#include "CLARK_PARK.h"
#include "PI_Controller.h"
extern volatile struct SVPWM_System SYS;
extern PI_Controller DC_PI, Id_PI, Iq_PI;
// 定时器0中断 - 主控制循环
interrupt void cpu_timer0_isr(void)
{
static Uint16 control_counter = 0;
float Vd_ref, Vq_ref;
Clarke_Components clarke;
Park_Components park;
float Ta, Tb, Tc;
float T1, T2;
SVPWM_SECTOR sector;
// 每10个周期(100us * 10 = 1ms)执行一次控制
if(control_counter++ >= 10)
{
control_counter = 0;
// 1. 读取ADC采样值
ReadADCValues();
// 2. ADC原始值转换为实际值
SYS.Va = GetADCScaledValue(ADC_Result[0], 3.0f, 100.0f); // 电压传感器变比100:1
SYS.Vb = GetADCScaledValue(ADC_Result[1], 3.0f, 100.0f);
SYS.Vc = GetADCScaledValue(ADC_Result[2], 3.0f, 100.0f);
SYS.Ia = GetADCScaledValue(ADC_Result[3], 3.0f, 10.0f); // 电流传感器变比10:1
SYS.Ib = GetADCScaledValue(ADC_Result[4], 3.0f, 10.0f);
SYS.Ic = GetADCScaledValue(ADC_Result[5], 3.0f, 10.0f);
SYS.Vdc = GetADCScaledValue(ADC_Result[6], 3.0f, 200.0f); // 直流电压传感器变比200:1
// 3. Clark变换(三相电流到αβ坐标系)
clarke = Clarke_Transform(SYS.Ia, SYS.Ib, SYS.Ic);
// 4. 锁相环PLL更新角度
// 简化的PLL实现
float Va_alpha, Va_beta;
Clarke_Components voltage_clarke = Clarke_Transform(SYS.Va, SYS.Vb, SYS.Vc);
Va_alpha = voltage_clarke.alpha;
Va_beta = voltage_clarke.beta;
// 计算角度(通过反正切)
SYS.theta = atan2(Va_beta, Va_alpha);
// 角度归一化到0-2π
if(SYS.theta < 0) SYS.theta += 6.28318530718f; // 2π
// 计算三角函数值
SYS.sin_theta = sin(SYS.theta);
SYS.cos_theta = cos(SYS.theta);
// 5. Park变换(αβ到dq坐标系)
park = Park_Transform(clarke.alpha, clarke.beta,
SYS.sin_theta, SYS.cos_theta);
SYS.Id_fb = park.d;
SYS.Iq_fb = park.q;
// 6. PI控制
// 直流电压外环PI控制
SYS.Id_ref = PI_Update(&DC_PI, SYS.Vdc_ref, SYS.Vdc);
// 设置q轴电流参考为0(单位功率因数控制)
SYS.Iq_ref = 0.0f;
// d轴电流内环PI控制
Vd_ref = PI_Update(&Id_PI, SYS.Id_ref, SYS.Id_fb);
// q轴电流内环PI控制
Vq_ref = PI_Update(&Iq_PI, SYS.Iq_ref, SYS.Iq_fb);
// 7. 前馈解耦补偿
float w = 2.0f * 3.1415926f * SYS.frequency;
Vd_ref = Vd_ref - w * 0.1f * SYS.Iq_fb; // L为电感值
Vq_ref = Vq_ref + w * 0.1f * SYS.Id_fb;
// 8. 逆Park变换(dq到αβ坐标系)
clarke = Inverse_Park_Transform(Vd_ref, Vq_ref,
SYS.sin_theta, SYS.cos_theta);
SYS.Valpha = clarke.alpha;
SYS.Vbeta = clarke.beta;
// 9. SVPWM生成
sector = SVPWM_GetSector(SYS.Valpha, SYS.Vbeta);
SVPWM_CalculateTime(SYS.Valpha, SYS.Vbeta, SYS.Vdc, &T1, &T2, sector);
SVPWM_GeneratePWM(T1, T2, sector, &Ta, &Tb, &Tc);
// 10. 更新PWM占空比
Update_PWM_Duty(Ta, Tb, Tc);
}
// 清除中断标志
PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;
}
九、保护功能
9.1 过流、过压保护
// protection.c
#include "DSP2833x_Device.h"
#include "math.h"
// 故障标志
volatile struct {
Uint16 OverCurrent : 1;
Uint16 OverVoltage : 1;
Uint16 UnderVoltage : 1;
Uint16 OverTemperature : 1;
Uint16 DC_OverCurrent : 1;
Uint16 Reserved : 11;
} Fault_Flags;
// 保护阈值
#define OVER_CURRENT_THRESHOLD 20.0f // 20A
#define OVER_VOLTAGE_THRESHOLD 450.0f // 450V
#define UNDER_VOLTAGE_THRESHOLD 300.0f // 300V
#define TEMPERATURE_THRESHOLD 85.0f // 85°C
#define DC_OVER_CURRENT_THRESHOLD 30.0f // 30A
// 故障检测函数
void Check_Faults(float Ia, float Ib, float Ic,
float Vdc, float temperature)
{
float I_peak, I_dc_est;
// 计算相电流峰值
I_peak = fmaxf(fabs(Ia), fmaxf(fabs(Ib), fabs(Ic)));
// 估计直流电流
I_dc_est = sqrtf(Ia*Ia + Ib*Ib + Ic*Ic) * 0.8165f; // 近似计算
// 过流保护
if(I_peak > OVER_CURRENT_THRESHOLD)
{
Fault_Flags.OverCurrent = 1;
Trip_PWM();
}
// 直流侧过流
if(I_dc_est > DC_OVER_CURRENT_THRESHOLD)
{
Fault_Flags.DC_OverCurrent = 1;
Trip_PWM();
}
// 过压保护
if(Vdc > OVER_VOLTAGE_THRESHOLD)
{
Fault_Flags.OverVoltage = 1;
Trip_PWM();
}
// 欠压保护
if(Vdc < UNDER_VOLTAGE_THRESHOLD)
{
Fault_Flags.UnderVoltage = 1;
Trip_PWM();
}
// 过温保护
if(temperature > TEMPERATURE_THRESHOLD)
{
Fault_Flags.OverTemperature = 1;
Trip_PWM();
}
}
// 封锁PWM输出
void Trip_PWM(void)
{
// 设置PWM为高阻态或固定状态
EPwm1Regs.AQCTLA.bit.ZRO = AQ_CLEAR;
EPwm1Regs.AQCTLA.bit.CAU = AQ_CLEAR;
EPwm1Regs.AQCTLA.bit.CAD = AQ_CLEAR;
EPwm1Regs.AQCTLA.bit.PRD = AQ_CLEAR;
EPwm2Regs.AQCTLA.bit.ZRO = AQ_CLEAR;
EPwm2Regs.AQCTLA.bit.CAU = AQ_CLEAR;
EPwm2Regs.AQCTLA.bit.CAD = AQ_CLEAR;
EPwm2Regs.AQCTLA.bit.PRD = AQ_CLEAR;
EPwm3Regs.AQCTLA.bit.ZRO = AQ_CLEAR;
EPwm3Regs.AQCTLA.bit.CAU = AQ_CLEAR;
EPwm3Regs.AQCTLA.bit.CAD = AQ_CLEAR;
EPwm3Regs.AQCTLA.bit.PRD = AQ_CLEAR;
// 禁用PWM输出
EALLOW;
GpioCtrlRegs.GPAMUX1.bit.GPIO0 = 0; // 恢复为GPIO
GpioCtrlRegs.GPAMUX1.bit.GPIO1 = 0;
GpioCtrlRegs.GPAMUX1.bit.GPIO2 = 0;
GpioCtrlRegs.GPAMUX1.bit.GPIO3 = 0;
GpioCtrlRegs.GPAMUX1.bit.GPIO4 = 0;
GpioCtrlRegs.GPAMUX1.bit.GPIO5 = 0;
EDIS;
}
十、编译配置和头文件
10.1 DSP2833x_Device.h配置
// 必要的头文件包含
#include "DSP2833x_Adc.h"
#include "DSP2833x_CpuTimers.h"
#include "DSP2833x_EPwm.h"
#include "DSP2833x_Gpio.h"
#include "DSP2833x_PieCtrl.h"
#include "DSP2833x_PieVect.h"
#include "DSP2833x_SysCtrl.h"
10.2 链接命令文件
MEMORY
{
PAGE 0: /* Program Memory */
PAGE 1: /* Data Memory */
/* 实际根据DSP28335的内存映射配置 */
RAMH0 : origin = 0x3F8000, length = 0x002000
FLASHH : origin = 0x300000, length = 0x008000
}
SECTIONS
{
/* 代码段 */
.text : > FLASHH, PAGE = 0
/* 已初始化的全局和静态变量 */
.cinit : > FLASHH, PAGE = 0
.pinit : > FLASHH, PAGE = 0
/* 未初始化的变量 */
.bss : > RAMH0, PAGE = 1
.stack : > RAMH0, PAGE = 1
/* 中断向量表 */
.intvecs : > 0x3FFFC0, PAGE = 0
}
参考代码 三相交流,SVPWM整流,dsp28335程序实现 www.youwenfan.com/contentcnv/71782.html
十一、使用说明
11.1 系统参数配置
// 在main.c中配置系统参数
void Configure_System(void)
{
// 直流母线电压参考值
SYS.Vdc_ref = 400.0f; // 400V
// 电网频率
SYS.frequency = 50.0f; // 50Hz
// PI控制器参数
// 直流电压外环: 慢响应
PI_Init(&DC_PI, 0.5f, 0.01f, 0.001f, 10.0f, -10.0f);
// 电流内环: 快响应
PI_Init(&Id_PI, 0.8f, 0.1f, 0.0001f, 200.0f, -200.0f);
PI_Init(&Iq_PI, 0.8f, 0.1f, 0.0001f, 200.0f, -200.0f);
// PWM频率
PWM_FREQUENCY = 10000.0f; // 10kHz
// 采样电阻和传感器变比
CURRENT_SENSOR_GAIN = 10.0f; // 电流传感器变比
VOLTAGE_SENSOR_GAIN = 100.0f; // 电压传感器变比
}
11.2 调试接口
// 通过SCI发送调试信息
void Send_Debug_Info(void)
{
float data[6];
// 采集数据
data[0] = SYS.Va;
data[1] = SYS.Vb;
data[2] = SYS.Vc;
data[3] = SYS.Ia;
data[4] = SYS.Ib;
data[5] = SYS.Vdc;
// 通过SCI发送
for(int i = 0; i < 6; i++)
{
Send_Float_Data(data[i]);
}
}
十二、注意事项
-
硬件连接:
- 确保ADC输入电压不超过3V
- 正确配置电流和电压传感器的变比
- PWM输出需经过驱动电路隔离
-
软件调试:
- 先测试开环运行,确认PWM输出正常
- 然后测试电流采样和电压采样
- 逐步启用闭环控制
-
参数整定:
- 先整定电流内环PI参数
- 再整定电压外环PI参数
- 注意采样频率和控制频率的匹配
-
保护功能:
- 必须实现过流、过压保护
- 考虑软启动功能
- 添加故障记录和恢复机制

浙公网安备 33010602011771号