|  | 
 
 
 楼主|
发表于 2025-9-13 09:21:35
|
显示全部楼层 
| 源代码,喝了太多聪明水,毫欧表功能还没能加入,源代码就被国家大佬盗过并修改过,仅供参考吧 
 复制代码
/*-----------------------------------------------
  AVmeter STC8H1K08T RES 2K22*4--2K5--10K
  Oscilator:24Mhz
------------------------------------------------*/
#include <STC8H.H>
#define uint unsigned int
#define uchar unsigned char  
#define iRefValue (*(unsigned int idata*)0xef)
#define eRefValue (*(unsigned int volatile xdata *)0xfde7)
#define UID0        0xF8  
#define UID1        0x40
#define UID2        0xC4
#define UID3        0x97
#define UID4        0x09
#define UID5        0x5C
#define UID6        0x7D
#define chRefV2K2D  11
#define chRefV2K2C  10
#define chRefV2K2B  9
#define chRefV2K2A  8
#define chRefV4400  7
#define chRefV3570  6
#define chRefV2750  5
#define chRefV2350  4
#define chRefV1730  3
#define chRefV1340  2
#define chRefVA620  1
#define constVoltDivider  2300                //100*(R1+R2)/R2=100*(100+4.4)/4.7=2234
#define constAVResL       2100                //4v4:2k1-13k  5v0:2k5-18k
#define constAVResH       13000
#define constVRefineTurn  10470               //VRefineTurn/100=95.30% 9770 9720  9545
//#define constHVFineTurn   1000               
#define constARANGE       10000               //5000ma
#define constAFineTurn    10000               //AFineTurn/100=100.00% 10000 10716
#define constHICFullADC   1595.0              //5A:1478(4V4);10A:1595(5V)/1565(4V4);20A:???
#define constResFullADC   780                 //10mR,10A   
#define constATurnStep    50                  //100% +/- 0.5%
#define constADCNoise     5
#define UseOldRef      0                      //OldRef:2k5-24k/12k/10k  NewRef:2k1-13k
#define CheckFullADC   0
#define CheckChipID    0
#define CheckKey       0
#define ShowEEROM      0
#define UseIdleMode    0
#define AVmeterUseHIC  1
#define ShowRefVolt    1
#define ThreeLEDVer    0
#define TxThreeDigi    0
#define LDOIs3V3       0
#define LDOIs3V6       0
#define LDOIs5V        0                      //Normal is 4V4
#define AVmeterIsLCM   0
#define AVmeterIsOLED  0
#define AVmeterIsmR    0
struct
   {uchar ParamValid;
    uchar ResZero;
    uint  HicZero;
    uint  VoltDivider;
        uint  AFineTurn;
    uint  VRefineTurn;
   } idata HwParam _at_ 0xf0;
