51内核SOC单片机AD采用交流电压
我用SOC芯片单片机做了个5A数显的交流电流表,有1%的误差跳变,要求是0.5%误差,需要多采样几次,做一个平均,能有改善吗我是直接芯片的库函数 ReadMeterPara(0x10d9); //秒平均电流有效值 ,使用库函数读取的,1.28秒才更新一次的 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); //秒平均电流有效值
}
码哥 上来就程序 晕{:dizzy:}{:dizzy:} 显示什么都正常的,就是满量程的时候,是交流5A,有1%的误差,要求0.5%的 自己顶顶。。。。。。。。 顶起来。。。。。。。。。。。。。。 我也帮顶~ 帮你顶一下吧 在网络上搜索了下,找到个求平均值的方法,比如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]