Arduino教程学习A13-最简单的Arduino频率计

Arduino学习笔记A13 - 最简单的Arduino频率计

想测量一个声音的频率或是占空比,但是又没频率计?我们可以用一块arduino去搞定这事情。
需要的材料仅是一块普通arduino,无需外围元件。

特性:

  1. 可以测量20~20kHz的信号,超过的话误差越来越大。
  2. 误差大致是±5%。玩玩还行。
  3. 输出的结果有:频率,占空比,周期,高电平时间,低电平时间。
  4. 只能测量单频,复合波形就不行了。

    步骤:
    1.写下面程序到arduino里面
    ARDUINO 代码复制打印下载
    /Arduino Frequency meterAnsifa2013/1/5/int divider[6] = {0, 1, 8, 64, 256, 1024};int prescaler = 5;double count = 0;double middle = 0;char x = 0;ISR(TIMER1_OVF_vect){  if (prescaler < 4)  {  prescaler++;  }}void interrupt(){  if (!x)  {  count = TCNT1;  TCNT1 = 0x000;  TCCR1B = prescaler;  attachInterrupt(0, interrupt, FALLING);  }  else  {  middle = TCNT1;  attachInterrupt(0, interrupt, RISING);  }  x = ~x;}void setup(){  Serial.begin(57600);  TIMSK1 = 0x01;  TCCR1A = 0x00;  attachInterrupt(0, interrupt, RISING);}void loop(){  Serial.print("Freq: ");  Serial.print(16000000.0 / divider[prescaler] / count);  Serial.print(" Hz\t\tDuty: ");  Serial.print(middle / count * 100);  Serial.print(" %\t\tPeriod: ");  Serial.print(0.0000625 * divider[prescaler]count);  Serial.print(" ms\t\tH-time: ");  Serial.print(0.0000625 * divider[prescaler]middle);  Serial.print(" ms\t\tL-time: ");  Serial.print(0.0000625 * divider[prescaler](count - middle));  Serial.println(" ms");  if (prescaler > 1)  {  prescaler--;  delay(200);  }  delay(100);}
    /

    Arduino Frequency meter

    Ansifa

    2013/1/5

    /

    int divider[6] = {0, 1, 8, 64, 256, 1024};

    int prescaler = 5;

    double count = 0;

    double middle = 0;

    char x = 0;

    ISR(TIMER1_OVF_vect)

    {

    if (prescaler < 4)

    {

    prescaler++;

    }

    }

    void interrupt()

    {

    if (!x)

    {

    count = TCNT1;

    TCNT1 = 0x000;

    TCCR1B = prescaler;

    attachInterrupt(0, interrupt, FALLING);

    }

    else

    {

    middle = TCNT1;

    attachInterrupt(0, interrupt, RISING);

    }

    x = ~x;

    }

    void setup()

    {

    Serial.begin(57600);

    TIMSK1 = 0x01;

    TCCR1A = 0x00;

    attachInterrupt(0, interrupt, RISING);

    }

    void loop()

    {

    Serial.print("Freq: ");

    Serial.print(16000000.0 / divider[prescaler] / count);

    Serial.print(" Hz\t\tDuty: ");

    Serial.print(middle / count * 100);

    Serial.print(" %\t\tPeriod: ");

    Serial.print(0.0000625 * divider[prescaler]
    count);

    Serial.print(" ms\t\tH-time: ");

    Serial.print(0.0000625 * divider[prescaler]middle);

    Serial.print(" ms\t\tL-time: ");

    Serial.print(0.0000625 * divider[prescaler]
    (count - middle));

    Serial.println(" ms");

    if (prescaler > 1)

    {

    prescaler--;

    delay(200);

    }

    delay(100);

    }

2. 将你的信号从D2和GND引脚输入。由于没有经过任何放大处理,信号必须满足开关arduino引脚的电平值,就是最好可以有0-5v的振幅。。
电路图太简单 快照1.GIF 2013-1-5 12:12 上传(8.1 KB)
  1. 打开串口监视器,调波特率到57600,即可看到结果。因为没有任何防干扰措施,出现偏差特别大的结果请自行忽略。
    快照2.GIF
    2013-1-5 12:12 上传(41.51 KB)

  2. 如果你愿意的话,也可以扩展一下这个电路的性能:

  • 振幅不够的话,可以使用运放或者三极管进行预放大;
  • 测量频率不够高,可以使用74HEF4060进行分频。74HEF4060可以支持高达2^14=16384级分频,理论可以将量程提高16384倍。但是由于74HEF4060性能限制,可以将输入频率提高到20MHz。但是分频之后就只能看到频率,而测不到波形的占空比了。并且注意不要使用CD4060,那是低速版本。
    via - 极客工坊

标签: Arduino教程