⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ct_monitor.c

📁 基于MSP430的电表终端上的CT检测程序
💻 C
字号:
//CT检测子程序
#include "msp430x13x.h"
#include "math.h"


void MonotonyJudge(const long  In, const long Fn, long *I0, long *F0, int *count, int *shortflag );
void Judge3Phase();
unsigned char MonotonyJudgeEN=0;//电流频率控制位
#define JDQA_ON  0x40
#define JDQA_OFF !JDQA_ON
#define JDQB_ON  0x20
#define JDQB_OFF !JDQA_ON
#define JDQC_ON  0x10
#define JDQC_OFF !JDQA_ON


unsigned char two_CT_state;       //二次CT状态字
//位  :   7	  6	  5	  4	  3	  2	  1	  0
//定义: 未定义	未定义	C相开路	B相开路	A相开路	C相短路	B相短路	A相短路
#define CTA_duan_lu_ON   0x01
#define CTA_duan_lu_OFF  0xfe
#define CTB_duan_lu_ON   0x02
#define CTB_duan_lu_OFF  0xfd
#define CTC_duan_lu_ON   0x04
#define CTC_duan_lu_OFF  0xfb

#define CTA_kai_lu_ON    0x08
#define CTA_kai_lu_OFF   0xf7
#define CTB_kai_lu_ON    0x10
#define CTB_kai_lu_OFF   0xef
#define CTC_kai_lu_ON    0x20
#define CTC_kai_lu_OFF   0xdf

 long int CT_check_data_a;
 long int CT_check_data_b;
 long int CT_check_data_c;
 long int CT_current_A,CT_current_B,CT_current_C;
long int kl_up_data_a,kl_up_data_b,kl_up_data_c;
unsigned int kl_count_a,kl_count_b,kl_count_c;
unsigned int dl_count_a,dl_count_b,dl_count_c;

extern void InitTA (void);       //初始化TIMEA  处于增计数模式
extern void InitTB (void);
extern unsigned long int TimeANumber;       //TA中断时TB的计时数值
extern unsigned int TAIntCount;       //TA中断的次数
extern unsigned int TAIntCountNow;
extern void ResetTA (void);
extern void ResetTB (void);
unsigned char AllDataChang;           //三相数据已更新标志

unsigned char ChangeSLab=0;      //三路信号切换标志.

extern unsigned char TBInt;           //TB中断标志
extern unsigned char SPIDataBuff[1700];;       //SPI接收缓存区

unsigned char temp_H,temp_M,temp_L;
unsigned char temp_aH,temp_aM,temp_aL,temp_bH,temp_bM,temp_bL,temp_cH,temp_cM,temp_cL;
unsigned char dis_plus_aH,dis_plus_aM,dis_plus_aL,dis_plus_bH,dis_plus_bM,dis_plus_bL,dis_plus_cH,dis_plus_cM,dis_plus_cL;
void hex_to_dec(unsigned long int a);unsigned int BCD_to_HEX(unsigned char H,unsigned char M,unsigned char L);
extern void  clr_wdt(void);
extern unsigned int flash_data_buff[10];
extern void  write_flash (void);
extern void  read_flash (void);
extern void flash_init(void);
extern unsigned char StartSaveCtdata;
extern unsigned char WriteCurrentSB;   //2410写入电流标志

extern unsigned char LMD_WRITE;       //灵敏度百分比1》1%  2》2%
extern unsigned char DEY_WRITE;
#define dl_a  flash_data_buff[0]
#define dl_b  flash_data_buff[1]
#define dl_c  flash_data_buff[2]
//#define kl_a  flash_data_buff[3]
//#define kl_b  flash_data_buff[4]
//#define kl_c  flash_data_buff[5]
#define study_state flash_data_buff[6]
#define LMD_state flash_data_buff[7]
#define DEY_state flash_data_buff[8]
#define ZB_state flash_data_buff[9]   //电流屏蔽,为0则不屏蔽
#define bc_state flash_data_buff[3]

unsigned char S331_341=1;      //331与341选择  1:341 0 :331
unsigned char StartSaveStateA=1,StartSaveStateB=1,StartSaveStateC=1;





void hex_to_dec(unsigned long int a)            //十六进制转十进制BCD
{
   unsigned char temp1,temp2;
   if (a>=0xf423f)
     {
        temp_H=0x99;
        temp_M=0x99;
        temp_L=0x99;
     }
   else
   {
    temp1= a / 100000;
    temp2= (a % 100000)/10000;
    temp_H= (temp1<<4)+temp2;
    temp1= (a % 10000)/1000;
    temp2= (a % 1000)/100;
    temp_M= (temp1<<4)+temp2;
    temp1= (a % 100)/10;
    temp2= a % 10;
    temp_L= (temp1<<4)+temp2;
   }
}

