在做一个频率计,有个地方不知道怎么回事,想请问大家一下谢谢

2019-07-15 12:41发布

我想做一个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--);       
}

友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
8条回答
wufa1986
1楼-- · 2019-07-16 06:00
 精彩回答 2  元偷偷看……
275849752
2楼-- · 2019-07-16 10:26
wufa1986 发表于 2017-1-10 17:25
你这个补偿方法不可取,测不准是程序不对

谢谢。。。。。

一周热门 更多>