uchar idata ParamBuf[10] _at_ 0xf0;
uchar idata UIDbuf[7],Vchar[8],Achar[8],Rchar[8],Echar[11];
uchar bdata DispFlag,IAPTick,KeyTick,KeyPressTime,Keybuf,CIDTick;
uchar ASEG1,ASEG2,ASEG3,ASEG4;
uchar VSEG1,VSEG2,VSEG3,VSEG4;
uchar scantick,adccnt,segnum;
uint  Abuf,PreAbuf,Vbuf,BCDbuf,BGVbuf,ADtick,RefVAtick;
uint  RefAVolt,VccVolt,R6k1Volt,Ref1300Volt;
uint  ADCVolt3570,ADCVolt2750,ADCVolt2350,ADCVolt1730,ADCVolt1340,ADCVARef;
unsigned long int LongBuf;
uint  AMPerDigi,mRbuf,Vbuffer[8],Abuffer[8];
#define KeyP1M0      0x9f                //AVR:0x9f   AVmeter:0xcf
sbit    KeyUpPin=P1^6;                   //AVR:P1.6   AVmeter:P1.4
sbit    KeyDownPin=P1^5;                 //AVR:P1.5   AVmeter:P1.5
sbit  KeyUpBit=Keybuf^4;
sbit  KeyDownBit=Keybuf^0;
sbit  IsSacnKey=KeyTick^7;
sbit  IsLongPress=KeyPressTime^7;
sbit  IsCheckID=CIDTick^7;
sbit  IsSaveEEROM=IAPTick^5;
sbit  IsIAPflash=IAPTick^7;
sbit  IsUpKey   =DispFlag^0;
sbit  IsValidADC=DispFlag^1;
sbit  IsRerr    =DispFlag^2;
sbit  IsShowRef =DispFlag^3;
sbit  IsWorking =DispFlag^4;
sbit  IsRstAZero=DispFlag^5;
sbit  IsLCM     =DispFlag^6;
sbit  IsmRFunc  =DispFlag^7;
sbit  SEGA=P3^7;
sbit  SEGB=P3^6;
sbit  SEGC=P3^1;
sbit  SEGD=P3^2;
sbit  SEGE=P3^3;
sbit  SEGF=P1^0;
sbit  SEGG=P1^1;
sbit  SEGDP=P3^0;
sbit  VDIG4=P3^5;
sbit  VDIG3=P1^5;
sbit  VDIG2=P1^4;
sbit  VDIG1=P1^6;
sbit  ADIG4=P3^4;
sbit  ADIG3=P1^3;
sbit  ADIG2=P1^7;
sbit  ADIG1=P5^4;
uchar code SEGTAB[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71};
uchar code CHARTAB[16]="0123456789ABCDEF";
uchar code EEROM[16] _at_ 0x2000;
uchar BCD2SEG(uchar bcddat)
{
return(SEGTAB[bcddat & 0x0f]);
}
uchar BIN2CHAR(uchar bindat)
{
return(CHARTAB[bindat & 0x0f]);
}
void TurnoffDIG()
{
  VDIG1=1;
  VDIG2=1;
  VDIG3=1;
  VDIG4=1;
  ADIG1=1;
  ADIG2=1;
  ADIG3=1;
  ADIG4=1;
}
void TurnoffSEG()
{
  SEGA=0;
  SEGB=0;
  if(scantick<64) SEGC=1; else SEGC=0;
  SEGD=0;
  SEGE=0;
  SEGF=0;
  SEGG=0;
  SEGDP=0;
}
void delay100us()
{     
      TR1 =0;      //0xffff-0xff38=200*0.5us=0.1ms
          TH1 =0xff;   
          TL1 =0x38;      
          TF1 =0;
      TR1 =1;
          while(~TF1){};
      TF1 =0;
      TR1 =0;  
}
void waken200us()
{     
      TR1  =0;      //0xffff-0xfe70=400*0.5us=200us
          TH1  =0xfe;   
          TL1  =0x70;      
          TF1 =0;
          //ET1 =1;
      TR1 =1;
          //PCON=0x01;
          while(~TF1){};
      TF1 =0;
          ET1 =0;
      TR1 =0;
}
void SelectRef(uchar Channel)
{
        //REF    x    x      x        2K       2K2  2K2  2K2  2K2
    //P3  :SEGA-SEGB-  VDIG4-   ADIG4-----SEGE-SEGD-SEGC-SEGDP   准双向口  推挽输出  高阻输入  开漏输出
        //P3M0:  1    1      1       1/0      1/0  1/0  1/0  1/0        0         1         0         1
    //P3M1:  0    0      0       0/1      0/1  0/1  0/1  0/1        0         0         1         1
switch(Channel)                                                   //  2k5
    {case chRefV4400:             //-----S  S  D 2k1 2k2 2k2 2k2 2k2   5000  P1=0xfc;P54=1;
              P3=0x3f;                //P3:  0  0  1  1   1   1   1   1
                  P3M0=0xff;P3M1=0x00;    //P3M0:1  1  1  1   1   1   1   1
                                          //P3M1:0  0  0  0   0   0   0   0
              break;      
     case chRefV3570:             //-----S  S  D 2k1 2k2 2k2 2k2 2k2   3892  P1=0xfc;P54=1;
              P3=0x3e;                //P3:  0  0  1  1   1   1   1   0
                  P3M0=0xff;P3M1=0x00;    //P3M0:1  1  1  1   1   1   1   1
                                          //P3M1:0  0  0  0   0   0   0   0
              break;               
     case chRefV2750:             //-----S  S  D 2k1 2k2 2k2 2k2 2k2   3112  P1=0xfc;P54=1;
              P3=0x3c;                //P3:  0  0  1  1   1   1   0   0
                  P3M0=0xff;P3M1=0x03;    //P3M0:1  1  1  1   1   1   1   1
                                          //P3M1:0  0  0  0   0   0   1   1
              break;                  
     case chRefV2350:             //-----S  S  D 2k1 2k2 2k2 2k2 2k2   2556  P1=0xfc;P54=1;
              LDO3V3:
              P3=0x3c;                //P3:  0  0  1  1   1   z   0   0
                  P3M0=0xfb;P3M1=0x07;          //P3M0:1  1  1  1   1   0   1   1
                                          //P3M1:0  0  0  0   0   1   1   1
              break;                                  
     case chRefV1730:             //-----S  S  D 2k1 2k2 2k2 2k2 2k2   1982  P1=0xfc;P54=1;
              if(LDOIs3V3) goto LDO3V3;
                  LDO_3V6:
              P3=0x3c;                //P3:  0  0  1  1   z   z   0   0
                  P3M0=0xf3;P3M1=0x0f;          //P3M0:1  1  1  1   0   0   1   1
                                          //P3M1:0  0  0  0   1   1   1   1
              break;                                                                    
     case chRefV1340:
          if(LDOIs3V3)      
            {                        //-----S  S  D 2k1/2k5 2k2 2k2 2k2 2k2   1333  P1=0xfc;P54=1;
                 P3=0x38;                //P3:  0  0  1    1     1   0   0   0
                     P3M0=0xff;P3M1=0x07;    //P3M0:1  1  1    1     1   1   1   1
                                             //P3M1:0  0  0    0     0   1   1   1
            } else {                        //-----S  S  D 2k1 2k2 2k2 2k2 2k2   1333  P1=0xfc;P54=1;
                        P3=0x38;                //P3:  0  0  1  1   z   0   0   0
                            P3M0=0xf7;P3M1=0x0f;    //P3M0:1  1  1  1   0   1   1   1
                                                    //P3M1:0  0  0  0   1   1   1   1
                   }
          if(LDOIs3V6) goto LDO_3V6;
                  if(LDOIs5V)
             {                       //-----S  S  D 2k1 2k68 2k68 2k68 2k68   1333  P1=0xfc;P54=1;
                  P3=0x30;               //P3:  0  0  1  1   0    0    0    0
                      P3M0=0xff;P3M1=0x0f;   //P3M0:1  1  1  1   1    1    1    1
                                             //P3M1:0  0  0  0   1    1    1    1
             }
              break;                                  
     case chRefVA620:            
              if(UseOldRef)
                {                     //-----S  S  D 2k5 2k2 2k2 2k2 2k2   515  P1=0xfc;P54=1;
                 P3=0x30;             //P3:  0  0  1  1   0   0   0   0
             P3M0=0xff;P3M1=0x1f; //P3M0:1  1  1  1   1   1   1   1
             P3PU=0x10;           //P3M1:0  0  0  1   1   1   1   1
                        } else {                     //-----S  S  D 2k1 2k2 2k2 2k2 2k2   515  P1=0xfc;P54=1;
                        P3=0x2f;             //P3:  0  0  1  0   z   z   z   z
                    P3M0=0xf0;P3M1=0x0f; //P3M0:1  1  1  1   0   0   0   0
                                         //P3M1:0  0  0  0   1   1   1   1
                                   }
              break;          
    if(UseOldRef)
     {
     case chRefV2K2A:             //-----S  S  D 2k5 2k2 2k2 2k2 2k2  P1=0xfc;P54=1;
              P3=0x30;                //P3:  0  0  1  1   z   z   z   0   
                  P3M0=0xf1;P3M1=0x1f;    //P3M0:1  1  1  1   0   0   0   1
                  P3PU=0x10;              //P3M1:0  0  0  1   1   1   1   1
              break;
     case chRefV2K2B:             //-----S  S  D 2k5 2k2 2k2 2k2 2k2  P1=0xfc;P54=1;
              P3=0x30;                //P3:  0  0  1  1   z   z   0   z   
                  P3M0=0xf2;P3M1=0x1f;    //P3M0:1  1  1  1   0   0   1   0
                  P3PU=0x10;              //P3M1:0  0  0  1   1   1   1   1
              break;
     case chRefV2K2C:             //-----S  S  D 2k5 2k2 2k2 2k2 2k2  P1=0xfc;P54=1;
              P3=0x30;                //P3:  0  0  1  1   z   0   z   z   
                  P3M0=0xf4;P3M1=0x1f;    //P3M0:1  1  1  1   0   1   0   0
                  P3PU=0x10;              //P3M1:0  0  0  1   1   1   1   1
              break;
     case chRefV2K2D:             //-----S  S  D 3k9 2k2 2k2 2k2 2k2  P1=0xfc;P54=1;
              P3=0x30;                //P3:  0  0  1  1   0   z   z   z   
                  P3M0=0xf8;P3M1=0x1f;    //P3M0:1  1  1  1   1   0   0   0
                  P3PU=0x10;              //P3M1:0  0  0  1   1   1   1   1
              break;
     }
     default:;
   }
}
#define     MD3U16                  (*(unsigned int volatile xdata *)0xfcf0)  
//#define     MD2                     (*(unsigned char volatile xdata *)0xfcf1)
#define     MD1U16                  (*(unsigned int volatile xdata *)0xfcf2)
//#define     MD0                     (*(unsigned char volatile xdata *)0xfcf3)
#define     MD5U16                  (*(unsigned int volatile xdata *)0xfcf4)
//#define     MD4                     (*(unsigned char volatile xdata *)0xfcf5)
//32位除法  被除数:MD3U16:MD1U16 除数:MD5U16  商:MD3U16:MD1U16      余数:MD5U16
//16位除法  被除数:MD1U16        除数:MD5U16  商:MD1U16             余数:MD5U16
//16位乘法  被乘数:MD1U16        乘数:MD5U16  积:MD3U16:MD1U16
void LoadCurrent()
{
    //P1  :ADIG2-VDIG1-VDIG3-VDIG2-------ADIG3-  NU-SEGG/Current-SEGF/Volt                准双向口  推挽输出  高阻输入  开漏输出
        //P1M0:  1     1     1     1          1      1      1/0        1/0      0xff/0xfc         0         1         0         1  
    //P1M1:  0     0     0     0          0      0      0/1        0/1      0x00/0x03         0         0         1         1
    P_SW2|=0x80;       //使能访问XSFR
    //P1M0  =0xff;       //设置P1.1为ADC口:ADC1:current;ADC0:Volt  1 1 1 1  1 1 0 1
    //P1M1  =0x00;       //                                          0 0 0 0  0 0 1 0
        //SEGG=0;
        ADC_CONTR=0x81;    //使能ADC模块,并选择ADC1
        ADCTIM=0x27;       //设置ADC内部时序:1+2+16  0-0-1---0-1-1-1-1
    ADCCFG=0x27;       //设置ADC时钟为系统时钟/2/2,转换结果右对齐--ADCCFG:x-x-RESFMT-x-S3-S2-S1-S0 Fadc=SYSCLK/2/(SPEED+1)
    ADCEXCFG =0x05;    //设置ADC转换4次并取平均值:(1+2+16+12)*10*2=620*16=410us  ADCEXCFG:x-x-0-0-0--1-0-0
    //ADCEXCFG =0x06;  //设置ADC转换8次并取平均值:(1+2+32+12)*32*8=12000=500us  ADCEXCFG:x-x-0-0-0--1-0-0
        ADC_CONTR|=0x40;   //启动AD转换
        adccnt=4;
        if(EADC) PCON=0x01;
          else {while(!(ADC_CONTR & 0x20));//查询ADC完成标记                 
                ADC_CONTR=0x81;            //清除ADC完成标记
           }
    P1M0  =0xfd;       //设置P1.1为ADC口:ADC1:current;ADC0:Volt  1 1 1 1  1 1 0 1
    P1M1  =0x02;       //                                          0 0 0 0  0 0 1 0
        //delay100us();
    //delay100us();
        //if(AVmeterUseHIC) delay100us();
        if(UseIdleMode) waken200us();
          else {delay100us();delay100us();}
    Abuf=0;
        while(adccnt--)
      {ADC_CONTR|=0x40;                  //启动AD转换
           F0=0;
           if(EADC) PCON=0x01;
             else {while(!(ADC_CONTR & 0x20));       //查询ADC完成标记                 
                   ADC_CONTR=0x81;                   //清除ADC完成标记
                          }
           Abuf+=(ADC_RES<<8)| ADC_RESL;     //读取ADC结果
           }
   Abuf>>=2;
   ADC_CONTR=0x8f;
}
void LoadVolt()
{
    P_SW2|=0x80;       //使能访问XSFR
    //P1M0  =0xfe;       //设置P1.0为ADC口:ADC0:Volt  1 1 1 1   1 1 1 0
    //P1M1  =0x01;       //                            0 0 0 0   0 0 0 1
        ADC_CONTR=0x80;    //使能ADC模块,并选择ADC0---ADC_PWR--ADC_START--ADC_FLAG--ADC_EPWMT-------ADCCHS3..0
        ADCTIM=0x27;       //设置ADC内部时序:1+2+32  0-0-1---0-1-1-1-1
    ADCCFG=0x27;       //设置ADC时钟为系统时钟/2/16,转换结果右对齐--ADCCFG:x-x-RESFMT-x-S3-S2-S1-S0 Fadc=SYSCLK/2/(SPEED+1)
    ADCEXCFG=0x05;     //设置ADC转换4次并取平均值:(1+2+32+12)*32*2=12000=500us
    //ADCEXCFG =0x06;  //设置ADC转换8次并取平均值:(1+2+32+12)*32*16=24000=1000us
    ADC_CONTR|=0x40;   //启动AD转换
        adccnt=4;
        if(EADC) PCON=0x01;
          else {while(!(ADC_CONTR & 0x20));//查询ADC完成标记                 
                ADC_CONTR=0x80;            //清除ADC完成标记
                   }
    P1M0  =0xfe;       //设置P1.0为ADC口:ADC0:Volt  1 1 1 1   1 1 1 0
    P1M1  =0x01;       //  
        if(UseIdleMode) waken200us();
          else {delay100us();delay100us();}
    Vbuf=0;
        while(adccnt--)
      {ADC_CONTR|=0x40;                  //启动AD转换
           F0=0;
                   if(EADC) PCON=0x01;
              else {while(!(ADC_CONTR & 0x20));       //查询ADC完成标记                 
                    ADC_CONTR=0x80;                   //清除ADC完成标记
                           }
           Vbuf+=(ADC_RES<<8)| ADC_RESL;     //读取ADC结果
           }
   Vbuf>>=2;   
   ADC_CONTR=0x8f;
}
void LoadBGVolt()
{
    P_SW2|=0x80;       //使能访问XSFR
        ADC_CONTR=0x8f;    //使能ADC模块,并选择ADC15
        ADCTIM=0x3f;       //设置ADC内部时序:1+2+32
    ADCCFG=0x2f;       //设置ADC时钟为系统时钟/2/16,转换结果右对齐:000000bb,bbbbbbbb
    ADCEXCFG=0x06;     //设置ADC转换8次并取平均值:(1+2+32+12)*32*4=24000=1000us
    ADC_CONTR|=0x40;                  //启动AD转换
        F0=0;
        if(EADC) PCON=0x01;
          else {while(!(ADC_CONTR & 0x20));       //查询ADC完成标记                 
            ADC_CONTR=0x8f;                   //清除ADC完成标记
                   }
        BGVbuf=(ADC_RES<<8)| ADC_RESL;    //读取ADC结果
}
//[V]n[:]vvvvv[0x0A]--8
//[A]n[:]aaaaa[0x0A]--8
//[R]n[:]rrrrr[0x0A]--8
//[E]n[:]eeeeeeee[0x0A]--11:密钥,n=3:3led; n=4:4led; n=5:5led volt meter;
//E1:sharemod[0x0A]--3led share mode
//Vchar[8],Achar[8],Rchar[8],Echar[11];
void InitTxBuf()
{
  //Vchar[0]='V';
  Vchar[1]='0';
  //Vchar[2]=':';
  Vchar[3]='0';
  Vchar[4]='.';
  Vchar[5]='0';
  Vchar[6]='0';
  Vchar[7]='0';
  //Achar[0]='A';
  Achar[1]='0';
  //Achar[2]=':';
  Achar[3]='0';
  Achar[4]='.';
  Achar[5]='0';
  Achar[6]='0';
  Achar[7]='0';
  //Rchar[0]='R';
  Rchar[1]='0';
  //Rchar[2]=':';
  Rchar[3]='0';
  Rchar[4]='.';
  Rchar[5]='0';
  Rchar[6]='0';
  Rchar[7]='0';
  //Echar[0]='E';
  //if(ThreeLEDVer) Echar[1]='3';else Echar[1]='4';
  //Echar[2]=':';
}
void TxCharBuf()
{
  if(IsRerr) {scantick+=0x40;scantick&=0xc0;return;}
  SEGD=SEGE=SEGDP=1;
  segnum++;
  TI=0;
  switch(scantick)
  {
    case 0x00:break;
    case 0x01:SBUF=0x0a;break;
    case 0x02:SBUF='E';break;
    case 0x03:if(ThreeLEDVer) SBUF='3';else SBUF='4';break;//SBUF=Echar[1];
    case 0x04:SBUF=':';break;
    case 0x05:SBUF=Echar[3];break;
    case 0x06:SBUF=Echar[4];break;
    case 0x07:SBUF=Echar[5];break;
    case 0x08:SBUF=Echar[6];break;
    case 0x09:SBUF=Echar[7];break;
    case 0x0a:SBUF=Echar[8];break;
    case 0x0b:SBUF=Echar[9];break;
    case 0x0c:SBUF=Echar[10];break;
    case 0x0d:SBUF=0x0a;break;
    case 0x0e:SBUF='V';break;
    case 0x0f:SBUF=Vchar[1];break;
    case 0x10:SBUF=':';break;
    case 0x11:SBUF=Vchar[3];break;
    case 0x12:SBUF=Vchar[4];break;
    case 0x13:SBUF=Vchar[5];break;
    case 0x14:SBUF=Vchar[6];break;
    case 0x15:SBUF=Vchar[7];break;
    case 0x16:SBUF=0x0a;break;
    case 0x17:SBUF='A';break;
    case 0x18:SBUF=Achar[1];break;
    case 0x19:SBUF=':';break;
    case 0x1a:SBUF=Achar[3];break;
    case 0x1b:SBUF=Achar[4];break;
    case 0x1c:SBUF=Achar[5];break;
    case 0x1d:SBUF=Achar[6];;break;//
    case 0x1e:SBUF=Achar[7];break;
    case 0x1f:SBUF=0x0a;break;
    case 0x20:SBUF='R';break;
    case 0x21:SBUF=Rchar[1];break;
    case 0x22:SBUF=':';break;
    case 0x23:SBUF=Rchar[3];break;
    case 0x24:SBUF=Rchar[4];break;
    case 0x25:SBUF=Rchar[5];break;
    case 0x26:SBUF=Rchar[6];break;
    case 0x27:SBUF=Rchar[7];break;
    case 0x28:SBUF=0x0a;break;
        case 0x29:SBUF='C';break;
        case 0x2a:SBUF='I';break;
        case 0x2b:SBUF='D';break;
        case 0x2c:SBUF=':';break;
        case 0x2d:SBUF=CHARTAB[CHIPID0>>4];break;
        case 0x2e:SBUF=CHARTAB[CHIPID0&0x0f];break;
        case 0x2f:SBUF=CHARTAB[CHIPID1>>4];break;  
        case 0x30:SBUF=CHARTAB[CHIPID1&0x0f];break;
        case 0x31:SBUF=CHARTAB[CHIPID2>>4];break;  
        case 0x32:SBUF=CHARTAB[CHIPID2&0x0f];break;
        case 0x33:SBUF=CHARTAB[CHIPID3>>4];break;  
        case 0x34:SBUF=CHARTAB[CHIPID3&0x0f];break;
        case 0x35:SBUF=CHARTAB[CHIPID4>>4];break;  
        case 0x36:SBUF=CHARTAB[CHIPID4&0x0f];break;
        case 0x37:SBUF=CHARTAB[CHIPID5>>4];break;  
        case 0x38:SBUF=CHARTAB[CHIPID5&0x0f];break;
        case 0x39:SBUF=CHARTAB[CHIPID6>>4];break;  
        case 0x3a:SBUF=CHARTAB[CHIPID6&0x0f];break;
        case 0x3b:if(ShowEEROM) SBUF=CHARTAB[EEROM[0]>>4];else SBUF=CHARTAB[CHIPID7>>4];break;  
        case 0x3c:if(ShowEEROM) SBUF=CHARTAB[EEROM[0]&0x0f];else SBUF=CHARTAB[CHIPID7&0x0f];break;   
        case 0x3d:if(ShowEEROM) SBUF=CHARTAB[HwParam.ResZero>>4];else SBUF=CHARTAB[CHIPID8>>4];break;   
        case 0x3e:if(ShowEEROM) SBUF=CHARTAB[HwParam.ResZero&0x0f];else SBUF=CHARTAB[CHIPID8&0x0f];break;   
    case 0x3f:SBUF=0x0a;break;
           default:segnum=0;
  }
}
void scanseg()
{
     if(scantick<64) {TxCharBuf();return;}
     switch(scantick & 0x3f)
         { //VSEG1
           case 0x00:
          if(VSEG1&0x01) {SEGA=1;VDIG1=0;segnum++;}
               break;
       case 0x01:
          if(VSEG1&0x02) {SEGB=1;VDIG1=0;segnum++;}
               break;
       case 0x02:
          if(VSEG1&0x04) {SEGC=1;VDIG1=0;segnum++;}
               break;
           case 0x03:
          if(VSEG1&0x08) {SEGD=1;VDIG1=0;segnum++;}
               break;
       case 0x04:
          if(VSEG1&0x10) {SEGE=1;VDIG1=0;segnum++;}
               break;
           case 0x05:
          if(VSEG1&0x20) {SEGF=1;VDIG1=0;segnum++;}
               break;
           case 0x06:
          if(VSEG1&0x40) {SEGG=1;VDIG1=0;segnum++;}
               break;
       case 0x07:segnum=0x5a;break;
       //VSEG2
       case 0x08:
          if(VSEG2&0x01) {SEGA=1;VDIG2=0;segnum++;}
               break;
       case 0x09:
          if(VSEG2&0x02) {SEGB=1;VDIG2=0;segnum++;}
               break;
       case 0x0a:
          if(VSEG2&0x04) {SEGC=1;VDIG2=0;segnum++;}
               break;
           case 0x0b:
          if(VSEG2&0x08) {SEGD=1;VDIG2=0;segnum++;}
               break;
       case 0x0c:
          if(VSEG2&0x10) {SEGE=1;VDIG2=0;segnum++;}
               break;
           case 0x0d:
          if(VSEG2&0x20) {SEGF=1;VDIG2=0;segnum++;}
               break;
           case 0x0e:
          if(VSEG2&0x40) {SEGG=1;VDIG2=0;segnum++;}
               break;
       case 0x0f:
          if(VSEG2&0x80) {SEGDP=1;VDIG2=0;segnum++;}
               break;
       //VSEG3
       case 0x10:
          if(VSEG3&0x01) {SEGA=1;VDIG3=0;segnum++;}
               break;
       case 0x11:
          if(VSEG3&0x02) {SEGB=1;VDIG3=0;segnum++;}
               break;
       case 0x12:
          if(VSEG3&0x04) {SEGC=1;VDIG3=0;segnum++;}
               break;
           case 0x13:
          if(VSEG3&0x08) {SEGD=1;VDIG3=0;segnum++;}
               break;
       case 0x14:
          if(VSEG3&0x10) {SEGE=1;VDIG3=0;segnum++;}
               break;
           case 0x15:
          if(VSEG3&0x20) {SEGF=1;VDIG3=0;segnum++;}
               break;
           case 0x16:
          if(VSEG3&0x40) {SEGG=1;VDIG3=0;segnum++;}
               break;
       case 0x17:
          if(VSEG3&0x80) {SEGDP=1;VDIG3=0;segnum++;}
               break;
       //VSEG4
       case 0x18:
          if(VSEG4&0x01) {SEGA=1;VDIG4=0;segnum++;}
               break;
       case 0x19:
          if(VSEG4&0x02) {SEGB=1;VDIG4=0;segnum++;}
               break;
       case 0x1a:
          if(VSEG4&0x04) {SEGC=1;VDIG4=0;segnum++;}
               break;
           case 0x1b:
          if(VSEG4&0x08) {SEGD=1;VDIG4=0;segnum++;}
               break;
       case 0x1c:
          if(VSEG4&0x10) {SEGE=1;VDIG4=0;segnum++;}
               break;
           case 0x1d:
          if(VSEG4&0x20) {SEGF=1;VDIG4=0;segnum++;}
               break;
           case 0x1e:
          if(VSEG4&0x40) {SEGG=1;VDIG4=0;segnum++;}
               break;
       case 0x1f:
          if(VSEG4&0x80) {SEGDP=1;VDIG4=0;segnum++;}
               break;
       //ASEG1
           case 0x20:
          if(ASEG1&0x01) {SEGA=1;ADIG1=0;segnum++;}
               break;
       case 0x21:
          if(ASEG1&0x02) {SEGB=1;ADIG1=0;segnum++;}
               break;
       case 0x22:
          if(ASEG1&0x04) {SEGC=1;ADIG1=0;segnum++;}
               break;
           case 0x23:
          if(ASEG1&0x08) {SEGD=1;ADIG1=0;segnum++;}
               break;
       case 0x24:
          if(ASEG1&0x10) {SEGE=1;ADIG1=0;segnum++;}
               break;
           case 0x25:
          if(ASEG1&0x20) {SEGF=1;ADIG1=0;segnum++;}
               break;
           case 0x26:
          if(ASEG1&0x40) {SEGG=1;ADIG1=0;segnum++;}
               break;
       case 0x27:segnum=0x5a;break;
       //ASEG2
       case 0x28:
          if(ASEG2&0x01) {SEGA=1;ADIG2=0;segnum++;}
               break;
       case 0x29:
          if(ASEG2&0x02) {SEGB=1;ADIG2=0;segnum++;}
               break;
       case 0x2a:
          if(ASEG2&0x04) {SEGC=1;ADIG2=0;segnum++;}
               break;
           case 0x2b:
          if(ASEG2&0x08) {SEGD=1;ADIG2=0;segnum++;}
               break;
       case 0x2c:
          if(ASEG2&0x10) {SEGE=1;ADIG2=0;segnum++;}
               break;
           case 0x2d:
          if(ASEG2&0x20) {SEGF=1;ADIG2=0;segnum++;}
               break;
           case 0x2e:
          if(ASEG2&0x40) {SEGG=1;ADIG2=0;segnum++;}
               break;
       case 0x2f:
          if(ASEG2&0x80) {SEGDP=1;ADIG2=0;segnum++;}
               break;
       //ASEG3
       case 0x30:
          if(ASEG3&0x01) {SEGA=1;ADIG3=0;segnum++;}
               break;
       case 0x31:
          if(ASEG3&0x02) {SEGB=1;ADIG3=0;segnum++;}
               break;
       case 0x32:
          if(ASEG3&0x04) {SEGC=1;ADIG3=0;segnum++;}
               break;
           case 0x33:
          if(ASEG3&0x08) {SEGD=1;ADIG3=0;segnum++;}
               break;
       case 0x34:
          if(ASEG3&0x10) {SEGE=1;ADIG3=0;segnum++;}
               break;
           case 0x35:
          if(ASEG3&0x20) {SEGF=1;ADIG3=0;segnum++;}
               break;
           case 0x36:
          if(ASEG3&0x40) {SEGG=1;ADIG3=0;segnum++;}
               break;
       case 0x37:
          if(ASEG3&0x80) {SEGDP=1;ADIG3=0;segnum++;}
               break;
       //ASEG4
       case 0x38:
          if(ASEG4&0x01) {SEGA=1;ADIG4=0;segnum++;}
               break;
       case 0x39:
          if(ASEG4&0x02) {SEGB=1;ADIG4=0;segnum++;}
               break;
       case 0x3a:
          if(ASEG4&0x04) {SEGC=1;ADIG4=0;segnum++;}
               break;
           case 0x3b:
          if(ASEG4&0x08) {SEGD=1;ADIG4=0;segnum++;}
               break;
       case 0x3c:
          if(ASEG4&0x10) {SEGE=1;ADIG4=0;segnum++;}
               break;
           case 0x3d:
          if(ASEG4&0x20) {SEGF=1;ADIG4=0;segnum++;}
               break;
           case 0x3e:
          if(ASEG4&0x40) {SEGG=1;ADIG4=0;segnum++;}
               break;
       case 0x3f:
          if(ASEG4&0x80) {SEGDP=1;ADIG4=0;segnum++;}
               break;
                    default:;
     }
if(~IsSaveEEROM)
   if(~IsIAPflash){ADIG4=ADIG3=ADIG2=ADIG1=1;}
if(ThreeLEDVer) ADIG1=VDIG1=1;
}
void FormatBCDbuf()
{   
    if(BCDbuf<10) return;
    MD1U16=BCDbuf;
    MD5U16=1000;
        ARCON=5<<5;                       //4:16*16位; 5:16/16位 6:32/16位
        OPCON=0x01;                       //启动计算
        while(OPCON&0x01!=0);             //等待计算完成
    BCDbuf=MD0;
    MD1U16=MD5U16;
    MD5U16=100;
        ARCON=5<<5;                       //4:16*16位; 5:16/16位 6:32/16位
        OPCON=0x01;                       //启动计算
        while(OPCON&0x01!=0);             //等待计算完成
    BCDbuf=(BCDbuf<<4)| MD0;
    MD1U16=MD5U16;
    MD5U16=10;
        ARCON=5<<5;                       //4:16*16位; 5:16/16位 6:32/16位
        OPCON=0x01;                       //启动计算
        while(OPCON&0x01!=0);             //等待计算完成
    BCDbuf=(BCDbuf<<4)| MD0;
    BCDbuf=(BCDbuf<<4)| MD4;      
}
void VMulRef()//BCDbuf=2238*RefValue/1000*Vbuf/BGVbuf; 75v-105v
{   
    MD1U16=eRefValue;
    MD5U16=HwParam.VoltDivider;//22.38
        ARCON=4<<5;                       //4:16*16位; 5:16/16位 6:32/16位----16位乘法  被乘数:MD1U16 乘数:MD5U16  积:MD3U16:MD1U16
        OPCON=0x01;                       //启动计算
        while(OPCON&0x01!=0);             //等待计算完成
    MD5U16=1000;
    ARCON=6<<5;                       //6:32/16位:MD3U16:MD1U16/MD5U16
        OPCON=0x01;                       //启动计算
        while(OPCON&0x01!=0);             //等待计算完成
    MD5U16=Vbuf;
        ARCON=4<<5;                       //4:16*16位; 5:16/16位 6:32/16位----16位乘法  被乘数:MD1U16 乘数:MD5U16  积:MD3U16:MD1U16
        OPCON=0x01;                       //启动计算
        while(OPCON&0x01!=0);             //等待计算完成
    MD5U16=BGVbuf;
    ARCON=6<<5;                       //6:32/16位:MD3U16:MD1U16/MD5U16
        OPCON=0x01;                       //启动计算
        while(OPCON&0x01!=0);             //等待计算完成
    BCDbuf=MD1U16;
}
void AMulDig()
{   if(AVmeterUseHIC)
      {MD1U16=Abuf;
       MD5U16=constARANGE/constHICFullADC*1000;   //5000/1478=33.83 3383; HICPerDigi=ARANGE/1478.0*1000;
           ARCON=4<<5;                       //4:16*16位; 5:16/16位 6:32/16位----16位乘法  被乘数:MD1U16 乘数:MD5U16  积:MD3U16:MD1U16
           OPCON=0x01;                       //启动计算
           while(OPCON&0x01!=0);             //等待计算完成
       MD5U16=1000;
       ARCON=6<<5;                       //6:32/16位:MD3U16:MD1U16/MD5U16
           OPCON=0x01;                       //启动计算
           while(OPCON&0x01!=0);             //等待计算完成
       //BCDbuf=MD1U16;                    
           } else {MD1U16=Abuf;
               MD5U16=AMPerDigi;                 //
                   ARCON=4<<5;                       //4:16*16位; 5:16/16位 6:32/16位----16位乘法  被乘数:MD1U16 乘数:MD5U16  积:MD3U16:MD1U16
                   OPCON=0x01;                       //启动计算
                   while(OPCON&0x01!=0);             //等待计算完成
               MD5U16=100;
               ARCON=6<<5;                       //6:32/16位:MD3U16:MD1U16/MD5U16
                   OPCON=0x01;                       //启动计算
                   while(OPCON&0x01!=0);             //等待计算完成
               //BCDbuf=MD1U16;
                           }
       MD5U16=HwParam.AFineTurn;         //BCDbuf=BCDbuf*AFineTurn/10000
           ARCON=4<<5;                       //4:16*16位; 5:16/16位 6:32/16位----16位乘法  被乘数:MD1U16 乘数:MD5U16  积:MD3U16:MD1U16
           OPCON=0x01;                       //启动计算
           while(OPCON&0x01!=0);             //等待计算完成  BCDbuf=BCDbuf*AFineTurn
       MD5U16=10000;
       ARCON=6<<5;                       //6:32/16位:MD3U16:MD1U16/MD5U16
           OPCON=0x01;                       //启动计算
           while(OPCON&0x01!=0);             //等待计算完成
       BCDbuf=MD1U16;
}
void BCDbufDiv10()
{   
    MD1U16=BCDbuf;
    MD5U16=10;
    ARCON=5<<5;                       //5:16/16位:MD1U16/MD5U16
        OPCON=0x01;                       //启动计算
        while(OPCON&0x01!=0);             //等待计算完成
    BCDbuf=MD1U16;
}
void Flashoff()
{
        ADIG4 =1;
        SEGC  =0;
    SEGD  =0;
    SEGE  =0;  
    SEGDP =0;
}
void GetChnVolt(uchar RefChannal)
{
    SelectRef(RefChannal);
    //delay100us();
        //delay100us();
    if(UseIdleMode) waken200us();
          else {delay100us();delay100us();}
        LoadBGVolt();
        Flashoff();
    MD1U16=eRefValue;                 //Vccbuf=4096*RefValue/BGVbuf
    MD5U16=4096;
        ARCON=4<<5;                       //4:16*16位; 5:16/16位 6:32/16位----16位乘法  被乘数:MD1U16 乘数:MD5U16  积:MD3U16:MD1U16
        OPCON=0x01;                       //启动计算
        while(OPCON&0x01!=0);             //等待计算完成
    MD5U16=BGVbuf;
    ARCON=6<<5;                       //6:32/16位:MD3U16:MD1U16/MD5U16
        OPCON=0x01;                       //启动计算
        while(OPCON&0x01!=0);             //等待计算完成
    //Vbuf=MD1U16;
}
void CalcChnADC()
{
    //MD1U16=ADCVoltvvvv;               //Vccbuf=4096*RefValue/BGVbuf
    MD5U16=4096;
        ARCON=4<<5;                       //4:16*16位; 5:16/16位 6:32/16位----16位乘法  被乘数:MD1U16 乘数:MD5U16  积:MD3U16:MD1U16
        OPCON=0x01;                       //启动计算
        while(OPCON&0x01!=0);             //等待计算完成
    MD5U16=VccVolt;
    ARCON=6<<5;                       //6:32/16位:MD3U16:MD1U16/MD5U16
        OPCON=0x01;                       //启动计算
    while(OPCON&0x01!=0);             //等待计算完成
}
void LoadEEROM()
{
adccnt=10;
while(adccnt--) ParamBuf[adccnt-1]=EEROM[adccnt-1];
if(HwParam.ParamValid!=0x5a)
   {HwParam.ResZero=constADCNoise;
    HwParam.HicZero=2045;
        HwParam.VoltDivider=constVoltDivider;
        HwParam.AFineTurn=constAFineTurn;
    HwParam.VRefineTurn=constVRefineTurn;
        return;
   }
if(HwParam.ResZero>8) HwParam.ResZero=constADCNoise;
if((HwParam.HicZero<2030)|(HwParam.HicZero>2066))
    HwParam.HicZero=2045;
if((HwParam.VoltDivider<2100)|(HwParam.VoltDivider>2300))
   HwParam.VoltDivider=constVoltDivider;
if((HwParam.AFineTurn<8000)|(HwParam.AFineTurn>12000))
   HwParam.AFineTurn=constAFineTurn;
if((HwParam.VRefineTurn<9000)|(HwParam.VRefineTurn>11000))
   HwParam.VRefineTurn=constVRefineTurn;
}
void SaveEEROM()
{
  //Erase Block
  IAP_CONTR=0x80;
  IAP_ADDRH=0x00;
  IAP_ADDRL=0x00;
  IAP_TPS=24;
  IAP_CMD=3;
  IAP_TRIG=0x5a;
  IAP_TRIG=0xa5;
  //Write param
  HwParam.ParamValid=0x5a;
  while(IAP_ADDRL<10)
    {IAP_DATA=ParamBuf[IAP_ADDRL];
     IAP_CMD=2;
     IAP_TRIG=0x5a;
     IAP_TRIG=0xa5;
         IAP_ADDRL++;
        }
  //Disable EEROM
  IAP_CONTR=0;
  IAP_CMD=0;
  IAP_TRIG=0;
  IAP_ADDRH=0x80;
  IAP_ADDRL=0x00;
  IsRstAZero=0;
}
void ResetAZero()  //2030-2066
{
if(AVmeterUseHIC) SelectRef(chRefV4400);
   else SelectRef(chRefVA620);
Vbuf=0;
segnum=16;
while(segnum--)
   {LoadCurrent();
    Vbuf+=Abuf;
   }
Vbuf=Vbuf>>4;
if(AVmeterUseHIC) {if((Vbuf>2030)&(Vbuf<2066)) {HwParam.HicZero=Vbuf;HwParam.ResZero=constADCNoise;IAPTick=0;IsRstAZero=1;}}
   else {if(Vbuf<8) HwParam.ResZero=Vbuf;IAPTick=0;IsRstAZero=1;}
}
void Timer0_Routine(void) interrupt 1
{
}
void Timer1_Routine(void) interrupt 3  
{
}
void ADC_Routine(void) interrupt 5
{
ADC_CONTR&=0xdf;
}
void main()
{
    //P1  :ADIG2-VDIG1-VDIG3-VDIG2-------ADIG3-  NU-SEGG/Current-SEGF/Volt
        //P1M0:  1     1     1     1          1      1      1/0        1/0      0xff/0xfc   
    //P1M1:  0     0     0     0          0      0      0/1        0/1      0x00/0x03   
        //REF    x    x      x        R        R    R    R    R
    //P3  :SEGA-SEGB-  VDIG4-   ADIG4-----SEGE-SEGD-SEGC-SEGDP   LED /RefV50-RefVA-RefV26-RefV18-RefV14-RefV11
        //P3M0:  1    1     1         1/0      1/0  1/0  1/0  1/0    0xff/0xe0  -0xf0 -0xe8  -0xec  -0xee  -0xef     
    //P3M1:  0    0     0         0/1      0/1  0/1  0/1  0/1    0x00/0x1f  -0x1f -0x17  -0x13  -0x11  -0x10
    //P5  :x-x-x-ADIG1  x-x-x-x
        //P3M0:1 1 1  1     1 1 1 1                                0xff
    //P3M1:0 0 0  0     0 0 0 0                                0x00
    //Flashoff();
        P_SW1 =0x00;      //RXD/P3.0,TXD/P3.1
    P_SW2|=0x80;      //使能访问XSFR
    TMOD  =0x00;      //T0 mode=0:16bit reload
        TH0   =0xff;      //65536-24Mhz/12/1000
        TL0   =0x38;      //0xffff-0xff38=200*0.5us=0.1ms
        TR0   =1;
    P1M0  =0xff;
    P1M1  =0x00;
        P1DR  =0xff;      //增强驱动能力
    P3M0  =0xff;
    P3M1  =0x00;
    P3DR  =0xff;      //增强驱动能力
    P5M0  =0xff;
    P5M1  =0x00;
          P5DR  =0xff;      //增强驱动能力
        //IE=0xa2;          //EA-ELVD-EADC-ES----ET1-EX1-ET0-EX0
        //                  //1   0    1   0      0   0   1   0
        //PCON  =IDEL;      //0x01:进入空闲模式
        //PCON  =PD;        //0x02:进入掉电模式
        //WKTCL =0xff;      //设定掉电唤醒时钟约为1秒
        //WKTCH =0x87;
        //PCON  =0x02;      //进入掉电模式
        SCON  =0x40;        //SM0-SM1-SM2-REN----TB8-RB8-TI-RI
                            // 0   1   0   0      0   0   0  0
        T2L   =0xcc;        //65536-24000000/115200bps/4=0xffcc  
        T2H   =0xff;        //65536-24000000/57600bps/4=0xff98
        AUXR  =0x15;        //T0x12-T1x12-UART_M0x6-T2R-----T2_C/T-T2x12-EXTRAM-S1ST2  启动定时器,选择T2为波特率发生器  
                            //  0     0      0       1         0     1     0      1
        InitTxBuf();
        LoadEEROM();        //init param
        GetChnVolt(chRefV4400);
        if(HwParam.ParamValid!=0x5a) ResetAZero();
    P3M0  =0xff;
    P3M1  =0x00;
        TurnoffSEG();
        TurnoffDIG();
        SEGC=0;
        if(CheckChipID)
          {UIDbuf[0]=UID0;
           UIDbuf[1]=UID1;
           UIDbuf[2]=UID2;
           UIDbuf[3]=UID3;
           UIDbuf[4]=UID4;
           UIDbuf[5]=UID5;
           UIDbuf[6]=UID6;
      }
        DispFlag  =0x00;
    KeyTick   =0x00;
        CIDTick   =0x00;
        Keybuf    =0xff;
    IAPTick   =0xa0;
        KeyPressTime=0x00;
        PreAbuf  =0x00;
        ADtick   =3000;
        RefVAtick=200;
        //P1  :ADIG2-VDIG1-VDIG3-VDIG2-------ADIG3-  NU-SEGG/Current-SEGF/Volt
    //P1  :ADIG2--up+---down-VDIG2+-------ADIG3-  NU-SEGG/Current-SEGF/Volt       准双向口  推挽输出  高阻输入  开漏输出
        //P1M0:  1     0     0     1           1      1      1        1                  0         1         0         1  
    //P1M1:  0     0     0     0           0      0      0        0                  0         0         1         1
 | 
 |