想測量一個聲音的頻率或是占空比,但是又沒頻率計?我們可以用一塊arduino去搞定這事情。
需要的材料僅是一塊普通arduino,無需外圍元件。
特性:
1. 可以測量20~20kHz的信號,超過的話誤差越來越大。
2. 誤差大致是±5%。玩玩還行。
3. 輸出的結果有:頻率,占空比,周期,高電平時間,低電平時間。
4. 只能測量單頻,復合波形就不行了。
步驟:
1.寫下面程序到arduino里面
- /*
- 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 Duty: ");
- Serial.print(middle / count * 100);
- Serial.print(" % Period: ");
- Serial.print(0.0000625 * divider[prescaler]*count);
- Serial.print(" ms H-time: ");
- Serial.print(0.0000625 * divider[prescaler]*middle);
- Serial.print(" ms L-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的振幅。。
電路圖太簡單
121241tb14qs9q7vqrdwrh.gif (8.1 KB, 下載次數: 192)
下載附件
2016-4-18 03:35 上傳
3. 打開串口監視器,調波特率到57600,即可看到結果。因為沒有任何防干擾措施,出現偏差特別大的結果請自行忽略。
121247xjzjuk3vznttjw55.gif (41.51 KB, 下載次數: 148)
下載附件
2016-4-18 03:35 上傳
4. 如果你愿意的話,也可以擴展一下這個電路的性能:
* 振幅不夠的話,可以使用運放或者三極管進行預放大;
* 測量頻率不夠高,可以使用74HEF4060進行分頻。74HEF4060可以支持高達2^14=16384級分頻,理論可以將量程提高16384倍。但是由于74HEF4060性能限制,可以將輸入頻率提高到20MHz。但是分頻之后就只能看到頻率,而測不到波形的占空比了。并且注意不要使用CD4060,那是低速版本。
問題解答:
請教
1)這個interrupt函數用的是遞歸嗎?
2)TCNT1 = 0x000;
TCCR1B = prescaler;
TIMSK1 = 0x01;
TCCR1A = 0x00;
這幾句話分別代表什么意思呢?
是定義時鐘的寄存器?
這幾句
答:
我就是懶得解釋才刪掉所有注釋的。。。
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
|