//三字节十进制BCD码转换为两字节HEX码
unsigned int BCD_to_HEX(unsigned char H,unsigned char M,unsigned char L)
{
unsigned int temp; if(H>5) return 0xffaa;
temp=(((L>>4)*10)+(L&0x0f))+(((M>>4)*10)+(M&0x0f))*100+(((H>>4)*10)+(H&0x0f))*10000;
return temp;
}

void delay_n_ms(unsigned char a)             //延时子程序
{ unsigned char b,c;
  for(;a>0;a--)
     for(b=100;b>0;b--)
     {   clr_wdt();
        for(c=100;c>0;c--);}
}


void delay_ns (unsigned char n)
{  unsigned int a,b;
   for (;n>0;n--)
      for(a=200;a>0;a--)
       {clr_wdt();
         for(b=100;b>0;b--);
         }
}

//**************************************************************//
void ChangeSInput (unsigned char n,unsigned char ON_OFF)             //n 表明要接入哪一路信号 1:A相  2:B相  3:C相
{                                               //ON_OFF 表明是要吸合还是断开信号输入 1:吸合 0:断开
 if(ON_OFF==1)
   {
    switch (n)
     {
       case 0 : P4OUT&=JDQC_OFF;
                P4OUT&=JDQB_OFF;
                P4OUT|=JDQA_ON;
                break;
       case 1 : P4OUT&=JDQA_OFF;
                P4OUT&=JDQC_OFF;
                P4OUT|=JDQB_ON;
                break;
       case 2 : P4OUT&=JDQA_OFF;
                P4OUT&=JDQB_OFF;
                P4OUT|=JDQC_ON;
                break;
       default: break;
     }
   }
 if(ON_OFF==0)
   {
    switch (n)
      {
       case 0 : P4OUT&=JDQA_OFF;
                break;
       case 1 : P4OUT&=JDQB_OFF;
                break;
       case 2 : P4OUT&=JDQC_OFF;
                break;
       default: break;
      }
   }
}
//**************************************************************

long load_data(unsigned char a)
{long plus;
    plus=(TimeANumber+65536*TAIntCount)*2;
    ChangeSInput(a,1);
    delay_ns(20);
    ResetTB();
    ResetTA();
    TimeANumber=0;
    TBInt=0;
    TAIntCountNow=0;
    return plus;
}

void load_CT_data(void)         //三相数据装载控制
{
	
    if((ChangeSLab==0)&&(TBInt>1))
    {
    ChangeSLab=1;
    CT_check_data_a=load_data(ChangeSLab);
    }

    if((ChangeSLab==1)&&(TBInt>1))
    {
    ChangeSLab=2;
    CT_check_data_b=load_data(2);
    }

    if((ChangeSLab==2)&&(TBInt>1))
    {
    ChangeSLab=0;
    CT_check_data_c=load_data(ChangeSLab);
    AllDataChang=1;
    }
}

void save_ct_data(unsigned long int ct_now_data ,unsigned char LMD, unsigned char flash_number)
{
 flash_data_buff[flash_number]= ct_now_data;
   //学习次数保存
   study_state++;
   clr_wdt();
   write_flash();
   clr_wdt();
   StartSaveCtdata=0;
   AllDataChang=0;
}

void save_all_CT_data(void)          //保存三相CT的初始化数据
{  unsigned char tempp;
   if(LMD_WRITE==0)
   {
    if (LMD_state>100)   //灵敏度值判断,默认为4%
    {tempp=4;LMD_state=tempp;LMD_WRITE=LMD_state;}
       else {tempp=LMD_state;LMD_WRITE=LMD_state;}
   }
   else    {tempp=LMD_WRITE; LMD_state=tempp;}

   if((StartSaveCtdata==1)&&(AllDataChang==1))
   {
   save_ct_data(CT_check_data_a,tempp,0);
   save_ct_data(CT_check_data_b,tempp,1);
   save_ct_data(CT_check_data_c,tempp,2);

   }
   //如果在331时AC相开路及341时ABC相开路则执行一次学习指令
   if(((two_CT_state&0x08)==0x08)&&(StartSaveStateA))
   {StartSaveStateA=0;save_ct_data(CT_check_data_a,tempp,0);}

   if(((two_CT_state&0x10)==0x10)&&(StartSaveStateB))
   {StartSaveStateB=0;save_ct_data(CT_check_data_b,tempp,1);}

   if(((two_CT_state&0x20)==0x20)&&(StartSaveStateC))
   {StartSaveStateC=0;save_ct_data(CT_check_data_c,tempp,2);}
}

