3

編集:PIC 16F684

さて、私は0から7までカウントする単純な3 LEDバイナリクロックを持っており、各ライトがオンになる間に約1秒の遅延を追加したいと思います。

私は、各ライトが一種のループにある必要があり、ティックやロールオーバーなどを測定するためにカウントを使用する必要があることを理解しました。

時計は4MHzだと思います。マニュアルのスクリーンショットは次のとおりです。http: //i.imgur.com/tJatQ.png

これが私のコードからの関連する抜粋です:

COUNT1 EQU 20h      ; Delay counter #1
COUNT2 EQU 21h      ; Delay counter #2

..。

LOOP0
        MOVLW   TRIS_D0_D1      ; Move value defined in Constants to TRISA, to switch on LED 0.
        TRIS    PORTA           ;
        CLRF    PORTA           ; Clear all outputs.
        MOVLW   D0              ; Set the accumulator to the value of D0.
        MOVWF   PORTA           ; Move the accumulator to PORTA, to switch on LED 0.

    ; Using COUNTs to add a delay
        decfsz    COUNT1,1       ; Decrease COUNT1 by 1, and skip the next line if the result is 0.
        goto      LOOP0          ; If COUNT1 is 0, carry on. If not, go to LOOP0.   
        decfsz    COUNT2,1       ; Decrease COUNT2 by 1, and skip the next line if the result is 0.
        goto      LOOP0          ; If COUNT1 is 0, carry on. If not, go to LOOP0.

しかし、私はタイミングを台無しにしているとかなり確信しています、誰かが私に手を差し伸べることができますか?

4

2 に答える 2

4

仮定:のコードは、遅延中にできるだけ多く実行するのではなく、遅延ごとに1LOOP0実行するコードです。また、あなたが何かに設定していると仮定します-あなたが投稿したコードは2つの「変数」を宣言していますが、それらを割り当てていません。COUNT1COUNT2

あなたが現在持っているコードは、LOOP0 COUNT1+COUNT2回繰り返しコードを実行します。これは、各ループが分離しているためです。これにより、510サイクルの最大遅延が得られます。他のコメント提供者が述べているように、PIC16は1サイクルあたり約1命令を実行するため、4MHzで1秒間待機するには、1,000,000サイクルを遅延させる必要があります。

サイクルを待機したい状況を考えると、196392基本的に16ビットカウンターを実装する必要があります。これを行うには、ループ内の1つのカウンターをデクリメントします。そのループが終了するたびに、別のカウンターをデクリメントします。両方のカウンターがゼロの場合、ループは戻ります。次に例を示します。

COUNT1 EQU 20h
COUNT2 EQU 21h

LOOP0
    ;do some stuff here
        ...

    ;delay loop starts here:
    ;assume COUNT1=0 and COUNT2=0
Delay_0
    decfsz COUNT1
    goto Delay_0
    decfsz COUNT2   ;COUNT1 = 0 so 0xff cycles have passed
    goto Delay_0
    goto LOOP0 ;both COUNT1 and COUNT2 = 0 - 196392 cycles have now passed

分岐命令は、スキップしない場合は1サイクル、スキップする場合は2サイクルかかります。goto常に2サイクルかかります。つまり、1回のフルカウントを実行するのにかかる実際の時間は767サイクル(255 * 3 + 2)です。両方にかかる時間を((255 * 3 + 2)+ 3)* 255+2として計算できます。

Dos4Everには遅延ルーチンの優れた説明があります。これは、遅延ルーチンがどのように機能するか、および遅延ルーチンのカウンター値とコストを計算する方法を示しています。

最後に、カットアンドペーストの遅延ルーチンが必要な場合は、PIClistの遅延ルーチンジェネレーターがほぼ完璧です。

于 2012-04-30T18:08:59.383 に答える
1

両方のカウンターが最初にゼロに設定されていると仮定した2つのループを使用した上記のコードは、(196392ではなく)197119サイクルかかりますか?

私はコードを参照しています:

  • Delay_0 decfsz COUNT1
  • goto Delay_0
  • decfsz COUNT2
  • goto Delay_0

