DSP代码学习记录

具体是项目工程代码。

(Var)=((Var)>=(Max))?(Max):(Var)//意思是if var>=max,则var+max,否则,var=var

k |= SW1_VALUE//位或,意思是把k的值和SW1_VALUE位按位或后,然后再赋值给SW1_VALUE。

if (ShadowScanState.bit.ScanFlag)是什么意思?shadowcanstate是阴影面积扫描吗

计算Id_reference的时候,首先是计算f32VboostErr,然后对gain进行限定,然后通过BusCon_Reg.f32BusErr_New = f32VboostGain * f32VboostErr计算出Bus_error;然后计算出Bus_ Err_new,就算这个是为了得到BusIL-ref,如果说放电状态,则把BusIL-ref赋值给IL_Peak_ref,这个在以后计算currentPID的时候会用到;

  • 关于平均值和有效值的计算:
    有效值:
AD_Acc.f32RmsGFCI += ADValue.f32GFCI   * ADValue.f32GFCI;
AD_Sum.f32RmsGFCI = AD_Acc.f32RmsGFCI;
RealValue.f32RmsGFCI = sqrt(AD_Sum.f32RmsGFCI   * f32rcnt);

通过上面的三次转换就知道rms值是怎么计算得到的了。其他的都一样;
平均值:
平均值的计算就比较简单了;

AD_Acc.f32GFCI += ADValue.f32GFCI;
AD_Sum.f32GFCI     = AD_Acc.f32GFCI;
RealValue.f32GFCI = (AD_Sum.f32GFCI * f32rcnt);

CAN通信,data unpack部分。

if(data0==0X7E)		//	判断标志位==7E;
	{	
		for(index=1;index<5;index++)   // 提取data1、2、3/4
		{
			switch(index)
			{
				case 1:
                    ucRXMsgData[index] = CanaRegs.CAN_IF2DATA.bit.Data_1;
                break;
                case 2:
                    ucRXMsgData[index] = CanaRegs.CAN_IF2DATA.bit.Data_2;
                break;
                case 3:
                    ucRXMsgData[index] = CanaRegs.CAN_IF2DATA.bit.Data_3;
                break;
                case 4:
                    ucRXMsgData[index] = CanaRegs.CAN_IF2DATB.bit.Data_4;
                break;
			}
		}
		//dataunpack;
		result+=ucRXMsgData[1];
		result+=(ucRXMsgData[2]<<8);
		result+=(ucRXMsgData[3]<<16);
		result+=(ucRXMsgData[4]<<24);		
	}

记录一下数据流(CAN通信发电量)

  g_i32ExternalPvPower = getCANMessage(CAN_RX_MSG_OBJ);
            g_i32ExternalPvPower = g_i32ExternalPvPower*0.1;        //单位转换成W;
            if(g_i32ExternalPvPower<0)
            {
                g_i32ExternalPvPower = -g_i32ExternalPvPower;         
 //              flag=0;
            }

这里是提取can发来的数据,并且存在 g_i32ExternalPvPower这个变量里。

 g_u16SpiTxBuf[18] = (int16)g_i32ExternalPvPower;

我们的主DSP和副DSP是通过SPI通信的。这里讲 g_i32ExternalPvPower传到Buff[18]。

并且在PMU里也会用到:

if (/*fabs(RealValue.f32BatChgDischgPower) < 50.0*/
				(!(g_MPPTState.bit.PV1ON || g_MPPTState.bit.PV2ON)&&(g_i32ExternalPvPower<45))
				&& ( (RealValue.f32PowerAC - (RealValue.f32PowerUtility/*-f32PCCPowerSet*/)) < 40)
				&& (fabs(f32PCCPowerSet) < 0.1f))

这里是如果PV1 on或者PV2 on或者接了外置PV逆变器的情况下,电池都不会出现standby的情况;
注意这里小于45,这个45是随便取的一个很小的值,意思是只要外置PV功率小于45W我们都认为没有外接PV,因为正常情况下,这个外置的PV会大于这个值。

接下来是副DSP里的处理。

M_CalcResultRms.i16ExternalPvPower = g_SpiRxBuf[18];

副DSP接收数据。

i16temp_1 =  ADCalc_EnergyPow.i16PowerAC - ADCalc_EnergyPow.i16GridPower + M_CalcResultRms.i16ExternalPvPower;	//能量守恒
	if(i16temp_1 < 0)		//默认负载不放电,只耗电
	{
		i16temp_1 = 0;
	}
	ADCalc_EnergyPow.i16LoadPower = i16temp_1;

这里是计算显示屏上面的负载的功率,计算方式是PowerAC - GridPower + i16ExternalPvPower。

然后,

ADCalc_EnergyPow.i16PVGenPower = M_CalcResultRms.i16Input1Watt + M_CalcResultRms.i16Input2Watt
                                                                                  + M_CalcResultRms.i16ExternalPvPower  ;

这里是计算显示屏上面PV发电量,PV发电量为内接PV和外置PV发电量之和。

最后是监控板上面的逻辑:

#if 1
       if(rtdb.i16PVGenPower <= (rtdb.PV1Power+rtdb.PV2Power))
       {
        
   
        	// 防止AC采样误差造成负载计算成负的
        	// 假设了负载不会输出功率 且 电网功率是准确的
        	if (Inverter_Information.i16PowerAC < Inverter_Information.Outputactivepower)
        	{
        		Inverter_Information.i16PowerAC = Inverter_Information.Outputactivepower;
        	}
        	// PV 等于 Inv
        	if (1 != inputInvState.bit.Bat && 2 != inputInvState.bit.Bat
        		&& inputInvState.bit.PVReady)
        	{
        		Inverter_Information.i16PVGenPower = Inverter_Information.i16PowerAC;
        		if (Inverter_Information.i16PVGenPower < 0)
        		{
        			Inverter_Information.i16PVGenPower = 0;
        		}
        	}
        	// Bat 等于 Inv
        	else if (0 == inputInvState.bit.PVReady
        		&& (1 == inputInvState.bit.Bat || 2 == inputInvState.bit.Bat))
        	{
        		Inverter_Information.i16BatPower = -Inverter_Information.i16PowerAC;
        	}
        	// 全部工作
        	else if (1 == inputInvState.bit.PVReady
        		&& (1 == inputInvState.bit.Bat || 2 == inputInvState.bit.Bat))
        	{
        		i32Ptmp = Inverter_Information.i16PVGenPower;
        		Inverter_Information.i16PVGenPower = (i32Ptmp * 251) >> 8;	// 0.981
        	
        		// 如果电池符号改变,强制为0
        		i32Ptmp = Inverter_Information.i16PVGenPower - Inverter_Information.i16PowerAC;
        		
        		
        		if ((i32Ptmp > 0 && Inverter_Information.i16BatPower < 0)
        			|| (i32Ptmp < 0 && Inverter_Information.i16BatPower > 0))
        		{
        			i32Ptmp = 0;
        		}
        		Inverter_Information.i16BatPower = i32Ptmp;
        	}

        }     

       rtdb.i16PVGenPower = Inverter_Information.i16PVGenPower / 10;
        rtdb.i16BatChgDischgPower = Inverter_Information.i16BatPower / 10;
#endif

小记一下;
这里的关于PowerPV1计算的时候用到了IIR FILTER

#define IIR_FILTER(s,x,n)			do{(s)=(s)-((s)>>(n))+(x);}while(0)

下次来了再看一下。

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值