|
楼主 |
发表于 2020-10-23 00:37:26
|
显示全部楼层
以下是完整的采样以及计算公式,两个开平方返回的结果是一样的,说明公式应该没有问题,主要是我自己写的这部分程序哪里不对,平均值是正确的,就是均方根值不正确,两种公式得出的结果是一样的,但是结果不正确。
unsigned int insqrt(unsigned long a)
{
unsigned long i,c;
unsigned long b=0;
unsigned int dat;
for(i=0x40000000;i!=0;i>>=2)
{
c =i+b;
b>>=1;
if(c<= a)
{
a-=c;
b+=i;
}
}
dat=b;
return dat;
}
unsigned int isqrt32(unsigned long x)
{
unsigned long m, y, b;
m = 0x40000000;
y = 0;
while (m != 0)
{
b = y | m;
y = y >> 1;
if (x >= b)
{
x = x - b;
y = y | m;
}
m >>= 2;
}
return y;
}
void READ_SYS_Voltage(void)//读取系统电压
{
unsigned char i,DL;
unsigned int Dat=0;
unsigned int xdata a[140];
unsigned long b=0,p=0;
for(i=138;i>0;i--)//清空数组内数据
{
a[i]=0;
}
TF1 = 0; //清除TF1标志
ET1 = 0; //关闭定时器1中断
TR1 = 0; //定时器1关闭计时
TH1 = 0x00; //初始化计时值
TH1 = 0xb8; //初始化计时值 定时20毫秒@11.0592M外置晶振
TF1 = 0; //清除TF1标志
ET1 = 1; //使能定时器1中断
TR1 = 1; //定时器1开始计时
READ_Voltage_EN=1;//将定时时间到置1
Dat=0;
while(READ_Voltage_EN)//到达20毫秒后,此变量通过定时器1中断置0,退出采样
{
ADC_CONTR = 0xc0; //清除ADC 180个时钟转换一次
ADC_CONTR = 0Xcc; //P1.4
while(!(ADC_CONTR&0x10));
a[i]=ADC_RES;
DL=ADC_RESL;
a[i]<<=2;
a[i]|=DL;
ADC_CONTR = 0xc0; //清除ADC
a[i]>>=1;
if(i<139)
{
i++;
}
Delay_Read();//延时
Dat++;
}
Send_ASCII("共计采样:",0);
WR_DAT(Dat);
DL=i;
for(i=0;i<DL;i++)
{
b+=(a[i]*a[i]);//计算平方和
p+=a[i];//累加
}
b/=DL;//计算平方和后再平均
Dat=insqrt(b);//开平方
a[0]=isqrt32(b);
Send_ASCII("均方根值1:",0);//第一种均方根计算方式
WR_DAT(Dat);
Send_ASCII("均方根值2:",0);//第二种均方根计算方式
WR_DAT(a[0]);
Dat=p/DL;//直接平均
Send_ASCII("平均值:",0);
WR_DAT(Dat);
ENT();ENT();
}
|
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有帐号?注册
x
|