その理由は、count1に関連付けられた内部ループが255回ループするためです。つまり、{255 x 3命令サイクル}に加えて、最後のdecfszにさらに2サイクルかかります。したがって、この内部ループが循環するのは初めての場合、関連する遅延(d1F)はd1F = 255 * 3 + 2=767サイクルになります。これはすべて、count2のdecfszに到達する前に発生します。次に、残りのアクティビティはdecfszcount2に達したときに発生します。これはdecfszcount2で始まり、goto Delay_0が続きます。ここで、'goto'は別の内部ループ遅延(d1Fに等しい)を呼び出します。したがって、decfsz count2、goto Delay_0、およびd1Fで構成されるこのトリプルの組み合わせは、カウント2のインデックス値255に関連付けられます。その後、インデックス254、インデックス253の順にトリプルコンボを取得し続けます。 count2インデックス1。つまり、255のトリプルの組み合わせが得られるということです。そして最後に、最後のdecfsz count2(インデックス0)で終了します。最終的なdecfszcount2'命令'は1ではなく2サイクルかかります。したがって、遅延の2番目の部分は(d1F + 3)* 255 + 2になります。'3'(命令サイクル)は、通常のdecfszとgoto命令によるものです。ループします。

したがって、遅延の最初の部分と2番目の部分を組み合わせると、次のようになります。

  • d2F = d1F +(d1F + 3)x255 + 2 = 767 +(767 + 3)x255 + 2 = 197119

複数のループがある場合は、次の方程式を使用できます。

  • d(n)_F = d(n-1)_F + {d(n-1)_F + 3} x255 + 2 = 256xd(n-1)_F + 767

  • d(n)_C = d(n-1)_C + {d(n-1)_F + 3} x {count_n-1} + 2

ここで、d(n)_Fまたはd(n-1)_Fの「F」は、すべてのカウンターがゼロ値で初期化される条件を示します。また、d(n)_Cの「C」は、n番目のループのカウンターが最初に選択した値で初期化される条件を示します。そして、「n」はn番目のループに関連付けられています。また、「n-1」は(n-1)番目のループに関連付けられています。

したがって、2つのループがある場合、d(1)_Fは、「フル」サイクル数のループ#1による遅延です(つまり、counter1は最初はゼロまたは256です)。d(2)_Fは、counter1とcounter2の両方が最初にゼロまたは256に等しい場合の、ループ#1およびループ#2による遅延です。

  • d(1)_Cは、count1が最初に選択した値で初期化された場合のループ#1による遅延です。
  • d(2)_Cは、count2が最初に選択した値で初期化される場合の、ループ#1およびループ#2による遅延です。

count_nは、n番目のループのINITIALカウンター値であることに注意してください。また、特定のカウンターが最初にゼロ値で初期化される場合、その値を「256」として扱うと便利なことがよくあります。もちろんこれは8ビットカウンタ用です。たとえば、count1 = 0の場合、count1 = 256(0ではなく)として扱うと便利です。

  • また、d(0)_F = 0、およびd(0)_C=0を定義することもできます。

したがって、count1 = 1、count2 = 4、およびcount3=2の3ループシステムの場合。

  • d(1)_F = 256xd(0)_F + 767 = 256x0 + 767 = 767

  • d(1)_C = 0 + {0 + 3} x {1-2} + 2 = 2

  • d(2)_F = 256xd(1)_F + 767 = 256x767 + 767 = 197119

  • d(2)_C = d(1)_C + {d(1)_F + 3} x {4-1} + 2 = 2 + {767 + 3} x3 + 2 = 2314

  • d(3)_F = 256xd(2)_F + 767 = 256x197119 + 767 = 50463231

  • d(3)_C = d(2)_C + {d(2)_F + 3} x {2-1} + 2 = 199438

3ループシステムは次のようなものです。

  • Delay_0 decfsz count1
  • goto Delay_0
  • decfsz count2
  • goto Delay_0
  • decfsz count3
  • goto Delay_0

ケニー・レオン

于 2013-06-13T00:16:01.003 に答える