我想做一个51mcu 4位频率计,测1~9999hz方波,程序写好了,可以正常运行,显示正常。但是有个问题就是:当待测频率较小的时候,100hz左右时候没有误差,待测频率在1000hz左右时,测出来的相对误差大概1.6%,2000hz时候误差3.2%,3000hz时候5.3%,8000hz时候误差15%。频率越大,误差越大。但是误差是跟频率成正比的,所以我想给num乘以一个关于频率的函数,频率越高,此函数值越大,刚好就弥补了待测频率越高误差越大的缺陷。
但是void display()里面num一乘以double型变量就显示出错了,强制转换(uint)(num*x)类型也没用,还是显示不对。请问该怎么改?
//四位方波频率计
#include<reg52.h>
sbit dula=P2^6;
sbit wela=P2^7;
#define uint unsigned int
#define uchar unsigned char
uint num,a,b,c,d,k;//num作为一个全局变量//a b c d是千位到个位
//double num;
uchar code table[]={
0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71};
/*函数声明*/
void delay(uint);
void display();
uint read1();
/*主函数*/
void main()
{
TMOD=0x15; //0001 0101 定时器1,计数器0
TH1=(65536-45872)/256; //11.0592MHZ下装入45872才是50ms
TL1=(65536-45872)%256;
TH0=0;
TL0=0; //要用1个计数器,1个定时器
ET1=1;
EA=1;
TR0=1;
TR1=1;
while(1);
}
/*定时1s函数*/
void
timer0() interrupt 3
{
TR1=0;
TH1=(65536-45872)/256;
TL1=(65536-45872)%256;
k++;
if(k==20)
{
num=read1(); //num是计数个数
display();
k=0;
TH0=0;
TL0=0;
}
TR1=1;
}
/*前4位数码管显示函数*/
void display()
{
uint i;
for(i=100;i>0;i--)
{
num=(num*1); //在此处num乘以修正系数,不修正时NUM乘1
a=(num/1000);
b=((num%1000)/100);
c=(((num%1000)%100)/10);
d=(((num%1000)%100)%10);
dula=1; //千位
P0=table[a];
dula=0;
P0=0xff;
wela=1;
P0=0xfe;//1111 10
wela=0;
delay(5);
dula=1; //百位
P0=table[b];
dula=0;
P0=0xff;
wela=1;
P0=0xfd;//1111 01
wela=0;
delay(5);
dula=1; //十位
P0=table[c];
dula=0;
P0=0xff;
wela=1;
P0=0xfb;//1110 11
wela=0;
delay(5);
dula=1; //个位
P0=table[d];
dula=0;
P0=0xff;
wela=1;
P0=0xf7;//1101 11
wela=0;
delay(5);
wela=1;
P0=0xff;//1101 11
wela=0;
delay(5);
}
}
uint read1() //读计数器1的值
{
uint t1_1,th1_1,th2_1;
uint val_1;
while(1)
{
th1_1=TH0;
t1_1=TL0;
th2_1=TH0;
if(th1_1==th2_1)
break;
}
val_1=th1_1*256+t1_1;
return val_1;
}
/*延时函数*/
void delay(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
一周热门 更多>