asunder_love 发表于 2011-8-10 08:25:22

用STC89C52的定时器及计数器做频率计无法测准400Khz以上频率?

昨天用51写了个测量频率的程序,晶振12M。测量500Hz到400KHz范围内的频率都达到了所需要的精度。例如测量400K时误差在0.5K以内。在测量500K时误差也不大。但是测量420K至500K之间的频段时误差就很大了。可以达到20K。这是为什么?

asunder_love 发表于 2011-8-10 08:26:12

显示用的是12864,处理完数据才慢悠悠地显示,因而显示环节应该没有问题。

asunder_love 发表于 2011-8-10 08:26:33

附源程序:

#include <reg52.h>
#include "LCD_Dis.h"



char i=0;
float frq=0;
unsigned char timeflag=0;
void err()//显示err
{
        FontSet(1,1);
        SetBackLight(50);
        PutChar(0,0,0x45);
        PutChar(X_Witch,0,0x52);
        PutChar(2*X_Witch,0,0x52);       
}



void dis(float r)//在LCD上显示浮点数
{
        int i=0;
        int disx=122,disy=3;
        long int s;
//        r=r*100.0;
//        ClrScreen();       
        s=r*1000000;

        while(i<6)
                {        i++;                       
                        PutChar(disx,disy,0x30+(s%10));
                        s=s/10;
                        disx=disx-X_Witch;

                }
//以下为显示小数点指令
        SPI_SSSet(0);                                        //SS置低电平       
        SPI_Send(1);                                        //传送指令0x07
        SPI_Send(disx+X_Witch/2);                                        //要显示字符的左上角的X轴位置
        SPI_Send(disy+Y_Witch-3);                                        //要显示字符的左上角的Y轴位置
        disx=disx-X_Witch;
        SPI_SSSet(1);                                        //完成操作置SS高电平

        s=r;
        while((s/10)!=0)
        {

                PutChar(disx,disy,0x30+(s%10));
                s=s/10;
                disx=disx-X_Witch;
        }
        PutChar(disx,disy,0x30+s);
        disx=disx-X_Witch;

}

void time() interrupt 1                                //低频信号将进入此中断
{
        TR1=0;
        timeflag+=1;

        if(timeflag>=200)
        {        frq=(i+1.0)*1024.0*1000000.0/(timeflag*65536.0+4);                //估计修正值4us          
                dis(frq);
                while(1);
        }
        else
        {
                TR0=1;
                TR1=1;
        }
}




float calcfrq()//calculate frequency
{

        float frequency;
        frequency=((i+1.0)*1024.0*1000000.0/(TH0*256.0+TL0+timeflag*65536.0)*1.01626-1626);
        return frequency;
}

void count() interrupt 3//高频信号进入此中断
{
        TR0=0;
        if(TH0<40)
        {
                TH1=TH1-0x04*(i+1);//测量时间太短时延长测量时间
                i++;
                TL1=0x00;
                  TH0=0x00;
                TL0=0x00;
                TR1=1;
                TR0=1;
       }
       else
               {
               frq=calcfrq();
               dis(frq);
               while(1);
                }
}

void main()
{

        int i=0;
        EA=1;
        ET0=1;
        ET1=1;
        TMOD=0x51;
        LCD_Init();
        ClrScreen();
        SetBackLight(60);
        FontSet(1,1);
        TH0=0x00;
        TL0=0;
        TH1=0xfc;
        TL1=0x00;


        TR1=1;
        TR0=1;
               
        while(1)
        {       
                for(i=255;i<0;i--)       
                        ;
        }



}

chess01 发表于 2011-8-10 08:29:27

计数器最高输入频率只能到晶振的1/24,换24M晶振吧,要不先用分频器分频

zuu0 发表于 2011-8-10 08:49:04

我12M 40K都做不上去

zhaolong5 发表于 2011-8-10 09:17:47

先用74HC4040做分频后再送到外中断,在程序中乘以原分频值,得到原来的频率,想是这样啊,没玩过。

lcmdw 发表于 2011-8-10 10:42:34

mark

asunder_love 发表于 2011-8-10 13:26:38

回复【3楼】chess01=CHESS
-----------------------------------------------------------------------

试了一下果然是。。。换了个手头有的22.1184就达到700k了。、
谢谢~~

asunder_love 发表于 2011-8-10 13:27:04

回复【6楼】lcmdw
-----------------------------------------------------------------------

这个有什么好Mark。。。

asunder_love 发表于 2011-8-10 13:27:25

3楼,然后就6楼了。。。

BCE312 发表于 2011-8-11 23:49:17

今天也写了这个程序~~

starsun 发表于 2011-9-20 02:10:21

STC89C52
设成6T的,不是相当于24MHz,能测500KHz以上吗?

millwood0 发表于 2011-9-20 06:24:16

it can easily measure frequencies in excess of 1Mhz.

you just need to know how to code correctly.

XA144F 发表于 2011-9-20 08:35:15

{ frq=(i+1.0)*1024.0*1000000.0/(timeflag*65536.0+4); //估计修正值4us   ???
在中断程序中跑浮点运算?这不扯淡嘛!

还有在中断3里出现了如下的代码:
else
{
frq=calcfrq();
dis(frq);
while(1);
}

别把什么显示、计算的功能放在中断里,中断里的程序越简洁越好。

使用单片机的定时器2之16位自动重载方式来定时,保证计时精确。T1和T2用来记录脉冲,在12MHz时测量500KHz以下绝对精确。
页: [1]
查看完整版本: 用STC89C52的定时器及计数器做频率计无法测准400Khz以上频率?