Question

Comment devrais-je écrire une macro de retard pour un PIC 18f87J50 avec un cristal de 48MHz et compilateur de MCC18. Le délai devrait être en nous. Donc, par exemple, je peux écrire: Delay_us (201) et vraiment délai 201us.

Ce que j'ai maintenant:

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

Et il does'nt semble juste à mon oscilloscope! : /

Cordialement!

Et joyeux Noël!

Était-ce utile?

La solution

Le PIC divise l'horloge de 4 donc pour 48Mhz chaque opcode fonctionne en 0.0833us ou 12 cycles par nous. Je MPLAB et mis dans les différentes valeurs nous et vérifié dans le simulateur afin que le nombre de cycles est sorti comme je m'y attendais. La meilleure façon de régler la fonction est de regarder à l'assemblée ou utiliser le simulateur.

Vous pouvez faire quelque chose comme ce qui suit, mais vous devrez régler l'appel de fonction pour votre complier.

#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
}

Autres conseils

Une partie de l'inexactitude pourrait être due à l'évaluation de l'expression qui calcule la valeur qui est passée à Delay10TCYx . Étant donné que cette expression contient une division, il peut prendre un certain temps pour le contrôleur pour calculer cette valeur.

Le manuel MCC explique le calcul très simple qui est impliqué dans la création de boucles de retard. Vous pouvez simplement mettre en œuvre votre propre boucle au lieu de compter sur les fonctions de retard bibliothèque.

Je trouve que cela fait mon retard nous beaucoup plus précis:

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
}

D'autres idées ou replys ce sujet?

Merci à Dario G à .... un autre forum;)

J'ai entendu ce serait encore plus précis, mais mon ocsilloscope me donner d'autres valeurs puis à droite. Se pourrait-il avoir quelque chose à faire quand je compiler ?? Cela je ne suis pas le faire au plus haut lvl ??

#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))
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top