1

48MHzの水晶振動子とMCC18のコンパイラを使用してPIC18f87J50の遅延マクロを作成するにはどうすればよいですか。遅れは私たちの中にあるはずです。したがって、たとえば、Delay_us(201)と記述して、実際に201usの遅延を取得できます。

私が今持っているのは:

#define Delay_us(n) (Delay10TCYx(((n) * (uint16_t) 12 + 9) / 10))

そして、それは私のオシロスコープでは正しくないようです!:/

敬具!

そしてメリークリスマス!

4

5 に答える 5

2

PICはクロックを4で割るので、48Mhzの場合、各オペコードは0.0833usまたは1あたり12サイクルで実行されます。私はMPLABを使用し、さまざまなus値を入力し、シミュレーターをチェックインして、予想どおりのサイクル数が得られるようにしました。関数を調整する最良の方法は、アセンブリを確認するか、シミュレーターを使用することです。

次のようなことができますが、コンパイラの関数呼び出しを調整する必要があります。

#define OVERHEAD (2)

void Delay_us(uint8_t us)
{
   if ( us <= OVERHEAD ) return; // prevent underflow
   us  -= OVERHEAD ;             // overhead of function call in us.

   Nop();       // 1  extra overhead to make function overhead an even us.
   Nop();       // 1  add or remove Nop's as necessary.
   Nop();       // 1
   //Nop();       // 1
   //Nop();       // 1
   //Nop();       // 1
   //Nop();       // 1
   //Nop();       // 1
   //Nop();       // 1
   //Nop();       // 1
   //Nop();       // 1
   //Nop();       // 1

   do   // loop needs to be 12 cycles so each cycle is 1us.
   {
      Nop();       // 1
      Nop();       // 1
      Nop();       // 1
      Nop();       // 1
      Nop();       // 1
      Nop();       // 1
      Nop();       // 1
      Nop();       // 1
      ClrWdt();    // 1
   } while(--us);  // 3
}
于 2009-12-26T16:45:18.880 に答える
2

不正確さの一部は、 Delay10TCYxに渡される値を計算する式の評価が原因である可能性があります。この式には除算が含まれているため、コントローラーがその値を計算するのにかなりの時間がかかる場合があります。

于 2009-12-28T11:17:29.210 に答える
1

MCCマニュアルでは、遅延ループの作成に関係する非常に単純な計算について説明しています。ライブラリ遅延関数に依存する代わりに、独自のループを実装することができます。

于 2009-12-25T11:09:39.513 に答える
0

これはさらに正確だと聞きましたが、私のオシロスコープは他の値を教えてくれます。コンパイルするときに何か関係がありますか?そのimは最高レベルでそれをしていませんか?

#define CONST_RANGE(min, val, max) (sizeof(char (*)[(val) >= (min) && (val) <= (max) ? +1 : -1]), (val))
#define Delay_ms(n) Delay1KTCYx(CONST_RANGE(1, (n) * 12L, 255))
#define Delay_us(n) Delay10TCYx(CONST_RANGE(1, ((n) * 12L + 6) / 10, 255))
于 2009-12-29T14:04:11.453 に答える
0

これにより、遅延がはるかに正確になることがわかりました。

void Delay_uS(byte uSec) {

   do {
       Delay1TCY();            // 1
       Delay1TCY();            // 1
       Delay1TCY();            // 1
       Delay1TCY();            // 1
       Nop();                        // 1
       Nop();                        // 1
       Nop();                        // 1
       ClrWdt();                        // 1; Clear the WDT
       } while(--uSec);        // 3
}

これに関する他のアイデアや返信はありますか?

Dario Gに感謝します....別のフォーラム;)

于 2009-12-25T14:46:37.577 に答える