设为首页收藏本站

极客工坊

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 32979|回复: 47

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

    [复制链接]
发表于 2013-1-5 12:43:52 | 显示全部楼层 |阅读模式
本帖最后由 Ansifa 于 2013-1-5 13:11 编辑

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


想测量一个声音的频率或是占空比,但是又没频率计?我们可以用一块arduino去搞定这事情。

需要的材料仅是一块普通arduino,无需外围元件。

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

步骤:
1.写下面程序到arduino里面

[pre lang="arduino" line="1" file="Freq.pde"]/*
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);
}
[/code]

2. 将你的信号从D2和GND引脚输入。由于没有经过任何放大处理,信号必须满足开关arduino引脚的电平值,就是最好可以有0-5v的振幅。。

电路图太简单
快照1.GIF

3. 打开串口监视器,调波特率到57600,即可看到结果。因为没有任何防干扰措施,出现偏差特别大的结果请自行忽略。
快照2.GIF


4. 如果你愿意的话,也可以扩展一下这个电路的性能:
* 振幅不够的话,可以使用运放或者三极管进行预放大;
* 测量频率不够高,可以使用74HEF4060进行分频。74HEF4060可以支持高达2^14=16384级分频,理论可以将量程提高16384倍。但是由于74HEF4060性能限制,可以将输入频率提高到20MHz。但是分频之后就只能看到频率,而测不到波形的占空比了。并且注意不要使用CD4060,那是低速版本。

评分

参与人数 1威望 +1 收起 理由
幻生幻灭 + 1 A大威武,13年首贴啊

查看全部评分

回复

使用道具 举报

发表于 2013-1-5 13:52:06 | 显示全部楼层
请教版主
1)这个interrupt函数用的是递归吗?

2)TCNT1 = 0x000;
  TCCR1B = prescaler;
  TIMSK1 = 0x01;
   TCCR1A = 0x00;

这几句话分别代表什么意思呢?
是定义时钟的寄存器?
这几句
回复 支持 反对

使用道具 举报

 楼主| 发表于 2013-1-5 17:55:33 | 显示全部楼层
seuabb 发表于 2013-1-5 13:52
请教版主
1)这个interrupt函数用的是递归吗?

我就是懒得解释才删掉所有注释的。。。

   1)这个interrupt函数用的是递归吗?
   
   不是,因为没有调用,attachInterrupt只是设置上升触发中断还是下降触发,因为输入波形上升下降是轮流发生的,所以设置一个检测完一种立即换另外一个,x就是不断在换。

2)TCNT1 = 0x000;
  TCCR1B = prescaler;
  TIMSK1 = 0x01;
   TCCR1A = 0x00;

这几句话分别代表什么意思呢?
是定义时钟的寄存器?

这几句都是寄存器,TCNT1存着计数器当前值,就是计次结果;TCCR1B预分频器,调整量程;TIMSK1允许计数器1溢出中断;TCCR1A是其他零碎的。。。请参看http://wenku.baidu.com/view/ec6961f09e3143323968931b.html
回复 支持 反对

使用道具 举报

发表于 2013-1-5 18:29:01 | 显示全部楼层
学习了。
回复 支持 反对

使用道具 举报

发表于 2013-1-5 20:15:26 | 显示全部楼层
是哪个软件啊,求共享
回复 支持 反对

使用道具 举报

 楼主| 发表于 2013-1-5 20:53:32 | 显示全部楼层
benzking 发表于 2013-1-5 20:15
是哪个软件啊,求共享


频率计只出数字,不是示波器。。。没波形。。不需要加软件
回复 支持 反对

使用道具 举报

发表于 2013-1-5 21:18:07 | 显示全部楼层
Ansifa 发表于 2013-1-5 20:53
频率计只出数字,不是示波器。。。没波形。。不需要加软件

串口监视器是哪个软件。。之前打错了。。
回复 支持 反对

使用道具 举报

发表于 2013-1-5 21:31:28 | 显示全部楼层
benzking 发表于 2013-1-5 21:18
串口监视器是哪个软件。。之前打错了。。

arduino ide自带的吧
回复 支持 反对

使用道具 举报

 楼主| 发表于 2013-1-5 22:50:34 | 显示全部楼层
benzking 发表于 2013-1-5 21:18
串口监视器是哪个软件。。之前打错了。。


嗯嗯,如楼上说的,ide自带的串口监视器即可
回复 支持 反对

使用道具 举报

发表于 2013-1-28 11:06:43 | 显示全部楼层
此帖必火!
强贴留名!
回复 支持 反对

使用道具 举报

高级模式  
您需要登录后才可以回帖 登录 | 注册

本版积分规则

Archiver|联系我们|极客工坊 ( 浙ICP备09023225号  

GMT+8, 2017-4-26 15:53 , Processed in 0.104382 second(s), 13 queries , File On.

Powered by Discuz! X3.3 Licensed

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表