写一个电压电流双环控制的DSP程序
时间: 2023-10-01 21:09:10 浏览: 324
以下是一个电压电流双环控制的DSP程序的示例,供您参考:
```c
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "DSP2833x_Device.h"
#include "DSP2833x_Examples.h"
// 定义采样周期
#define Ts 0.0001
// 定义电压电流采样AD最大值
#define Vmax 4096
#define Imax 4096
// 定义PID参数
#define Kp_v 0.1
#define Ki_v 0.01
#define Kp_i 0.2
#define Ki_i 0.02
// 定义电压电流变量
int16 V, I;
// 定义PID控制变量
float error_v, error_i;
float integral_v, integral_i;
float output_v, output_i;
float setpoint_v, setpoint_i;
// 定义DAC输出变量
int16 DAC_v, DAC_i;
// 定义函数原型
void Init_ADC();
void Init_DAC();
void Init_PWM();
void Init_PID();
void ADC_ISR();
void PWM_ISR();
void main(void)
{
// 初始化系统
InitSysCtrl();
// 初始化ADC、DAC、PWM、PID等模块
Init_ADC();
Init_DAC();
Init_PWM();
Init_PID();
// 启用全局中断
EINT;
ERTM;
// 进入主循环
while(1)
{
// 获取电压电流采样值
V = AdcRegs.ADCRESULT0;
I = AdcRegs.ADCRESULT1;
// 计算电压电流PID控制量
error_v = setpoint_v - V;
integral_v += Ki_v * error_v * Ts;
output_v = Kp_v * error_v + integral_v;
if(output_v > 1.0) output_v = 1.0;
if(output_v < 0.0) output_v = 0.0;
error_i = setpoint_i - I;
integral_i += Ki_i * error_i * Ts;
output_i = Kp_i * error_i + integral_i;
if(output_i > 1.0) output_i = 1.0;
if(output_i < 0.0) output_i = 0.0;
// 输出DAC控制信号
DAC_v = output_v * Vmax;
DAC_i = output_i * Imax;
DacaRegs.DACVALS.all = DAC_v;
DacbRegs.DACVALS.all = DAC_i;
}
}
// 初始化ADC模块
void Init_ADC()
{
// 初始化ADC时钟
AdcRegs.ADCTRL2.bit.PRESCALE = 6;
AdcRegs.ADCTRL3.bit.ADCCLKPS = 5;
// 初始化ADC采样周期
AdcRegs.ADCCTL1.bit.ADCPWDN = 1;
AdcRegs.ADCCTL1.bit.ADCBGPWD = 1;
AdcRegs.ADCCTL1.bit.ADCREFPWD = 1;
AdcRegs.ADCCTL1.bit.ADCENABLE = 1;
AdcRegs.ADCCTL1.bit.ADCREFSEL = 0;
AdcRegs.ADCCTL1.bit.INTPULSEPOS = 1;
AdcRegs.ADCSOC0CTL.bit.TRIGSEL = 5;
AdcRegs.ADCSOC0CTL.bit.CHSEL = 0;
AdcRegs.ADCSOC0CTL.bit.ACQPS = 15;
AdcRegs.ADCSOC1CTL.bit.TRIGSEL = 5;
AdcRegs.ADCSOC1CTL.bit.CHSEL = 1;
AdcRegs.ADCSOC1CTL.bit.ACQPS = 15;
// 初始化ADC中断
PieCtrlRegs.PIEIER1.bit.INTx6 = 1;
IER |= M_INT1;
}
// 初始化DAC模块
void Init_DAC()
{
// 初始化DAC时钟
DacaRegs.DACCTL.bit.DACREFSEL = 0;
DacaRegs.DACCTL.bit.LOADMODE = 0;
DacaRegs.DACOUTEN.bit.DACOUTEN = 1;
DacbRegs.DACCTL.bit.DACREFSEL = 0;
DacbRegs.DACCTL.bit.LOADMODE = 0;
DacbRegs.DACOUTEN.bit.DACOUTEN = 1;
}
// 初始化PWM模块
void Init_PWM()
{
// 初始化PWM时钟
CpuSysRegs.PCLKCR2.bit.EPWM1ENCLK = 1;
EPwm1Regs.TBCTL.bit.CTRMODE = 2;
EPwm1Regs.TBPRD = 1500;
EPwm1Regs.TBCTL.bit.PHSEN = 1;
EPwm1Regs.TBPHS.half.TBPHS = 0;
EPwm1Regs.TBCTL.bit.SYNCOSEL = 3;
EPwm1Regs.CMPA.half.CMPA = 750;
EPwm1Regs.AQCTLA.bit.CAU = 1;
EPwm1Regs.AQCTLA.bit.CAD = 2;
EPwm1Regs.CMPB.half.CMPB = 750;
EPwm1Regs.AQCTLB.bit.CBU = 1;
EPwm1Regs.AQCTLB.bit.CBD = 2;
}
// 初始化PID模块
void Init_PID()
{
// 初始化PID变量
setpoint_v = 500;
setpoint_i = 200;
error_v = 0;
error_i = 0;
integral_v = 0;
integral_i = 0;
output_v = 0;
output_i = 0;
}
// ADC采样中断服务程序
interrupt void ADC_ISR()
{
AdcRegs.ADCINTFLGCLR.bit.ADCINT1 = 1;
}
// PWM中断服务程序
interrupt void PWM_ISR()
{
PieCtrlRegs.PIEACK.all = PIEACK_GROUP3;
}
```
以上是一个简单的电压电流双环控制的DSP程序示例,具体实现方式可能因硬件平台和控制算法不同而有所差异。程序的基本思路是通过ADC采集电压电流值,经过PID控制计算后输出控制信号到DAC模块,通过PWM模块控制电压电流输出到负载。需要注意的是,程序中的PID参数需要根据实际应用场景进行调整,以达到最佳的控制效果。
阅读全文