找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1598|回复: 1
收起左侧

MSP430采集交流信号程序

[复制链接]
ID:599388 发表于 2019-8-12 15:22 | 显示全部楼层 |阅读模式
     本程序利用MSP较高的采样速度和12位AD精度,采用均方根算法,求电压、电流有效值;四象限有功功率,无功功率;电能值。
需要整体源代码及原理图的朋友请和我联系。珠海的朋友可以项目合作。扣扣:2544931233

单片机源程序如下:
  1. //本程序的主要功能是:
  2. //                  1.计算各电参数每周波的有效值;
  3. //                  2.计算各电参数多个周波有效值的平均值(滤波),每分钟进行计算
  4. //                  3.产生电能脉冲输出;
  5. //                  4.计算电能
  6. //                  5.产生告警记录,(在每一分钟进行统计)
  7. //                  6.统计最大值最小值
  8. #include "msp430x14x.h"
  9. #include "my.h"
  10. #include "stdlib.h"

  11. void Process1s(void);
  12. void Process10s(void);
  13. void Process1m(void);
  14. void ProcessT(void);
  15. void ProcessMonth(void);
  16. void InitMaxMin(void);
  17. void CalculateEnergy(void);
  18. void CalculateVirtualValue(void);
  19. void  CalPower(void);
  20. void ClearEnergyRegister(void);

  21. static WORD CalPf(WORD p,WORD q);
  22. static WORD MExtract(DWORD sqr);

  23. extern BYTE FlashErase(UWORD *address);
  24. extern BYTE FlashWrite(UWORD *dataaddr,UWORD *flashaddr,UWORD counter);
  25. extern void FlashRead(UWORD *dataaddr,UWORD *flashaddr,UWORD counter);
  26. extern void WriteMainRecord(BYTE type);
  27. extern void GetHext(UDWORD ASECOND);
  28. BYTE  RecordErr;


  29. //相角补偿表
  30. const WORD Compensate[60]=
  31. {
  32.     -54,-52,-50,-48,-46,-45,-43,-41,-39,-38,
  33.      -36,-34,-32,-30,-29,-27,-25,-23,-21,-20,
  34.      -18,-16,-14,-13,-11, -9, -7, -5, -4, -2,
  35.        0,  2,  4,  5,  7,  9, 11, 13, 14, 16,
  36.       18, 20, 21, 23, 25, 27, 29, 30, 32, 34,
  37.       36, 38, 39, 41, 43, 45, 46, 48, 50, 52,
  38. };

  39. //===========================================================================
  40. SUM   Sum,SumTemp;
  41. WORD  CalSeq;
  42. DWORD DDataEPaP,DDataEPbP,DDataEPcP,DDataEPaN,DDataEPbN,DDataEPcN;
  43. DWORD DDataEQaP,DDataEQbP,DDataEQcP,DDataEQaN,DDataEQbN,DDataEQcN;
  44. DWORD CounterPulseP,CounterPulseQ;
  45. RECORD RecordTemp;

  46. DWORD  V_Sum_1m[3], I_Sum_1m[4];
  47. WORD   Power[6];
  48. BYTE   Count_Sum_1m;
  49. UWORD  FlagAlarm;
  50. VIRTUALDATA VirtualData;

  51. //extern BYTE Flag1s,Flag10s,Flag1m,FlagT;
  52. extern BYTE  FlagTime;
  53. extern PARAMETER ParameterTemp;
  54. extern CLOCK Clock;
  55. extern FREEZE_ENERGY FreezeEnergy[3];
  56. extern UWORD FreezeEnergyCounter;
  57. extern UDWORD  RSECOND;
  58. extern UDWORD PRODUCTNUMBER;
  59. extern UDWORD ProductNumber;
  60. extern SAMPLEDATA SampleData;

  61. extern COEFF Coeff,CoeffTemp;
  62. extern ENERGY Energy;
  63. extern BYTE Page;
  64. extern BYTE NewMonthFlag;
  65. extern WORD Frequency;
  66. extern UWORD RecordNumber;
  67. extern BYTE FlagCalculate;

  68. //==================================================================================
  69. //计算电流电压功率温度平均值
  70. void Process1s(void)
  71. {
  72.         BYTE i,FlagAlarm1s;      
  73.         WORD TemptErr;   //温度差                       
  74.             WORD *ptr0,*ptr1,reg0,reg1;
  75.             DWORD *dptr,dreg;
  76.             UDWORD TimeTemp;
  77.            
  78.             FlagTime&=~BIT0;
  79.         
  80.         TemptErr = VirtualData.Tempt-30;
  81.         
  82.             ptr0=(WORD*)&VirtualData.Ua;           
  83.             ptr1=(WORD*)&CoeffTemp.Ua;
  84.             dptr=&Sum.Ua;
  85.             for(i=0;i<3;i++)
  86.             {
  87.                 reg1=*dptr>>4;                              //   *dptr=0;
  88.                 reg0 = reg1;//-(DWORD)reg1*3*TemptErr/10000;
  89.                 *ptr0=((DWORD)reg0*(*ptr1))>>10;            //U
  90.                 if((UWORD)*ptr0>0x7fff) *ptr0=0x7fff;
  91.                 V_Sum_1m[i]+=*ptr0;                         //电压和累计
  92.         
  93.                 reg1=*(dptr+1)>>4;
  94.                 reg0 = reg1;//-(DWORD)reg1*3*TemptErr/10000;  //温度补偿
  95.                 *(ptr0+1)=((DWORD)reg0*(*(ptr1+1)))>>10;    //I               
  96.                 if((UWORD)(*(ptr0+1))>0x7fff) *(ptr0+1)=0x7fff;
  97.                 I_Sum_1m[i]+=*(ptr0+1);
  98.       
  99.                 ptr0+=2;ptr1+=2;dptr+=2;
  100.             }
  101.            
  102.             CalPower();
  103.            
  104.             ptr0=(WORD*)&VirtualData.Pa;
  105.             ptr1=(WORD*)&CoeffTemp.Pa;           
  106.         for(i = 0;i<3;i++)
  107.         {               
  108.                 *ptr0=Power[2*i]+(((DWORD)Power[2*i+1]*Compensate[*ptr1])>>10);
  109.                 if(abs(*ptr0)<10) *ptr0=0;          //判断绝对值
  110.                
  111.                 *(ptr0+1)=Power[i*2+1]-(((DWORD)Power[2*i]*Compensate[*(ptr1+1)])>>10);
  112.                 if(abs(*(ptr0+1))<10) *(ptr0+1)=0;          //判断绝对值
  113.                
  114.                 ptr0+=2; ptr1+=2;
  115.             }
  116.            
  117.             reg0=Sum.I0>>4;
  118.             reg1=(DWORD)reg0*Coeff.Ib>>10;    //乘以IB的系数
  119.             if((UWORD)reg1>0x7fff)reg1=0x7fff;           
  120.             VirtualData.I0=reg1;
  121.             I_Sum_1m[3]+=reg1;   
  122.                     
  123.             Count_Sum_1m++;                              //和累计次数   
  124.    
  125.    
  126.             if(VirtualData.Ia<10)VirtualData.Pfa=0;
  127.             else  VirtualData.Pfa=CalPf(VirtualData.Pa,VirtualData.Qa);
  128.    
  129.             if(VirtualData.Ib<10)VirtualData.Pfb=0;
  130.             else  VirtualData.Pfb=CalPf(VirtualData.Pb,VirtualData.Qb);
  131.    
  132.             if(VirtualData.Ic<10)VirtualData.Pfc=0;
  133.             else  VirtualData.Pfc=CalPf(VirtualData.Pc,VirtualData.Qc);
  134.            
  135.             if(Frequency==0)Frequency = 5000;
  136.             VirtualData.Freq=Frequency;
  137.             dreg=0;
  138.             for(i=0;i<24;i++)dreg+=(DWORD)SampleData.Tempt[i];
  139.             reg0=dreg/24-1560;//1580;
  140.             VirtualData.Tempt=((DWORD)reg0*10)/80;
  141.    
  142.         
  143.             FlagAlarm1s=FALSE;
  144.             ptr0=&VirtualData.Ua;
  145.             for(i=0;i<3;i++)
  146.             {
  147.                 if(*ptr0>ParameterTemp.OverVoltage)FlagAlarm1s=TRUE;
  148.                 if(*ptr0<ParameterTemp.LowVoltage) FlagAlarm1s=TRUE;
  149.                 ptr0+=2;
  150.             }
  151.             ptr0=&VirtualData.Ia;
  152.             for(i=0;i<3;i++)
  153.             {
  154.                 if(*ptr0>ParameterTemp.OverCurrent)FlagAlarm1s=TRUE;
  155.                 ptr0+=2;
  156.             }
  157.            
  158.             if(VirtualData.I0>ParameterTemp.OverCurrent0)FlagAlarm1s=TRUE;
  159.    
  160.             if(FlagAlarm1s)P1OUT|=BIT2;                          //告警指示灯亮   
  161.             else           P1OUT&=~BIT2;                         //熄灭告警指示灯   
  162.            
  163.             _DINT();
  164.             TimeTemp = RSECOND;
  165.             _EINT();
  166.             if(Page!=0x01)GetHext(TimeTemp);
  167.            
  168.             if(Clock.month!=Clock.monthR)
  169.             {
  170.                     NewMonthFlag=true;            //判断是否进入新的一月
  171.             //        ProcessMonth();
  172.             }   
  173.    
  174. }
  175. //====================================================================================================
  176. void CalPower(void)
  177. {
  178.         BYTE i;
  179.         DWORD *dptr;
  180.         WORD  reg0,*ptr1;
  181.        
  182.         dptr =(DWORD *)&Sum.Pa;
  183.         ptr1=(WORD *)&CoeffTemp.Ua;
  184.        
  185.         for(i = 0;i <3 ; i++)
  186.         {               
  187.                 reg0=*dptr>>4;     //P
  188.                 reg0=((DWORD)reg0*(*ptr1))>>10;      //*Coeff_U
  189.                 reg0=((DWORD)reg0*(*(ptr1+1)))>>10;  //*Coeff_I         
  190.                 Power[i*2] = reg0;
  191.                 dptr++;
  192.                
  193.                 reg0=*dptr>>4;   //Q
  194.                 reg0=((DWORD)reg0*(*ptr1))>>10;      //*Coeff_U
  195.                 reg0=((DWORD)reg0*(*(ptr1+1)))>>10;  //*Coeff_I         
  196.                 Power[2*i+1] = reg0;
  197.                 dptr++;
  198.                 ptr1+=2;
  199.         }
  200. }      

  201. //====================================================================================================
  202. //函数名:ProcessMonth
  203. //功能:  对每月的电能进行冻结,统计,存储。可以连续存3个月。
  204. //====================================================================================================
  205. void ProcessMonth(void)
  206. {
  207.         BYTE i;
  208.         DWORD temp1,temp2,*ptr1;
  209.         UWORD *ptr3,*ptr4;
  210.         UWORD j;
  211.        
  212.         FREEZE_ENERGY FreezeEnergyTemp[3];
  213.        
  214.        
  215.         NewMonthFlag=false;
  216.         Clock.monthR=Clock.month;
  217.        
  218.         ptr1=(DWORD*)&VirtualData.EPaP;
  219.         temp1=0;
  220.         for(i=0;i<3;i++)temp1+=*ptr1++;    //统计有功电能
  221.        
  222.         ptr1=(DWORD*)&VirtualData.EQaP;
  223.         temp2=0;
  224.         for(i=0;i<3;i++)temp2+=*ptr1++;    //统计无功电能
  225.        
  226.         ptr3=(UWORD*)&FreezeEnergy[0].SECOND1;
  227.         ptr4=(UWORD*)&FreezeEnergyTemp[0].SECOND1;
  228.         for(i=0;i<21;i++)*ptr4++=*ptr3++;   //读出已经存起来的统计电能
  229.                
  230.         j=FreezeEnergyCounter;
  231.        
  232.         _DINT();
  233.         FreezeEnergyTemp[j%3].SECOND1=RSECOND;
  234.         _EINT();
  235.         FreezeEnergyTemp[j%3].SumEP=temp1;
  236.         FreezeEnergyTemp[j%3].SumEQ=temp2;
  237.         FreezeEnergyTemp[j%3].FreezeFlag=0x55aa;
  238.         j++;
  239.        
  240.         ProductNumber=PRODUCTNUMBER;       
  241.         FlashErase((UWORD*)&PRODUCTNUMBER);
  242.        
  243.         FlashWrite((UWORD*)&ProductNumber,(UWORD*)&PRODUCTNUMBER,2);       
  244.         FlashWrite((UWORD*)&FreezeEnergyTemp[0].SECOND1,(UWORD*)&FreezeEnergy[0].SECOND1,21);       
  245.         FlashWrite((UWORD*)&j,(UWORD*)&FreezeEnergyCounter,1);               
  246.        
  247. }
  248. //====================================================================================================
  249. //函数名: Process10s
  250. //功能: 每10秒钟处理事情,包括比较U,I,P,Q最大值,最小值,以供统计; 保存电能值。
  251. void Process10s(void)
  252. {      
  253.         BYTE i;
  254.         WORD *ptrdata,*ptrdata1;
  255.         WORD *ptr1,*ptr2;
  256.         //Flag10s=FALSE;
  257.         FlagTime&=~BIT1;

  258.         ptrdata=&VirtualData.Ua;ptrdata1=&RecordTemp.Ua[0];
  259.         for(i=0;i<13;i++)
  260.         {
  261.                 if(*ptrdata1<*ptrdata)*ptrdata1=*ptrdata;
  262.                 ptrdata1++;
  263.                 if(*ptrdata1>*ptrdata)*ptrdata1=*ptrdata;
  264.                 ptrdata1++;
  265.                 ptrdata++;
  266.         }
  267.         
  268.          if(RecordTemp.Frequency[0]<VirtualData.Freq)RecordTemp.Frequency[0]=VirtualData.Freq;
  269. //计算最小值
  270.          if(RecordTemp.Frequency[1]>VirtualData.Freq)RecordTemp.Frequency[1]=VirtualData.Freq;
  271.         
  272.          if(RecordTemp.Ua[0]<RecordTemp.Ua[1])InitMaxMin();
  273.          else  RecordErr=0;  
  274.          
  275.         ptr1=(WORD*)&VirtualData.EPaP;
  276.                ptr2=(WORD*)&Energy.EPaP;    //读电能
  277.                for(i=0;i<24;i++) *ptr2++=*ptr1++ ;   
  278.       
  279. }
  280. //====================================================================================================
  281. //函数名: Process1m
  282. //功能:   1.得到每分钟U I  的平均值
  283. //         2.根据平均值与设置的阀值进行比较,形成告警记录。
  284. //修改记录:
  285. void  Process1m(void)
  286. {
  287.         WORD avargeV[3],avargeI[4];             
  288.               BYTE i;  
  289.               FlagTime&=~BIT2;
  290.       
  291.       
  292.               if(Count_Sum_1m!=0)                                       //求1分钟之内的电压、电流平均值
  293.                {
  294.                     for (i=0;i<3;i++)
  295.                      {
  296.                             avargeV[i]=V_Sum_1m[i]/Count_Sum_1m;        //计算电压在1分钟内的平均值
  297.                             V_Sum_1m[i]=0;                              //清除累加和
  298.                      }
  299.                     for (i=0;i<4;i++)
  300.                      {
  301.                             avargeI[i]=I_Sum_1m[i]/Count_Sum_1m;        //计算电流在1分钟内的平均值
  302.                             I_Sum_1m[i]=0;                                     //清除累加和
  303.                      }
  304.                      Count_Sum_1m=0;                                    //清除累加次数
  305.         }
  306.       
  307.               for(i=0;i<3;i++)
  308.                {
  309.                     if(avargeV[i]>ParameterTemp.OverVoltage)
  310.                      {
  311.                            if(!((FlagAlarm>>i)&0x01))
  312.                             {
  313.                                     FlagAlarm|=(0x01<<i);
  314.                                     WriteMainRecord(0x0003+i);      //过压告警
  315.                             }
  316.                      }
  317.                     else
  318.                      {
  319.                            if((FlagAlarm>>i)&0x01)
  320.                             {
  321.                                      FlagAlarm&=~(0x01<<i);
  322.                                      WriteMainRecord(0x0006+i);      //过压恢复
  323.                             }
  324.                       }               
  325.                }

  326.         
  327.               for(i=3;i<6;i++)
  328.                {
  329.                     if(avargeV[i-3]<ParameterTemp.LowVoltage)
  330.                      {
  331.                            if(!((FlagAlarm>>i)&0x01))
  332.                             {
  333.                                     FlagAlarm|=(0x01<<i);
  334.                                     WriteMainRecord(0x0006+i);      //欠压告警
  335.                             }
  336.                      }
  337.                     else
  338.                     {
  339.                            if((FlagAlarm>>i)&0x01)
  340.                            {
  341.                                     FlagAlarm&=~(0x01<<i);
  342.                                     WriteMainRecord(0x0009+i);      //欠压恢复
  343.                             }
  344.                     }
  345.                
  346.               }
  347.       
  348.              for(i=6;i<9;i++)
  349.               {
  350.                     if(avargeI[i-6]>ParameterTemp.OverCurrent)
  351.                     {
  352.                            if(!((FlagAlarm>>i)&0x01))
  353.                            {
  354.                                    FlagAlarm|=(0x01<<i);
  355.                                    WriteMainRecord(0x0009+i);      //过流告警
  356.                            }
  357.                     }
  358.                    else
  359.                     {
  360.                            if((FlagAlarm>>i)&0x01)
  361.                            {
  362.                                   FlagAlarm&=~(0x01<<i);
  363.                                   WriteMainRecord(0x000c+i);      //过流恢复
  364.                            }
  365.                     }
  366.               
  367.                }
  368.               
  369.                 if(avargeI[3]>ParameterTemp.OverCurrent0)
  370.          {
  371.                if(!((FlagAlarm>>9)&0x01))
  372.                 {
  373.                           FlagAlarm|=(0x01<<9);
  374.                           WriteMainRecord(0x0015);      //零序告警
  375.                 }
  376.          }
  377.          else
  378.          {
  379.                if((FlagAlarm>>9)&0x01)
  380.                 {
  381.                           FlagAlarm&=~(0x01<<9);
  382.                           WriteMainRecord(0x0016);      //零序恢复
  383.                 }
  384.          }
  385. }
  386. //===================================================================================================
  387. //函数名: ProcessT
  388. //功能 :  1.根据存储间隔 形成定时记录,同时保存记录  
  389. //         2.初始化U I P Q最大值,最小值。
  390. void ProcessT(void)
  391. {
  392.         //FlagT=FALSE;
  393.         FlagTime&=~BIT3;
  394.        
  395.         if(RecordErr)return;         //判断记录是否有效
  396.         WriteMainRecord(0x0000);     //定时记录
  397.        
  398.         InitMaxMin();               //清除最大值最小值       
  399. }
  400. //===================================================================================================
  401. //
  402. void InitMaxMin(void)
  403. {
  404.         BYTE i;
  405.         WORD *ptrdata;
  406.        
  407.         ptrdata=&RecordTemp.Ua[0];
  408.         for(i=0;i<13;i++)
  409.         {
  410.                 *ptrdata++=0xffff;
  411.                 *ptrdata++=0x7fff;
  412.         }
  413.         RecordTemp.Frequency[0]=0;
  414.         RecordTemp.Frequency[1]=0x7fff;
  415.         RecordErr=TRUE;
  416. }
  417. //===================================================================================================
  418. //计算电能
  419. //由50ms处调用该功能函数
  420. void CalculateEnergy(void)
  421. {
  422.         BYTE i;
  423.             DWORD *ptr0,*ptr1;

  424.             if(VirtualData.Pa>=0)DDataEPaP+=VirtualData.Pa;
  425.             else DDataEPaN-=VirtualData.Pa;
  426.             if(VirtualData.Pb>=0)DDataEPbP+=VirtualData.Pb;
  427.             else DDataEPbN-=VirtualData.Pb;
  428.             if(VirtualData.Pc>=0)DDataEPcP+=VirtualData.Pc;
  429.             else DDataEPcN-=VirtualData.Pc;
  430.             if(VirtualData.Qa>=0)DDataEQaP+=VirtualData.Qa;
  431.             else DDataEQaN-=VirtualData.Qa;
  432.             if(VirtualData.Qb>=0)DDataEQbP+=VirtualData.Qb;
  433.             else DDataEQbN-=VirtualData.Qb;
  434.             if(VirtualData.Qc>=0)DDataEQcP+=VirtualData.Qc;
  435.             else DDataEQcN-=VirtualData.Qc;
  436.    
  437.             CounterPulseP+=(DWORD)VirtualData.Pa+(DWORD)VirtualData.Pb+(DWORD)VirtualData.Pc;
  438.             CounterPulseQ+=(DWORD)VirtualData.Qa+(DWORD)VirtualData.Qb+(DWORD)VirtualData.Qc;

  439. //有功电度脉冲输出,3200imp/kw.h
  440.             if(CounterPulseP>=11636364)        //232727~3200   465455~1600
  441.              {
  442.                       TBCCTL6=0x04;              //0000,0000,0000,0100     点亮灯        P
  443.                  TBCCTL6=0x0a0;             //0000,0000,1010,0000        
  444.                  TBCCR6=1800+TBR;
  445.                  CounterPulseP-=11636364;
  446.         
  447.              }
  448. //无功电度脉冲输出,3200imp/kvar.h
  449.             if(CounterPulseQ>=11636364)
  450.              {
  451.                
  452.                   TBCCTL5=0x04;             //0000,0000,0000,0100     点亮灯      Q
  453.                   TBCCTL5=0x0a0;            //0000,0000,1010,0000        
  454.                   TBCCR5=1800+TBR;
  455.                   CounterPulseQ-=11636364;  //232727*50;         
  456.              }

  457.             ptr0=&DDataEPaP;ptr1=&VirtualData.EPaP;      //电度累积,0.01kwh=0x4000*3600*20*10/(264*6)
  458.             for(i=0;i<12;i++)
  459.             {
  460.                 while((*ptr0)>=372363636)        //7447273*50
  461.                 {
  462.                             (*ptr1)++;
  463.                             if(((*ptr1)>999999)||((*ptr1)<0))(*ptr1)=0;
  464.                             (*ptr0)-=372363636;
  465.                        }
  466.                 ptr0++;ptr1++;
  467.             }
  468. }
  469. //==================================================================================
  470. //计算功率因数
  471. //p:有功功率
  472. //q:无功功率
  473. //return:功率因数
  474. WORD CalPf(WORD p,WORD q)
  475. {
  476.             DWORD ddata0,ddata1;

  477.             ddata0=(DWORD)p*p;
  478.             ddata1=(DWORD)q*q;
  479.             ddata0+=ddata1;
  480.             q=MExtract(ddata0);
  481.             ddata0=(DWORD)p<<10;
  482.             ddata0/=q;
  483.             return((WORD)ddata0);
  484. }
  485. //==================================================================================
  486. //开方算法
  487. WORD MExtract(DWORD sqr)
  488. {
  489.             WORD ax=0,bx=0x8000;
  490.             DWORD temp;   

  491.             if(sqr>0x3fffffff)return(0);
  492.             while(bx!=0)
  493.             {
  494.                 ax|=bx;
  495.                 temp=(DWORD)ax*ax;
  496.                 if(temp==sqr)return(ax);
  497.                 if(temp>sqr)ax^=bx;
  498.                 bx=(UWORD)bx>>1;
  499.             }
  500.             return(ax);
  501. }
  502. //====================================================================================
  503. //计算有效值
  504. //从采样中断中进行调用该函数
  505. void CalculateVirtualValue(void)
  506. {
  507.             WORD i,zerodrift[6],reg0,reg1;
  508.             DWORD i_0[24];   
  509.             DWORD sum0,sum1,sum2,sum3,sqsumi_0;
  510.             DWORD *dptr0,*dptr1;
  511.             DWORD regtemp;
  512.             BYTE  FlagIMin;
  513.            
  514.             FlagCalculate = false;
  515.    

  516. //计算通道零漂
  517.             sum0=0;
  518.             for(i=0;i<24;i++)sum0+=SampleData.Ua[i];
  519.             zerodrift[0]=sum0/24;
  520.             sum0=0;
  521.             for(i=0;i<24;i++)sum0+=SampleData.Ia[i];
  522.             zerodrift[1]=sum0/24;
  523.             sum0=0;
  524.             for(i=0;i<24;i++)sum0+=SampleData.Ub[i];
  525.             zerodrift[2]=sum0/24;
  526.             sum0=0;
  527.             for(i=0;i<24;i++)sum0+=SampleData.Ib[i];
  528.             zerodrift[3]=sum0/24;
  529.             sum0=0;
  530.             for(i=0;i<24;i++)sum0+=SampleData.Uc[i];
  531.             zerodrift[4]=sum0/24;
  532.             sum0=0;
  533.             for(i=0;i<24;i++)sum0+=SampleData.Ic[i];
  534.             zerodrift[5]=sum0/24;

  535. //---------------------------------------------------------------------
  536.            sqsumi_0=0;
  537.            for(i=0;i<24;i++)                  //计算零序电流  
  538.            {
  539.                    i_0[i]=(DWORD)SampleData.Ia[i]+(DWORD)SampleData.Ib[i]+(DWORD)SampleData.Ic[i];
  540.                    i_0[i]=i_0[i]-zerodrift[1]-zerodrift[3]-zerodrift[5];
  541.                    sqsumi_0+=(DWORD)i_0[i]*i_0[i];    //求平方和
  542.            }            
  543.            FlagIMin=0;  
  544.    
  545. //计算平方和,有效值
  546.             sum0=0;sum1=0;sum2=0;sum3=0;
  547.             for(i=0;i<24;i++)
  548.             {
  549.                 reg0=SampleData.Ua[i]-zerodrift[0];
  550.                 sum0+=(DWORD)reg0*reg0;                 //Ua
  551.                 reg1=SampleData.Ia[i]-zerodrift[1];
  552.                 sum1+=(DWORD)reg1*reg1;                 //Ia
  553.                 sum2+=(DWORD)reg0*reg1;                 //Pa
  554.                 reg1=SampleData.Ia[i+6]-zerodrift[1];
  555.                 sum3+=(DWORD)reg0*reg1;                 //Qa
  556.             }   
  557.      
  558.             regtemp=(DWORD)MExtract(sum0);
  559.             if(regtemp<30)regtemp>>=3;
  560.             SumTemp.Ua+= regtemp;
  561.    
  562.             regtemp=(DWORD)MExtract(sum1);   
  563.             if(regtemp<30)                           //电流零漂  //1000
  564.               {
  565.                  regtemp>>=3;
  566.                  sum2>>=3;
  567.                  sum3>>=3;
  568.                  FlagIMin|=BIT0;
  569.               }  
  570.             SumTemp.Ia+=regtemp;        
  571.             SumTemp.Pa+=sum2>>16;
  572.             SumTemp.Qa+=sum3>>16;

  573.             sum0=0;sum1=0;sum2=0;sum3=0;
  574.             for(i=0;i<24;i++)
  575.             {
  576.                 reg0=SampleData.Ub[i]-zerodrift[2];
  577.                 sum0+=(DWORD)reg0*reg0;                 //Ub
  578.                 reg1=SampleData.Ib[i]-zerodrift[3];
  579.                 sum1+=(DWORD)reg1*reg1;                 //Ib
  580.                 sum2+=(DWORD)reg0*reg1;                 //Pb
  581.                 reg1=SampleData.Ib[i+6]-zerodrift[3];
  582.                 sum3+=(DWORD)reg0*reg1;                 //Qb
  583.             }
  584.             regtemp=(DWORD)MExtract(sum0);   
  585.             if(regtemp<30) regtemp>>=3;      
  586.             SumTemp.Ub+= regtemp;
  587.    
  588.             regtemp=(DWORD)MExtract(sum1);   
  589.             if(regtemp<30)                           //电流零漂
  590.               {
  591.                  regtemp>>=3;
  592.                  sum2>>=3;
  593.                  sum3>>=3;
  594.                  FlagIMin|=BIT1;
  595.               }   
  596.             SumTemp.Ib+=regtemp;   
  597.             SumTemp.Pb+=sum2>>16;
  598.             SumTemp.Qb+=sum3>>16;

  599.             sum0=0;sum1=0;sum2=0;sum3=0;
  600.             for(i=0;i<24;i++)
  601.             {
  602.                 reg0=SampleData.Uc[i]-zerodrift[4];
  603.                 sum0+=(DWORD)reg0*reg0;                 //Uc
  604.                 reg1=SampleData.Ic[i]-zerodrift[5];
  605.                 sum1+=(DWORD)reg1*reg1;                 //Ic
  606.                 sum2+=(DWORD)reg0*reg1;                 //Pc
  607.                 reg1=SampleData.Ic[i+6]-zerodrift[5];
  608.                 sum3+=(DWORD)reg0*reg1;                 //Qc
  609.             }
  610.             regtemp=(DWORD)MExtract(sum0);
  611.             if(regtemp<30)regtemp>>=3;
  612.             SumTemp.Uc+=regtemp;
  613.    
  614.             regtemp=(DWORD)MExtract(sum1);
  615.             if(regtemp<30)
  616.             {
  617.                 regtemp>>=3;
  618.                 sum2>>=3;
  619.                 sum3>>=3;
  620.                 FlagIMin|=BIT2;
  621.             }   
  622.             SumTemp.Ic+=regtemp;
  623.             SumTemp.Pc+=sum2>>16;
  624.             SumTemp.Qc+=sum3>>16;
  625.    
  626.             if(FlagIMin!=0x07)                     //需判断各相电流是否都为0
  627.             {
  628.                     regtemp=(DWORD)MExtract(sqsumi_0);
  629.                     if(regtemp<1638) regtemp>>=4;              //判断零序电流是否大于取值的5%,0x7fff*5%=1638
  630.                     SumTemp.I0+=regtemp;                   
  631.             }
  632.    

  633. //计算平均值
  634.             if(++CalSeq>15)
  635.             {
  636.                 dptr0=(DWORD*)∑
  637.                 dptr1=(DWORD*)&SumTemp;
  638.                 CalSeq=0;
  639.                 for(i=0;i<13;i++)
  640.                  {
  641.                            *dptr0++=*dptr1;
  642.                            *dptr1++=0;
  643.                  }
  644.             }
  645.             ADC12CTL0&=~0x02;
  646.             ADC12CTL0|=0x02;            //Enable conversion
  647. //===============================================           
  648.             CCR1+=833;                  //2005-11-14
  649.         CCTL1&=0xffdf;              //Reset Timer_A.OUT1
  650.         CCTL1|=0x0020;
  651. }

  652. void ClearEnergyRegister(void)
  653. {
  654.         DDataEPaP = 0;
  655.         DDataEPbP = 0;
  656.         DDataEPcP = 0;
  657.         DDataEPaN = 0;
  658.         DDataEPbN = 0;
  659.         DDataEPcN = 0;
  660.         DDataEQaP = 0;
  661.         DDataEQbP = 0;
  662.         DDataEQcP = 0;
  663.         DDataEQaN = 0;
  664.         DDataEQbN = 0;
  665.         DDataEQcN = 0;
  666. }
复制代码



回复

使用道具 举报

ID:839438 发表于 2021-9-30 10:20 | 显示全部楼层
先记录一下,以后会用到
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表