📄 dc_control.c
字号:
#include "DSP281x_Device.h" // DSP281x Headerfile Include File
#include "DSP281x_Examples.h" // DSP281x Examples Include File
#include "DSP281x_Gpio.h"
#include "math.h"
#include "DSP281x_GlobalPrototypes.h"
interrupt void adc_isr(void); //ADC中断函数
//void delay(int16 z);
volatile int16 i=0;
int16 voltage[5]={0,0,0,0,0},current[5]={0,0,0,0,0}, givevoltage[5]={0,0,0,0,0};
volatile int16 ave_givevoltage=0,ave_current=0,ave_voltage=0;
volatile int16 temp1=0,temp2=0,error_v=0,error_c=0,con1=0,con2=0;
volatile float gdv=0,sjv=0,sjc=0;
#define lev 1707 //1707~1.25V
#define led *(int *)0xC0000
#define D 0.00293
volatile Uint16 loopcount=0,Duty_cycle=0;
volatile int16 flag=0,N=5;
volatile int16 ref_current=40,error_c_ago=0,error_v_ago=0;
volatile int16 I_c=0,I_v=0,vol_cnt=0;
volatile float Vkp=2,Vki=1,Vkd=0,Ikp=1,Iki=0.1,Ikd=0;
volatile float P_v=0,D_v=0,PID_v=0;
volatile float P_c=0,D_c=0,PID_c=0;
void setad()
{
EALLOW;
AdcRegs.ADCMAXCONV.all = 0x0002; // Setup 2 conv's on SEQ1
AdcRegs.ADCCHSELSEQ1.all= 0x3210; // Setup ADCINA3 as 1st SEQ1 conv.
// AdcRegs.ADCCHSELSEQ2.all= 0x7654;
// AdcRegs.ADCCHSELSEQ1.bit.CONV01 = 0x2; // Setup ADCINA2 as 2nd SEQ1 conv.
AdcRegs.ADCTRL2.bit.EVA_SOC_SEQ1 = 1; // Enable EVASOC to start SEQ1
AdcRegs.ADCTRL2.bit.INT_ENA_SEQ1 = 1; // Enable SEQ1 interrupt (every EOS)
// EvaRegs.T1CMPR = 0x0080; // Setup T1 compare value
AdcRegs.ADCTRL1.bit.ACQ_PS = 0x06; //采样窗长度
AdcRegs.ADCTRL1.bit.CPS = 1; //45M adc core timer equal HSPCLK/2 (SYSCLK)
AdcRegs.ADCTRL3.bit.ADCCLKPS = 0x3; //00//adc core clock=15M ????
EvaRegs.GPTCONA.bit.T1TOADC = 0x2; //1// Enable EVASOC in EVA
EvaRegs.T1CON.bit.TMODE = 0x02;
EvaRegs.T1CON.bit.TPS = 0x02; //0//timer CLK(15M) = HSPCLK=SYSCLK(90M)/6
EvaRegs.T1CON.bit.TENABLE = 1;
EvaRegs.T1CON.bit.TCLKS10 = 0x0;//选择内部时钟(如HSPCLK)
EvaRegs.T1PR =9000; //6000/ (4E1) T = Txpr+1 20KHz 0.05ms SYSCLK=120MHz
EvaRegs.T1CNT = 0x0000; // 2FE 32.55KHz 9C3~10KHz 341~30K
EDIS;
}
void InitEva()
{
EALLOW;
EvaRegs.T1PR = 9000; //9000 T = Txpr+1 10KHz 0.1ms SYSCLK=90MHz
EvaRegs.T1CNT = 0x0000; // 定时器1清零
EvaRegs.ACTRA.all=0x00FD; //pwm1低有效 pwm2~3强制高 pwm4强制高
EvaRegs.DBTCONA.all=0X0000; //禁止使用死区
EvaRegs.CMPR1=4500; //初始化占空比50%
EvaRegs.COMCONA.all=0X0A400;//使能比较操作 T1CNT=0或T1PR时CMPR重载,禁止SVPWM,T1CNT=0
EvaRegs.GPTCONA.bit.T1TOADC = 0x2; //设置周期中断标志启动ADC 通用定时器1启动ADC
EvaRegs.T1CON.bit.TMODE = 0x02; //连续增计数
EvaRegs.T1CON.bit.TPS = 0x00; //0//timer CLK(15M) = HSPCLK
EvaRegs.T1CON.bit.TENABLE = 0; //不使能定时器1
EvaRegs.T1CON.bit.TCLKS10 = 0x0; //使用内部时钟 //或T1PR时ACTR重载,先令PWM输出为高阻抗,待初始化完毕后,再令FCOMPOE=1启动PWM
//EvaRegs.T1CON.bit.TECMPR = 0x1; //使能定时器比较操作
EDIS;
}
int filter_givevoltage()
{
int count,a,b,temp,M;
int sum=0;
for (b=0;b<N;b++) //从大往小找数
{
for (a=0;a<N-1-b;a++) //比较相邻数的大小,只能找到几个数中的最大值,不能找到最小值,最小值通过第1个循环来找
{
if ( givevoltage[a]>givevoltage[a+1] )
{
temp=givevoltage[a];
givevoltage[a]=givevoltage[a+1];
givevoltage[a+1]=temp;
}
}
}
for(count=1;count<N-1;count++)
{sum+=givevoltage[count];}
M=N-2;
return (int)(sum/M);
}
int filter_current()
{
int count,a,b,temp,M;
int sum=0;
for (b=0; b<N; b++) //从大往小找数
{
for (a=0; a<N-1-b; a++) //比较相邻数的大小,只能找到几个数中的最大值,不能找到最小值,最小值通过第1个循环来找
{
if ( current[a]>current[a+1] )
{
temp=current[a]; //temp还需要定义吗?
current[a]=current[a+1];
current[a+1]=temp;
}
}
}
for(count=1; count<N-1; count++)
{ sum+=current[count];}
M=N-2;
return (int)(sum/M);
}
int filter_voltage()
{
int count,a,b,temp,M;
int sum=0;
for (b=0;b<N;b++) //从大往小找数
{
for (a=0;a<N-1-b;a++) //比较相邻数的大小,只能找到几个数中的最大值,不能找到最小值,最小值通过第1个循环来找
{
if ( voltage[a]>voltage[a+1] )
{
temp=voltage[a];
voltage[a]=voltage[a+1];
voltage[a+1]=temp;
}
}
}
for(count=1;count<N-1;count++)
{sum+=voltage[count];}
M=N-2;
return (int)(sum/M);
}
int current_PID()
{
error_c=ref_current-ave_current;
P_c=Ikp*error_c;
if(error_c<80)
{
I_c=I_c+Iki*error_c; //I_c为全局变?
}
D_c=Ikd*(error_c-error_c_ago); //error_c_ago是全局变量
error_c_ago=error_c;
PID_c=P_c+I_c+D_c;
con1=ceil(PID_c);//ceil函数的作用是求不小于给定实数的最小整数
if(con1<0)
{
temp1=-con1;
}
else temp1=con1;
if(temp1>9000) //limt是限幅值,可以赋给它周期寄存器的值
{
temp1=9000;
}
return (int)(temp1);
}
int voltage_PID()
{
error_v=ave_givevoltage-ave_voltage;
P_v=Vkp*error_v;
if(error_v<80)
{
I_v=I_v+Iki*error_v;
} // I为全局变量
D_v=Vkd*(error_v-error_v_ago); // error_old还没设置,应该是全局变量
error_v_ago=error_v;
PID_v=P_v+I_v+D_v;
con2=ceil(PID_v); //answer = ceil(3.1415); answer = 4.0 answer = ceil(-3.5); answer = -3.0
if(con2<0)
{
temp2=-con2;
}
else temp2=con2;
if(temp2>2000) //13A
{
temp2=2000;
}
return (int)(temp2);
}
interrupt void adc_isr(void)
{
loopcount++;
//GpioDataRegs.GPBDAT.all=0x0000;
asm(" clrc SXM"); // 抑制符号位扩展
current[i]=(AdcRegs.ADCRESULT0 >>4)-lev; // 电流结果
givevoltage[i]=(AdcRegs.ADCRESULT1 >>4)-lev;
voltage[i]=(AdcRegs.ADCRESULT2 >>4)-lev;
i++;
if(i==5)
{ flag=1; // flag是全局变量
i=0;
}
if(flag==1)
{
ave_current=filter_current();
flag=0;//对电流标志位清零
Duty_cycle=current_PID();
vol_cnt++;
gdv=ave_givevoltage*D;
sjv=ave_voltage*D;
sjc=ave_current*D;
if(vol_cnt==50)
{
ave_givevoltage=filter_givevoltage();
ave_voltage=filter_voltage();
ref_current=voltage_PID();
vol_cnt=0;
}
}
//Duty_cycle=4500;
EvaRegs.CMPR1=Duty_cycle;
//*ADCTRL2=*ADCTRL2|0X4200;
AdcRegs.ADCTRL2.bit.RST_SEQ1 = 1; // Reset SEQ1复位排序器,使SEQ1指向CONV00
AdcRegs.ADCST.bit.INT_SEQ1_CLR = 1; // Clear INT SEQ1 bit清中断标志位(写1清0)
PieCtrlRegs.PIEACK.all = PIEACK_GROUP1; // Acknowledge interrupt to PIE清PIEACK位,ADC中断属于INT1 响应中断
EvaRegs.T1CNT = 0x0000;
EvaRegs.EVAIFRA.all=0xffff;
asm(" CLRC INTM");
return;
}
void main()
{
asm(" SETC OBJMODE");
InitSysCtrl();//调用系统初始化函数
EALLOW; //高速外围时钟定标寄存器设置
SysCtrlRegs.HISPCP.all = 0x0; //为0时HSPCLK=SYSCLKOUT
EDIS;
DINT;//关总中断
InitGpio(); //port A -out port B -in GPIO口的初始化
InitPieCtrl();//外设中断扩展初始化
IER = 0x0000;
IFR = 0x0000;
MemCopy(&RamfuncsLoadStart, &RamfuncsLoadEnd, &RamfuncsRunStart);
InitFlash();//初始化Flash寄存器
InitPieVectTable();//初始化中断向量表
EALLOW; // This is needed to write to EALLOW protected register
PieVectTable.ADCINT = &adc_isr;//赋中断地址
EDIS; // This is needed to disable write to EALLOW protected registers
InitAdc(); // For this example, init the ADC 初始化ADC
setad();
InitEva();
PieCtrlRegs.PIEIER1.bit.INTx6 = 1;//使能位于PIE中的组1的第6个中断TINT0
IER |= M_INT1; // Enable CPU Interrupt 1 ADC处在INT1 使能全局中断INT1
EINT; // Enable Global interrupt INTM 使能全局中断INTM
ERTM; // Enable Global realtime interrupt DBGM 使能全局实时中断DBGM
EALLOW;
EvaRegs.T1CON.bit.TENABLE = 1; //使能定时器1
EvaRegs.COMCONA.all|=0x02E7;
EDIS;
//GpioDataRegs.GPBDAT.all=0xFFFF;
// delay(30000);
Duty_cycle=0;
for(;;)
{
led=0x000F;
//loopcount=0;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -