三国小兵 发表于 2014-8-7 06:56:35

51内核SOC单片机AD采用交流电压

我用SOC芯片单片机做了个5A数显的交流电流表,有1%的误差跳变,要求是0.5%误差,需要多采样几次,做一个平均,能有改善吗
我是直接芯片的库函数        ReadMeterPara(0x10d9); //秒平均电流有效值 ,使用库函数读取的,1.28秒才更新一次的

三国小兵 发表于 2014-8-7 07:16:23

unsigned int Check_time,i;
//unsigned char Check_time;
void main()
{
       
        SetPLL(SETPLL_3_2M);//设置3.2M的MCU时钟,单独调试(F11)此函数会失去调试连接
        SPCFNC = 0X01;
        FlashPw= 0x86;
        SPCFNC = 0X00;       
        EA=1;
        CLRWDT();
        Init_Port();
        CLRWDT();
        CPUInit();
        CLRWDT();
        check_temp();
           CLRWDT();
                for(i=0;i<500;i++)
                {
                        P6OD&=(~BIT1);
                        P6OD&=(~BIT2);
                        P6OD&=(~BIT3);
                        P6OD&=(~BIT4);
                        display_ledb(led_num);       
                }
                CLRWDT();
        while(1)
        {               
                CLRWDT();       
                if(Check_time++>120)
                        {
                        Check_time=0;
                        ReadMeterPara(0x10d9); //秒平均电流有效值                        
                   }
                        dislay_jisuan();
                if(Time_FLAG)
                {
                        Time_FLAG=0;                       
                  display();                                                                       
           }
                //CLRWDT();
                //display_jisuan();
        //        if(guc_RefreshTimeCnt=)
        //        {
        //                ReadMeterPara(0x10d8); //秒平均电压有效值
        //        }
                // display();
        }
                       
}

{
        uchar LEDByte;
        struct
        {
                uchar LED_A                :1;
                uchar LED_B                :1;
                uchar LED_C                :1;
                uchar LED_D                :1;
                uchar LED_E                :1;
                uchar LED_F                :1;
                uchar LED_G                :1;
                uchar LED_H                :1;
        }LEDBits;       
}LEDDisplay;
*/
/*union {
unsigned char LEDByte;//共用体成员
struct{
    unsigned char LED_A   :1;//位域   byte型,占1bit 为了节省内存
    unsigned char LED_B   :1;
    unsigned char LED_C   :1;
    unsigned char LED_D   :1;
    unsigned char LED_E   :1;
    unsigned char LED_F   :1;
    unsigned char LED_G   :1;
    unsigned char LED_H   :1;
} LEDBits;
} LEDDisplay;
*/
//const uchar led_num[]=
//{0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90 };//共阳


//const uchar led_num[]=
//{0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//共阴

union {
unsigned char LEDByte;//共用体成员
struct{
    unsigned char LED_A   :1;//位域   byte型,占1bit 为了节省内存
    unsigned char LED_B   :1;
    unsigned char LED_C   :1;
    unsigned char LED_D   :1;
    unsigned char LED_E   :1;
    unsigned char LED_F   :1;
    unsigned char LED_G   :1;
    unsigned char LED_H   :1;
} LEDBits;
} LEDDisplay;

//const uchar led_num[]=
//{0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90 };//共阳


//const uchar led_num[]=
//{0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x40,0x77,0x71,0x37,0x3e};//共阴

const uchar led_num[]=
{0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x40,0x77,0x71,0x37,0x3e};//共阴
unsigned char led_a,led_b,led_c,led_d;
//unsigned char SegX,SegX1,SegX2,SegX3,SegX4;
unsigned long k,temp;                                                                                                                               
void display_led(unsigned char dara)
{
        LEDDisplay.LEDByte = dara;
        if(LEDDisplay.LEDBits.LED_A)
       P4OD|=(BIT0);
        else
       P4OD&=(~BIT0);
        if(LEDDisplay.LEDBits.LED_B)
       P4OD|=(BIT1);
        else
       P4OD&=(~BIT1);
       if(LEDDisplay.LEDBits.LED_C)
       P4OD|=(BIT2);
        else
       P4OD&=(~BIT2);
       if(LEDDisplay.LEDBits.LED_D)
       P4OD|=(BIT3);
        else
       P4OD&=(~BIT3);
       if(LEDDisplay.LEDBits.LED_E)
       P4OD|=(BIT4);
        else
       P4OD&=(~BIT4);
       if(LEDDisplay.LEDBits.LED_F)
       P4OD|=(BIT5);
        else
       P4OD&=(~BIT5);
       if(LEDDisplay.LEDBits.LED_G)
       P5OD|=(BIT7);
        else
       P5OD&=(~BIT7);
       if(LEDDisplay.LEDBits.LED_H)
       P6OD|=(BIT0);
        else
       P6OD&=(~BIT0);
        delayms(2);
}
void display_clr()
{
        LEDDisplay.LEDByte = 0X00;
        if(LEDDisplay.LEDBits.LED_A)
       P4OD|=(BIT0);
        else
       P4OD&=(~BIT0);
        if(LEDDisplay.LEDBits.LED_B)
       P4OD|=(BIT1);
        else
       P4OD&=(~BIT1);
       if(LEDDisplay.LEDBits.LED_C)
       P4OD|=(BIT2);
        else
       P4OD&=(~BIT2);
       if(LEDDisplay.LEDBits.LED_D)
       P4OD|=(BIT3);
        else
       P4OD&=(~BIT3);
       if(LEDDisplay.LEDBits.LED_E)
       P4OD|=(BIT4);
        else
       P4OD&=(~BIT4);
       if(LEDDisplay.LEDBits.LED_F)
       P4OD|=(BIT5);
        else
       P4OD&=(~BIT5);
       if(LEDDisplay.LEDBits.LED_G)
       P5OD|=(BIT7);
        else
       P5OD&=(~BIT7);
       if(LEDDisplay.LEDBits.LED_H)
       P6OD|=(BIT0);
        else
       P6OD&=(~BIT0);
}
void dislay_jisuan()
{
        //k=0x17F89A16/2012;
               
//        k=0x126DCBCF/100;
        k=0x323B50A5/500;
        if(u32PMdatal<0x004E9E67)
        temp=0;
        else   
        temp=u32PMdatal/k;

//        temp3=temp/8;
//        temp=temp3/k;
        led_d=led_num[(temp/1000)%10];
        led_c=led_num[(temp/100)%10];
        led_b=led_num[(temp/10)%10];
        led_a=led_num;
}
void display_ledb(unsigned char dara)
{
        LEDDisplay.LEDByte = dara;
        if(LEDDisplay.LEDBits.LED_A)
       P4OD|=(BIT0);
        else
       P4OD&=(~BIT0);
        if(LEDDisplay.LEDBits.LED_B)
       P4OD|=(BIT1);
        else
       P4OD&=(~BIT1);
       if(LEDDisplay.LEDBits.LED_C)
       P4OD|=(BIT2);
        else
       P4OD&=(~BIT2);
       if(LEDDisplay.LEDBits.LED_D)
       P4OD|=(BIT3);
        else
       P4OD&=(~BIT3);
       if(LEDDisplay.LEDBits.LED_E)
       P4OD|=(BIT4);
        else
       P4OD&=(~BIT4);
       if(LEDDisplay.LEDBits.LED_F)
       P4OD|=(BIT5);
        else
       P4OD&=(~BIT5);
       if(LEDDisplay.LEDBits.LED_G)
       P5OD|=(BIT7);
        else
       P5OD&=(~BIT7);
       P6OD|=(BIT0);
        delayms(2);
}
void display()
{
       P6OD &= (~BIT1);P6OD |= BIT2;P6OD |= BIT3;P6OD |= BIT4;
        display_led(led_d);                                display_clr();

        P6OD |= BIT1;P6OD &= (~BIT2);P6OD |= BIT3;P6OD |= BIT4;
        display_ledb(led_c);                                display_clr();


        P6OD |= BIT1;P6OD |= BIT2;P6OD &= (~BIT3);P6OD |= BIT4;
        display_led(led_b);      display_clr();

//        P6OD|=(BIT0); delayms(1);

        P6OD |= BIT1;P6OD |= BIT2;P6OD |= BIT3;P6OD &= (~BIT4);       
        display_led(led_a);         display_clr();
}










