📄 energy_back_main.c
字号:
Uint16 DetTemperD=10;
///////void DetDefault(void)///////////
Uint16 DetDefPeriod=0;
Uint32 ErrorState=0; //错误状态寄存器:默认错误
Uint16 StateIsError=1; //错误标志:默认错误
///////Uint16 DelayTime600(void) ///////// //600ms
Uint16 DelayT600=0;
///////void SwitchMachDeal(void)////////
Uint16 SwtMachDPeriod=0;
///////void TemperProtect(void)///////
int16 Temperature;
int16 TemperArray[109]={3136, 3100 , 3068 , 3028 , 2988 , 2952 , 2912 , 2868, 2828 , 2784 , 2740 , 2696 , 2648 , 2600 , 2556 , 2508, 2464 , 2416 , 2372 , 2324 , 2276 , 2232 , 2184 , 2140, 2092 , 2048 , 2004 , 1960 , 1916 , 1876 , 1836 , 1792, 1752 , 1708 , 1664 , 1624 , 1580 , 1540 , 1500 , 1456 , 1416 , 1376 , 1340 , 1304 , 1272 , 1240 , 1208 , 1176 , 1144 , 1112 , 1080, 1052 , 1024 , 992 , 964 , 936 , 912 , 884 , 860 , 836 , 812 , 788 , 764 , 744 , 720 , 700 , 676 , 656 , 636 , 616 , 600 , 580 , 564 , 548 , 532 , 516 , 504 , 492 , 476 , 464 , 452 , 440 , 428 , 416 , 404 , 396 , 384 , 372 , 360 , 352 , 340 , 332 , 320 , 308 , 296 , 284 , 272 , 264 , 252 , 240 , 228 , 216 , 204 , 192 , 180 , 168 , 156 , 144 , 132};
//Led_0--Led_9
Uint16 LedNumZToN[10]={0x00c0,0x00f9,0x00a4,0x00b0,0x0099,0x0092,0x0082,0x00f8,0x0080,0x0090};
int16 SinCounter=0;
main()
{
//一、 system initialize: pll clock:100M;hispcp=1 100m/2; lospcp=2 100m/4;periferals clock enabled
InitSysCtrl();
//二、initialize GPIO:set the GPIO to it's default state: 普通GPIO状态,均为输入,输入采样方式为第一种,均为上拉使能.
//epwm disable pull up
InitGpio();
//用户自定义IO初始化: gpio24 27 20 21 22 23 16 17 34
InitLogicIO();
//EPwm初始化
InitEPwm1Gpio();
InitEPwm2Gpio();
InitEPwm3Gpio();
InitEPwm4Gpio();
InitEPwm5Gpio();
InitEPwm6Gpio();
//三、initialize interrupts:disable cpu interrupt; disabel all pie interrupts and clear all pie interrupt flags
DINT;
InitPieCtrl();
IER=0x0000;
IFR=0x0000;
//initialize Pie interrupts and enable pie
InitPieVectTable();
//用户自定义的中断初始化
EALLOW;
PieVectTable.TINT0 = &cpu_timer0_isr; //Cpu timer0 interrupt
PieVectTable.EPWM1_INT=&ISREPwm1_Zero; //EPwm1的计数器下溢中断
EDIS;
//四、initialize peripherials and setup peripherials
//CPU timer0 initialize
InitCpuTimers();
// Configure CPU-Timer 0 to interrupt every msecond:
// 100MHz CPU Freq, 3m second Period (in uSeconds)
ConfigCpuTimer(&CpuTimer0, 100, 3000);
StartCpuTimer0();
//ADC initialize
InitAdc();
//ADC setup
SetupAdc();
//Epwm Setup
SetupEPwm(); //pwm开始产生,初始化为上下桥臂一高一低
//关闭所有epwm ,LE控制
GpioDataRegs.GPASET.bit.GPIO12=1;
GpioDataRegs.GPASET.bit.GPIO13=1;
// CloseEPwmSignal();
IsDCOpenEPwm=0;
IsInvOpenEPwm=0;
//五、User specific code, enable interrupts:
//test
//开用到的中断
EnableInterrupts(); //EPWM1 int3.1中断
// Enable global Interrupts and higher priority real-time debug events:
// EINT; // Enable Global interrupt INTM
// ERTM; // Enable Global realtime interrupt DBGM
//User specific code
//////add
//////MemCopy(&RamfuncsLoadStart, &RamfuncsLoadEnd, &RamfuncsRunStart);
// Call Flash Initialization to setup flash waitstates
// This function must reside in RAM
InitFlash();
//////add
//初始化电压环的PID
//A相
// IncPIDInit(&VolALoopPID);
// PIDParaF2F(&VolALoopPID,VolALoop_P,VolALoop_I,VolALoop_D); //PID参数定标Q11
// IncPIDTempVar(&VolALoopPID); //算出a0a1a2
//初始化电流环的PID
//A相
// IncPIDInit(&CurrALoopPID);
// PIDParaF2F(&CurrALoopPID,CurrALoop_P,CurrALoop_I,CurrALoop_D);
// IncPIDTempVar(&CurrALoopPID);
// ReadEEPRom(0x0a, EEPROMNUMBER); //只读电表的度数3byte
ADSampIniFlag=0; //上电需要初始化交流电流霍尔的中点,启动initsampoffset()
// 六. 主循环IDLE loop. Just sit and loop forever (optional):
for(;;)
{
//3ms周期
if(Period3ms==1) //3ms
{
Period3ms=0; //flag clear
}
asm(" NOP");
}
}
//cpu timer0 interrupt: 3ms period
interrupt void cpu_timer0_isr(void)
{
Period3ms=1; //flag: 1ms
// Acknowledge this interrupt to receive more interrupts from group 1
PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;
}
//载波下溢中断,作为50us(20Hz)时间片
interrupt void ISREPwm1_Zero(void)
{
int32 ControlAValue; //控制算法返回的A相控制量
int32 ControlBValue;
//锁相用标志
int16 SampleAZero; //采样电压是否过零标志
int16 SampleBZero;
int16 SampleCZero;
int16 RefAZero; //参考电压是否过零点标志
int16 RefBZero;
int16 RefCZero;
/* 需要初始化或者是因为变量里的值在本次退出子程序后需要保存,以便下一次使用,因此定义为全局变量了
//锁相用标志
int16 LockAIsFirst=0; //ABC三相是否找到第一个零点标志
int16 LockBIsFirst=0;
int16 LockCIsFirst=0;
//ABC三相正弦波基准发生标志,1为开始产生正弦波基准,其实也是锁相完毕的标志
int16 ASinStart=0;
int16 BSinStart=0;
int16 CSinStart=0;
//锁相用变量
int16 AFreNumTemp; // 临时寄存的上一次实际采样周期值
int16 BFreNumTemp;
int16 CFreNumTemp;
int16 PeriodAError; //实际和基准的周期差,即上一次和本次的周期差
int16 PeriodBError;
int16 PeriodCError;
int16 AModeFlag; //工作模式变量.0为参考电压,采样电压递增模式.1为参考电压和采样电压同时到达零点时模式2为采样电压比参考电压先到达模式:持续时间为采样零点和参考零点之间3为参考电压比采样电压先到达模式,持续时间为参考零点和采样零点之间
int16 BModeFlag;
int16 CModeFlag;
*/
//-------------------------------------------------------------------------------
//50ms定时
// Period50ms();
//-------------------------------------------------------------------------------
//在三角波的最低点,即下溢时,自动启动一次adc,并且进入该下溢中断
//查询方式adc,修改参数:VolAArray(直流母线电压)
//CurrAArray(逆变器输出线电流)
//VolLockA(电网电压)
//PowerAIns(输出瞬时功率)
Adc_Inquire();
//---------------------------------------------------------------------------------
//产生正弦波参考
if(SinCounter==400)
{
SinCounter=0;
}
else
{
ASinRef=SinProduce(400,SinCounter); //-1-1 //Q15
SinCounter++;
}
//dcac 控制
//逆变器反馈控制
ControlAValue=(int32)ASinRef*1000;
ControlAValue=ControlAValue>>15;
// ControlAValue=ACControlArith(ASinRef,VolLockA,CurrAArray);
//DCAC驱动,产生占空比
EPwmU_Driver(ControlAValue);
EPwmV_Driver(ControlAValue);
//-------------------------------------------------------------------------------
//中断退出处理
EPwm1Regs.ETCLR.bit.INT=1; //手动清零
PieCtrlRegs.PIEACK.all=PIEACK_GROUP3;
}
//控制算法:返回int32控制量 现在改为int16了因为pid计算成为int16了
int32 ControlArith(int16 Vref,int16 Iref,int16 Vsample,int16 Isample)
{
int16 PID_rIn;
int32 PID_rOut;
int32 CurrTempRef;
int16 CurrFactRef; //电流环参考输入
IncPID *VolLoopPID;
IncPID *CurrLoopPID;
VolLoopPID=&VolALoopPID;
CurrLoopPID=&CurrALoopPID;
//电压环PID
VolLoopPID->RefPoint=Vref; // Set PID Refpoint //ADC定标
PID_rIn=Vsample; //1.5v offset //ADC定标
PID_rOut=VolIncPIDCalc(VolLoopPID,PID_rIn); //返回int32 ADC 定标int16的范围
PID_rOut=0-PID_rOut; //正为逆变
/*
AError=Vref-Vsample; //当前偏差
ASumError=ASumError+AError; // 当前积分
if(ASumError>=125000)//2147418112)
ASumError=125000;//2147418112;
else if (ASumError<=-5000000)
ASumError=-5000000;
PID_rOut=ASumError*0.001;//AError*1+ASumError*0.001;
if(PID_rOut>125)
PID_rOut=125;
else if(PID_rOut<-5000)//-3600
PID_rOut=-5000;//-7372800;
*/
//tiaoshi
// ybyb1=PID_rIn;//CurrFactRef;
// ybyb2=PID_rOut;
// ControlCValue=PID_rOut>>2; //DA
//yybb
// PID_rOut=-200;//-340;//120;
//yybb
// if(PID_rOut<=0)
// {
// PID_rOut=0; //此输出限幅
// }
//yybb
if(CurrRefFlag==1) //每个工频周期更新一次
{
CurrRefConst=PID_rOut;
CurrRefFlag=0;
}
// CurrRefConst=100;
//计算电流环的参考输入
CurrTempRef=CurrRefConst*Iref; //currtempref是int32不会溢出
//PID_rOut是int32 ADC 定标但范围是int16而Iref是Q15定标。 电流给定是以0对称的(因为作乘法,如果提前以一个确定值作对称,则对称值也改变了)
//CurrTempRef是int32 ADC*Q15定标
CurrTempRef=CurrTempRef>>15; //CurrTempRef是int32 转化为ADC定标int16的范围,对应24v
/*
// 实际上CurrTempRef肯定是int16的值
//PID模块的输入是int16,做截取 int16的范围是-32768--32767
if (CurrTempRef>32767)
CurrFactRef=32767; //超出,取最大
else if(CurrTempRef<-32768) //取最小
CurrFactRef=-32768;
else
CurrFactRef=(int16)CurrTempRef; //最大最小未超出,强制类型转换
*/
// ControlCValue=CurrFactRef; //DA
//yybb
//设定电流环的溢出饱和值,原来int16对应24v,现在为3v
// CurrFactRef=CurrFactRef>>3; //即溢出为4096
//yybb
// ybyb2=CurrFactRef;
//if(CurEqualZero==1) //关机时设定电流环的输入为0
//{
//CurrFactRef=0;
//}
//电流环PID
//This compensation unit is not used.
// KKKK=(float32)Vref/Vsample; //暂时没有用
CurrLoopPID->RefPoint=(int16)CurrTempRef; //int16 ADC定标 ,正弦以0对称
PID_rIn=Isample; //ADC采样,减去一个采样偏置(1.5v)则得到以0对称的采样
PID_rOut=CurIncPIDCalc(CurrLoopPID,PID_rIn); //返回int32 ADC 定标 正弦以0对称,值限定在了int16
/*
GridTemp=(float32)VolLockA*0.776;
GridCorrect=0-GridTemp;
PID_rOut=PID_rOut+GridCorrect;
*/
ybyb1=CurrLoopPID->RefPoint;//CurrFactRef;
ybyb2=PID_rIn;
if(PID_rOut>=1250)
PID_rOut=1250;
else if(PID_rOut<=-1250)
PID_rOut=-1249;
//此时饱和值设在int16 2n15=32768,三角波1250,实际上>1250就饱和了
// PID_rOut=PID_rOut>>4;
//???????算出ADC定标,如果假设pwm峰值为7.5v,则7.5v对应1250,而adc定标为3v对应4096
//其中差了8.192倍,所以结果再右移3位即可????
// PID_rOut=PID_rOut>>3; //转化为7.5v峰值的pwm定标
/*
if(SwitchABC==1) //A相
{
ybyb2=CurrFactRef-Isample;
ybyb1=PID_rOut;
// ybyb2=PID_rIn;
// ybyb2=PID_rOut;
}
*/
return PID_rOut;
}
//EPwm驱动:由控制量得到PWM占空比
void EPwmU_Driver(int32 CV)
{
int16 EPwm1Offset; //控制量是一个0对称的正弦,需要一个和pwm配合的偏置(实际上是三角波由计数器表示时,则相当于从0对称变成有偏置了)
int16 ControlVal; //转变为int16的控制量
int16 PlusWidth; //占空比
EPwm1Offset=EPWM_PERIOD>>1; // /2
//控制量转变
if(CV>EPwm1Offset)
ControlVal=EPwm1Offset; //占空比100%
else if(CV<(0-EPwm1Offset))
ControlVal=0-EPwm1Offset; //占空比0%
else
ControlVal=(int16)CV;
// ybyb1=ControlVal;
//得到占空比
PlusWidth=EPwm1Offset+ControlVal;
//驱动EPwm4
EPwm1Regs.CMPA.half.CMPA=PlusWidth;
}
void EPwmV_Driver(int32 CV)
{
int16 EPwm2Offset; //控制量是一个0对称的正弦,需要一个和pwm配合的偏置(实际上是三角波由计数器表示时,则相当于从0对称变成有偏置了)
int16 ControlVal; //转变为int16的控制量
int16 PlusWidth; //占空比
EPwm2Offset=EPWM_PERIOD>>1; // /2
//控制量转变
if(CV>EPwm2Offset)
ControlVal=EPwm2Offset; //占空比100%
else if(CV<(0-EPwm2Offset))
ControlVal=0-EPwm2Offset; //占空比0%
else
ControlVal=(int16)CV;
//得到占空比
PlusWidth=EPwm2Offset+ControlVal;
//驱动EPwm1
EPwm2Regs.CMPA.half.CMPA=PlusWidth;
}
void EPwmW_Driver(int32 CV)
{
int16 EPwm3Offset; //控制量是一个0对称的正弦,需要一个和pwm配合的偏置(实际上是三角波由计数器表示时,则相当于从0对称变成有偏置了)
int16 ControlVal; //转变为int16的控制量
int16 PlusWidth; //占空比
EPwm3Offset=EPWM_PERIOD>>1; // /2
//控制量转变
if(CV>EPwm3Offset)
ControlVal=EPwm3Offset; //占空比100%
else if(CV<(0-EPwm3Offset))
ControlVal=0-EPwm3Offset; //占空比0%
else
ControlVal=(int16)CV;
//得到占空比
PlusWidth=EPwm3Offset+ControlVal;
//驱动EPwm1
EPwm6Regs.CMPA.half.CMPA=PlusWidth;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -