2017-05-23 1 views
1

このコードは短い音を出します。どのように私は440hzの音を作ることができますか?avrどのように440Hzのサウンドを定義するのですか?

編集: または次のようなもの:私は速いPWMを使いたいとは思わない。

#include <avr/io.h> 
#include <avr/interrupt.h> 

ISR(TIMER1_COMPA_vect) {  
    PORTB = 0; 
} 

ISR(TIMER1_OVF_vect) { 
    PORTB ^= 8; 
} 

int main(void) { 

    DDRB = 8; 
    PORTB = 0; 
    TCCR1B=(1 << CS10); // Prescaler: 1, Mode: 0 
    OCR1A = 9089.91; // (F_CPU/2/1/440) - 1; 

    TIMSK1 |= (1 << OCIE1A) | (1 << TOIE1); //Interrupt an 
    PCICR = 0x01; 
    sei(); // Interrupts global aktivieren 

    while(1) { 
     }; 
} 
+4

このようにするには、遅延ループを調整する必要があります。より良い方法は、ハードウェアタイマーを使用することです。 –

+0

デジタル出力ポートを使用していますか? –

+0

はいデジタル出力ポートを使用しています – Cashew

答えて

1

高速PWMモードで実行できます。私は前にそれをやった。このアイデアは、PWMとローパスフィルタを使用して、440Hzの純粋な正弦波の量子化バージョンを作成することです。これは、タイマーを使用してPWMのデューティ・サイクルを変更し、ローパス・フィルタを使用してPWMのDC成分を分離することによって実行できます。実際にソフトウェアで実装することはあまり難しくありません。最初のステップは、440Hzの正弦波を取り、それを符号なしの8ビット値の配列に変換することです。私はすでにあなたのためにこれをしなかったので、あなたはこのようになります8ビット符号なし整数の配列を定義します

uint8_t wave[] = { 
    0x13, 0x00, 0x00, 0x00, 
    0x80, 0xab, 0xd1, 0xee, 
    0xfd, 0xfe, 0xf0, 0xd4, 
    0xaf, 0x84, 0x58, 0x31, 
    0x13, 0x03, 0x01, 0x0d, 
    0x28, 0x4d, 0x77 
}; 

正弦波の正弦波を再現するためにので、8000Hzの周波数でサンプリングし、 PWMを使用するには、8000回の割り込みを1秒間に発生させるタイマーを設定する必要があります。あなたはPWMでオーディオを再生する本当の作業例をしたい場合は

ISR(...) { 
    OCR1A = wave[index++]; 
    if (index == wave_array_length) { 
     index = 0; 
    } 
}  

:この割り込みは次のようになり、正弦道配列、に次のインデックスにPWMのデューティサイクルを変更する責任があります。私はリンクを投稿します(私が正しく覚えているなら、私はAT90USB647を使いました)。

関連する問題