/*


const uchar led_num[]=
{0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x40,0x77,0x71,0x37,0x3e};//共阴

unsigned char SegX,SegX1,SegX2,SegX3,SegX4;
unsigned long temp1,temp2,temp3;
unsigned char led_a,led_b,led_c,led_d;
unsigned char disp_count,k;
unsigned char current;
unsigned char current_zengyi; //电流增益
//unsigned char check_time;          //检测时间
unsigned char ucSamplingCnt=0;//统计采样的次数                                                                                                                       
/*void display_led(uchar dara)
{
        LEDDisplay.LEDByte = dara;
        P4OD = LEDDisplay.LEDBits.LED_A|(LEDDisplay.LEDBits.LED_B<<1)|(LEDDisplay.LEDBits.LED_C<<2)|(LEDDisplay.LEDBits.LED_D<<3)|(LEDDisplay.LEDBits.LED_E<<4)|(LEDDisplay.LEDBits.LED_F<<5);       
        P5OD = LEDDisplay.LEDBits.LED_G<<7;
        P6OD = LEDDisplay.LEDBits.LED_H;
        delayms(1);
}
void display_clr()
{
        LEDDisplay.LEDByte = 0Xff;
        P4OD = LEDDisplay.LEDBits.LED_A|(LEDDisplay.LEDBits.LED_B<<1)|(LEDDisplay.LEDBits.LED_C<<2)|(LEDDisplay.LEDBits.LED_D<<3)|(LEDDisplay.LEDBits.LED_E<<4)|(LEDDisplay.LEDBits.LED_F<<5);       
//        P5OD = LEDDisplay.LEDBits.LED_G<<7;
        P6OD = LEDDisplay.LEDBits.LED_H;
}
*/
/*
void display_jisuan()
{
//        unsigned char SegX,SegX1,SegX2,SegX3,SegX4;
        unsigned long k,temp;
//        disp_count++;
//        if(disp_count>3)disp_count=0;
//6.4M0x0EC37EA1      
//        3.2M0x184D98E7
//0x17F89A16      
          //3.2M
        k=0x17F89A16/2330;
        temp=u32PMdatal/k;
//        temp3=temp/8;
//        temp=temp3/k;
        SegX4=led_num[(temp/1000)%10];
        SegX3=led_num[(temp/100)%10];
        SegX2=led_num[(temp/10)%10];
        SegX1=led_num;

//       switch(disp_count)
//   {
//   case 0:SegX=SegX1;break;
//   case 1:SegX=SegX2;break;
//   case 2:SegX=SegX3;break;
//   case 3:SegX=SegX4;break;
//   }   
        CLOSE_LED1();
        CLOSE_LED2();
        CLOSE_LED3();
        CLOSE_LED4();
       
        if((SegX&0x01)==0x01)A_ON();
        else
                A_OF();
        if((SegX&0x02)==0x02)B_ON();
       else
             B_OF();

   if((SegX&0x04)==0x04)C_ON();
       else
             C_OF();

   if((SegX&0x08)==0x08)D_ON();
       else
             D_OF();

      if((SegX&0x10)==0x10)E_ON();
       else
             E_OF();
      
          if((SegX&0x20)==0x20)F_ON();
       else
             F_OF();

       if((SegX&0x40)==0x40)G_ON();
       else
          G_OF();

                if((SegX&0x80)==0x80)H_ON();
       else
          H_OF();
//        switch(disp_count)
//        {
//                case 0:OPEN_LED4();break;
//                case 1:OPEN_LED3();H_ON();break;
//                case 2:OPEN_LED2();break;
//                case 3:OPEN_LED1();break;
//        }                       
}
void display_led(void)
{
        CLOSE_LED1();
        CLOSE_LED2();
        CLOSE_LED3();
        CLOSE_LED4();
       disp_count++;
       if(disp_count>3)disp_count=0;
       switch(disp_count)
   {
           case 0:SegX=SegX1;break;
           case 1:SegX=SegX2;break;
           case 2:SegX=SegX3;break;
           case 3:SegX=SegX4;break;
   }   
           CLOSE_LED1();
        CLOSE_LED2();
        CLOSE_LED3();
        CLOSE_LED4();

                OPEN_LED4();
                OPEN_LED3();H_ON();
                OPEN_LED2();
                OPEN_LED1();

}
*/
void check_temp(void)
{
//        unsigned char temp;
//        switch(current_zengyi)           //电流增益值
//        {
//          case 0: temp=SETM_T1;break;
//          case 1: temp=SETM_T2;break;
//          case 2: temp=SETM_T4;break;
//          case 3: temp=SETM_T8;break;
//        }       

        SysCtrl&=0xef;                //开启计量电路时钟        时钟切换控制寄存器
           PMCtrl1=0x72;                  //选择电流通道剂量                  
        PMCtrl3=0x40;
//        SetADC(SETADC_U,SETADC_IT1);              //电压通道,采用1倍增益
        SetADC(SETADC_IA,SETADC_CLOSE);                  //A通道电流关闭
        SetADC(SETADC_IB,SETADC_IT16);                         //B通道电流,采用16倍增益
//        ReadMeterPara(0x10d9); //秒平均电流有效值
}

lcl 发表于 2014-8-7 07:31:26

码哥   上来就程序   晕{:dizzy:}{:dizzy:}

三国小兵 发表于 2014-8-7 08:01:31

显示什么都正常的,就是满量程的时候,是交流5A,有1%的误差,要求0.5%的

三国小兵 发表于 2014-8-7 08:02:21

自己顶顶。。。。。。。。

三国小兵 发表于 2014-8-7 08:20:52

顶起来。。。。。。。。。。。。。。

奮闘ing 发表于 2014-8-7 08:35:01

我也帮顶~

霸气侧漏 发表于 2014-8-7 08:38:53

帮你顶一下吧

三国小兵 发表于 2014-8-7 08:49:44

在网络上搜索了下,找到个求平均值的方法,比如5次采样分别为5.03,   5.10,   5.30,    5.4,   4.9;可以第一次显示5.03,第二次显示(5.1+5.03)/2,第三次显示(5.03+5.1+5.3)/3以此类推,每次只采样5个值
页: [1]
查看完整版本: 51内核SOC单片机AD采用交流电压