3

PIC18FにC言語を使用して、それぞれが特定の時間間隔で再生されるようなトーンを生成しています。PWM を使用してトーンを生成しました。しかし、間隔を作成する方法がわかりません。これが私の試みです。

#pragma code                                    // 
void main (void)
{

 int i=0;
    // set internal oscillator to 1MHz  
    //OSCCON = 0b10110110;                    // IRCFx = 101
    //OSCTUNEbits.PLLEN = 0;                //PLL disabled

    TRISDbits.TRISD7 = 0;

    T2CON  = 0b00000101;                    //timer2 on
    PR2    = 240;
    CCPR1L = 0x78;
    CCP1CON= 0b01001100;



LATDbits.LATD7=0;
Delay1KTCYx(1000);

while(1);
}
4

3 に答える 3

6

組み込みプログラミングをしているとき、構成レジスタを設定するときに意図していることを正確に説明するコメントを追加すると非常に便利です。そうすれば、データシートに戻って0x01001010、次にコードを変更する必要があるときにコードを取得しようとしたときに何が起こるかを理解する必要がありません。(コメントを変更と同期させてください)。

私がデコードできることから、PWMレジスタが設定されているように見えますが、希望の間隔で周波数を変更する方法はありません。それを行うにはいくつかの方法があります。ここに2つのアイデアがあります。

  • 起動時にタイマーを読み取り、目的の間隔を追加して目標時間を取得し、whileループでタイマーをポーリングすることができます。タイマーがターゲットに到達したら、新しいPWMデューティサイクルを設定し、次の間隔をターゲット時間に追加します。バックグラウンドループで他のことを開始する必要があるまで、これは正常に機能します。
  • timer0のカウントを0xFFFF-intervalに設定し、ロールオーバー時に割り込みをかけるように設定できます。ISRで、新しいPWMデューティサイクルを設定し、timer0カウントを次の間隔にリセットします。

組み込みプロセスでタイミングを制御する一般的な方法の1つは、次のようになります。

int flag=0;
void main()
{
  setup_interrupt(); //schedule interrupt for desired time.
  while (1)
  {  
     if (flag)
     {  
        update_something();
        flag = 0;
     }
  }

どこflagに設定されますか?割り込みハンドラーの場合:

void InterruptHandler()
{
  flag = 1;
  acknowledge_interupt_reg = 0;
}

あなたはあなたの例のすべての部分を持っています、あなたはそれらを適切な場所にまとめる必要があります。あなたの場合、update_something()PWMを更新します。ロジックは次のようになります。「オンの場合はオフにし、そうでない場合はオンにします。必要に応じてトーン(デューティサイクル)を更新します」

メインのwhileループで追加の遅延や一時停止を行う必要はありません。目標は、何かが行われるのを待って、何度も何度も実行されることです。プログラムが別の速度で何かを行う必要がある場合は、完全に独立してトリガーされる別のフラグを追加できます。これにより、2つのタスクのタイミングが互いに干渉することはありません。

于 2009-03-02T18:33:27.193 に答える
0

編集:
あなたが達成しようとしていることについて、私は今混乱しています。同じトーン (オン-オフ-オン-オフ) の一連のパルスが必要ですか? それとも、一時停止のない一連の異なる音符が必要ですか (do-re-me-fa-...)? 私は後者を想定していましたが、今は確信が持てません。


更新されたコードを確認した後、システムがどのように構成されているか正確にはわかりません。参考になれば幸いです。

  1. PWM 部分は動作していますか? 初音はわかりますか?はいと思います。
  2. ハードウェアには、RA4/T0CKI ピンに接続された何らかのクロック パルスがありますか? そうでない場合は、T0 をカウンター モードではなくクロック モードにする必要があります。
  3. 割り込みが呼び出されていますか? タイマー割り込みではなく、外部割り込みを有効にするINT0IEを設定しています
  4. トーンの更新間隔はどれくらいですか? 現在、0xFFFF / (clock_freq/8) 何か違うものが必要な場合は、TMR0H/L レジスタを設定する必要があります。
  5. LATD7 には何がありますか? そして、なぜあなたはそれをクリアしていますか? PWM出力を有効にするということですか?
  6. なぜ Delay() を呼び出すのですか? タイマー自体が必要な遅延を提供する必要があります。タイミングの取り方にズレがあるようです。他の答えを展開します
  7. PWM周波数をどこで変更しようとしていますか? PR2に書き込む必要はないのですか?トーンごとに異なる値を指定する必要があります。

「要求に応じて、最初の失敗でビルドを停止します。」

これは、構文エラーがあることを示しているだけです。エラー レポートを表示しないと、実際には役に立ちません。

于 2009-03-04T18:42:46.980 に答える
-2

Windows では、kernel32 でビープ機能を使用できます。

    [DllImport("kernel32.dll")]
    private static extern bool Beep(int frequency, int duration);
于 2009-03-02T18:08:17.627 に答える