找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開始

搜索
查看: 17441|回復(fù): 0
打印 上一主題 下一主題
收起左側(cè)

Arduino學(xué)習(xí)13-最簡(jiǎn)單的Arduino頻率計(jì)

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
想測(cè)量一個(gè)聲音的頻率或是占空比,但是又沒頻率計(jì)?我們可以用一塊arduino去搞定這事情。

需要的材料僅是一塊普通arduino,無需外圍元件。

特性:
1. 可以測(cè)量20~20kHz的信號(hào),超過的話誤差越來越大。
2. 誤差大致是±5%。玩玩還行。
3. 輸出的結(jié)果有:頻率,占空比,周期,高電平時(shí)間,低電平時(shí)間。
4. 只能測(cè)量單頻,復(fù)合波形就不行了。

步驟:
1.寫下面程序到arduino里面
  1.     /*
  2.     Arduino Frequency meter
  3.     Ansifa
  4.     2013/1/5
  5.     */
  6.     int divider[6] = {0, 1, 8, 64, 256, 1024};
  7.     int prescaler = 5;
  8.     double count = 0;
  9.     double middle = 0;
  10.     char x = 0;
  11.     ISR(TIMER1_OVF_vect)
  12.     {
  13.         if (prescaler < 4)
  14.         {
  15.             prescaler++;
  16.         }
  17.     }
  18.     void interrupt()
  19.     {
  20.         if (!x)
  21.         {
  22.             count = TCNT1;
  23.             TCNT1 = 0x000;
  24.             TCCR1B = prescaler;
  25.             attachInterrupt(0, interrupt, FALLING);
  26.         }
  27.         else
  28.         {
  29.             middle = TCNT1;
  30.             attachInterrupt(0, interrupt, RISING);
  31.         }
  32.         x = ~x;
  33.     }
  34.     void setup()
  35.     {
  36.         Serial.begin(57600);
  37.         TIMSK1 = 0x01;
  38.         TCCR1A = 0x00;
  39.         attachInterrupt(0, interrupt, RISING);
  40.     }
  41.     void loop()
  42.     {
  43.         Serial.print("Freq: ");
  44.         Serial.print(16000000.0 / divider[prescaler] / count);
  45.         Serial.print(" Hz                Duty: ");
  46.         Serial.print(middle / count * 100);
  47.         Serial.print(" %                Period: ");
  48.         Serial.print(0.0000625 * divider[prescaler]*count);
  49.         Serial.print(" ms                H-time: ");
  50.         Serial.print(0.0000625 * divider[prescaler]*middle);
  51.         Serial.print(" ms                L-time: ");
  52.         Serial.print(0.0000625 * divider[prescaler]*(count - middle));
  53.         Serial.println(" ms");
  54.         if (prescaler > 1)
  55.         {
  56.             prescaler--;
  57.             delay(200);
  58.         }
  59.         delay(100);
  60.     }
復(fù)制代碼

2. 將你的信號(hào)從D2和GND引腳輸入。由于沒有經(jīng)過任何放大處理,信號(hào)必須滿足開關(guān)arduino引腳的電平值,就是最好可以有0-5v的振幅。。

電路圖太簡(jiǎn)單


3. 打開串口監(jiān)視器,調(diào)波特率到57600,即可看到結(jié)果。因?yàn)闆]有任何防干擾措施,出現(xiàn)偏差特別大的結(jié)果請(qǐng)自行忽略。



4. 如果你愿意的話,也可以擴(kuò)展一下這個(gè)電路的性能:
* 振幅不夠的話,可以使用運(yùn)放或者三極管進(jìn)行預(yù)放大;
* 測(cè)量頻率不夠高,可以使用74HEF4060進(jìn)行分頻。74HEF4060可以支持高達(dá)2^14=16384級(jí)分頻,理論可以將量程提高16384倍。但是由于74HEF4060性能限制,可以將輸入頻率提高到20MHz。但是分頻之后就只能看到頻率,而測(cè)不到波形的占空比了。并且注意不要使用CD4060,那是低速版本。

問題解答:
請(qǐng)教
1)這個(gè)interrupt函數(shù)用的是遞歸嗎?

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

這幾句話分別代表什么意思呢?
是定義時(shí)鐘的寄存器?
這幾句

答:
我就是懶得解釋才刪掉所有注釋的。。。

   1)這個(gè)interrupt函數(shù)用的是遞歸嗎?
   
   不是,因?yàn)闆]有調(diào)用,attachInterrupt只是設(shè)置上升觸發(fā)中斷還是下降觸發(fā),因?yàn)檩斎氩ㄐ紊仙陆凳禽喠靼l(fā)生的,所以設(shè)置一個(gè)檢測(cè)完一種立即換另外一個(gè),x就是不斷在換。

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

這幾句話分別代表什么意思呢?
是定義時(shí)鐘的寄存器?

這幾句都是寄存器,TCNT1存著計(jì)數(shù)器當(dāng)前值,就是計(jì)次結(jié)果;TCCR1B預(yù)分頻器,調(diào)整量程;TIMSK1允許計(jì)數(shù)器1溢出中斷;TCCR1A是其他零碎的。。。請(qǐng)參看http://wenku.baidu.com/view/ec6961f09e3143323968931b.html

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏1 分享淘帖 頂 踩
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

手機(jī)版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表