这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 综合技术 » 基础知识 » AVR 谁用AVR做过频率计?

共2条 1/1 1 跳转至

AVR 谁用AVR做过频率计?

院士
2006-09-17 18:14:16     打赏
AVR 谁用AVR做过频率计?



关键词: 谁用     做过     频率计    

院士
2006-12-22 22:43:00     打赏
2楼
问 请问谁用AVR做过频率计,
我用Input Capture做的测周期,
但是发现总是不准.相差能在4%左右.实在太大了.
我的要求是最大千分之一.
不知谁做过这个,能否指点一二?
1: 测量的频率范围是多少?如果频率不是很低,用计数法更好些。 2: 我也准备做一个频率计,能否将你的代码参考一下?我是参加电子设计竞赛的学生,没有商业上的问题
如果你也用的是ATmega8的芯片,我十分愿意共同开发,不要报酬。 3: 没道理啊.没道理不能用Input Capture测频测周啊.
AVR的DataSheet上就说Input Capture可以用来测频的.
而且,我觉得程序应该没有什么问题,
一进Capture的中断就立即读取ICR的值,应该没错吧.
即便考虑进中断的四个时钟周期,那也只是0.5us的误差吧,
误差率应在0.5us/1ms=0.05%以下吧.(我现在只是做1KHz以下的测周)
可是误差怎么会这么大呢?
用计数器会不会好一点?
这是不是AVR本身的bug?或者是我在使用中遗漏了什么重要环节?
想了很久,改了很久,都没有什么变化.
请高手指教.
4: 我的程序不具有什么参考价值过纯中,你好.
我的程序不具什么参考价值,
只是随手写来测试一下AVR的Input Capture和Timer的准确度.
只写了一小部分(测周),
如果你要的话,可以等我写完后交换代码看一看.
我也是参加了今年的竞赛,QQ:151018994
可以交流 5: 发现问题了.原来是内部晶振的问题.原来是内部晶振不准.
换了外部的就好了.
只不过还是有点问题,就是精度只能到0.3%左右,
达不到0.1%的要求.:( 6: 信号源的波形和精度能达到要求吗? 7: ICP的噪声抑制使用了吗? 8: 用了噪声抑制.用了噪声抑制,信号源的精度没问题.

在低频时测量精度高(能达到5位有效数字,最后一位有时有点小变化,问题不大),100Hz以上精度就不太高,(第3位数字会变).比如844.33,测出来就变成855.21 我想不明白为什么.
我是这样测的:
1Hz-10Hz  以32us为单位进行测量.即TCCR1B=0xC4;(C表示上升沿,带噪声抑制,4表示256预分频)
10hz-100hz 以8us为单位进行测量.
100Hz-1KHz 以1us为单位进行测量.

这样测出来的数据应该都在1000-10000之间,误差率应在0.1%以下,
我这样算没错吧...
可是最后出来误差率在0.3%左右....
有可能是什么原因呢?
9: 被测信号作为闸门测量方法看上去好像没有问题,100Hz-1KHz 以1us为单位进行测量时数据在1000-10000之间,理论上只存在+-1误差。
你能确定信号源频率正确吗?844.33用什么测量的?要用好的频率计确认,示波器看的不准。还有信号源本身稳不稳定,精度能达到0.1%吗? 10: 今天我也写出了频率计的基本代码。不过好像问题多多,首先一个频率自适应问题就需要大量编码,不然如果被测信号频率低的话,16位的计数器很容易就溢出了n次了。

blackthick的程序应该写了差不多了,不知道你是怎么解决的?

如果你愿意请将代码发至:
ericguo@eastday.com 11: 过纯中不好意思,我只写了测周(量程自转换)的部分,
因为这几天比较忙,所以一直没动那个程序.
我过两天写好了再跟你探讨吧.OK?
12: 其实测频还是用CPLD做比如方便.用CPLD测又准又简单,
一个状态机就可以解决量程自转换的问题.
单片机好像真的很麻烦,
还要一些外围的分频器之类的.:( 13: 我的程序使用32位软计数器来解决问题最高频率<100KHz// Eric Guo writed at 2003-08-02, GPL license.
#include <AVR/io.h>
#include <AVR/interrupt.h>
#include <AVR/signal.h>
#include <stdlib.h>
#include <string.h>

#include "global.h"
#include "zlg7289.h"

volatile union cap_tags{
u32 l;
struct {u16 i0, i1; } i;
} cap_new, cap_old;

volatile u08 CAN_show;

void display_num(unsigned long num);

void mcu_init(void)
{
    ACSR  =(1<<ACBG)|(1<<ACIC)|(1<<ACIS1)|(1<<ACIS0);

    TCCR1A=0x00;
    TCCR1B=0x81;        // CLK/1
    ICR1  =0;
    TCNT1 =0;

    ASSR = 1<<AS2;    // Page 99
    TCCR2 = 0x05;    // Div128

    TIMSK =(1<<TICIE1)|(1<<TOIE1)|(1<<TOIE2);    // enable capture
}

SIGNAL(SIG_INPUT_CAPTURE1)
{
    cap_old.l=cap_new.l;
    cap_new.i.i0=ICR1;
    CAN_show=1;
}

SIGNAL(SIG_OVERFLOW1)
{
    cap_new.i.i1++;
    CAN_show=0;
}

INTERRUPT(SIG_OVERFLOW2)
{
while(CAN_show==0) ;
if(cap_new.l>cap_old.l)
    {
    float fre;
    fre=F_CPU/(cap_new.l-cap_old.l);
    display_num( fre );
    }
}

int main(void)
{
    zlg7289_reset();
    mcu_init();

    sei();

    cap_old.l=0;
    cap_new.l=0;
    CAN_show=0;

    while(1)
    {
        // let the interrupt do jobs.
    }
    return 0;
}

void display_num(unsigned long num)
{
    char zlg_line[0x10];
    u08 i, j;
    zlg7289_disp(0, 0, ZLG7289_RESET);
    ultoa(num, zlg_line, 10);
    for(i=strlen(zlg_line)-1, j=0; i>0; i--, j++)
        zlg7289_disp(zlg_line[i], j, ZLG7289_TYPE0);
    zlg7289_disp(zlg_line[0], j, ZLG7289_TYPE0);
}


// 大家以后还是用代码说话。 14: 我现 在也正在编一个频率计的程序我用的是AT90S8515,我正在编,望各位大侠有好的建议,给我 发E-MAIL.
同时我 也正在编串口通讯和LCD控制,请各位大侠给点建议和指导。
我的 E-MAIL:wanglele615@163.com

共2条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]