void CTStateCheck (void)             //检测三相的CT状态
{unsigned int temp_dey,temp_bc;

    if (DEY_state>150)    //检测延时
    {temp_dey=80;DEY_state=temp_dey;DEY_WRITE=DEY_state;}
       else {temp_dey=DEY_state;DEY_WRITE=DEY_state;}

//1.2A以上须减去一个固定频率,可通过echo XX > ptct_setct 进行修改 XX 为十六进制方式 最大为99,
        if (bc_state>100)
    {temp_bc=500;bc_state=(temp_bc/100);}  //数据无效,默认为500
       else {temp_bc=bc_state*100;}


 if((AllDataChang==1)&&(StartSaveCtdata==0))
 { AllDataChang=0;
    if(ZB_state!=0xaa)
     ZB_state=0xbb;
  if(ZB_state==0xbb)    //如果为BB则输出减去基准值后的值
   {
     if(CT_check_data_a>=dl_a)
        hex_to_dec((CT_check_data_a-dl_a));
     else
   	  {
        hex_to_dec((dl_a-CT_check_data_a));
        temp_H=(temp_H|0x10);//输出为负数
   	  }
   }
   else hex_to_dec(CT_check_data_a);// 如果不为BB则输出原始值
   temp_aH=temp_H;
   temp_aM=temp_M;
   temp_aL=temp_L;

   	
   if(ZB_state==0xbb)    //如果为BB则输出减去基准值后的值
   {
     if(CT_check_data_b>=dl_b)
        hex_to_dec((CT_check_data_b-dl_b));
     else
   	  {
        hex_to_dec((dl_b-CT_check_data_b));
        temp_H=(temp_H|0x10);//输出为负数
   	  }
   }
   else hex_to_dec(CT_check_data_b);// 如果不为BB则输出原始值
   temp_bH=temp_H;
   temp_bM=temp_M;
   temp_bL=temp_L;


   hex_to_dec(dl_a);
   dis_plus_aH=temp_H;
   dis_plus_aM=temp_M;
   dis_plus_aL=temp_L;
   hex_to_dec(dl_b);
   dis_plus_bH=temp_H;
   dis_plus_bM=temp_M;
   dis_plus_bL=temp_L;
   hex_to_dec(dl_c);
   dis_plus_cH=temp_H;
   dis_plus_cM=temp_M;
   dis_plus_cL=temp_L;



   if(ZB_state==0xbb)    //如果为BB则输出减去基准值后的值
   {
     if(CT_check_data_c>=dl_c)
        hex_to_dec((CT_check_data_c-dl_c));
     else
   	  {
        hex_to_dec((dl_c-CT_check_data_c));
        temp_H=(temp_H|0x10);//输出为负数
   	  }
   }
   else hex_to_dec(CT_check_data_c);// 如果不为BB则输出原始值
   temp_cH=temp_H;
   temp_cM=temp_M;
   temp_cL=temp_L;

   clr_wdt();
   if((CT_current_A<180)&&((two_CT_state&CTA_duan_lu_ON)!=CTA_duan_lu_ON))//0A时有短路就不报开路
   {if(kl_count_a<(temp_dey+2)) kl_count_a++;}
   else
   {if(kl_count_a!=0) kl_count_a--;}
  if(S331_341)
   {
   if((CT_current_B<180)&&((two_CT_state&CTB_duan_lu_ON)!=CTB_duan_lu_ON))//0A时有短路就不报开路
   {if(kl_count_b<(temp_dey+2)) kl_count_b++;}
   else
   {if(kl_count_b!=0) kl_count_b--;}
  }
   if((CT_current_C<180)&&((two_CT_state&CTC_duan_lu_ON)!=CTC_duan_lu_ON))//0A时有短路就不报开路
   {if(kl_count_c<(temp_dey+2)) kl_count_c++;}
   else
   {if(kl_count_c!=0) kl_count_c--;}

   if(kl_count_a>temp_dey)
   {two_CT_state|=CTA_kai_lu_ON;}
   if (kl_count_a==0)
   {two_CT_state&=CTA_kai_lu_OFF;StartSaveStateA=1;}//每次判断出开路恢复则开启开路记录基准频率功能
if(S331_341)
   {
   if(kl_count_b>temp_dey)
   {two_CT_state|=CTB_kai_lu_ON;}
   if (kl_count_b==0)
   {two_CT_state&=CTB_kai_lu_OFF;StartSaveStateB=1;}
}
   if(kl_count_c>temp_dey)
   {two_CT_state|=CTC_kai_lu_ON;}
   if (kl_count_c==0)
   {two_CT_state&=CTC_kai_lu_OFF;StartSaveStateC=1;}
 }
}











⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -