Remplacer delay_us sous XC8
Répondre à la discussion
Affichage des résultats 1 à 5 sur 5

Remplacer delay_us sous XC8



  1. #1
    invitead51e543

    Remplacer delay_us sous XC8


    ------

    Bonjour à tous,

    Comme l'indique le titre, je voudrais remplacer cette instruction dans mon code que je ne trouve pas très précise. (je souhaite une précision environ à la µs).
    Y a t-il un autre moyen que d'utiliser un Timer?

    Ou sinon comment procéder pour ne pas utiliser d'interruptions Timer dans mon programme?
    Peut-on stocker la valeur du Timer dans une variable et ensuite l'appeler avec un simple delay ou wait?

    Exemple :

    Code:
    __delay(valeurTimer);
    Merci d'avance,
    @+

    -----

  2. #2
    invite6cb06424

    Re : Remplacer delay_us sous XC8

    Salut,

    Tu souhaites faire des pauses de quelques µs précises ou quelques ms voir secondes précises à la µs?

    Si c'est juste quelques µs et que tu veux être vraiment précis, je crois bien qu'il ne te reste que l'assembleur, au moins, tu est sur que tel instruction fait autant de ns ; A toi de faire une boucle pour avoir tout pile poil ce que tu souhaites.

    Bien sur je ne te dit pas de refaire tout ton programme en assembleur, juste un petit bout de code ajouté au programme en C.
    L'assembleur n'est pas fini quand on veut être précis!

    Après personnellement j'ai pas remarqué que le delay_us n'est pas précis. Quel décalage observes-tu?

    A+

  3. #3
    invite60c6fa7f

    Re : Remplacer delay_us sous XC8

    Effectivement, je penses pas que la macro __delay_us() soit si imprécise que ça. Mais quand tu es à la uS en C, sans voir le code assemblé, tu n'as aucune idée du temps que ça peut prendre, sinon plus que demandé. Par exemple, j'avais essayé une tempo de l’ordre de 100uS avec XC8 en mode gratuit. Le résultat est plus proche avec delay_us(100); qu'avec un code du genre
    Code:
    for(TMR0=0;TMR0<100;);
    et une incrémentation de TMR0 toutes les 1uS, oscillateur interne 4MHz. De mon souvenir l’oscillateur interne est calibré de l'ordre de quelques %, j'en était était loin! Mesuré au scope en changeant l'état d'une sortie. Très probablement du à l'écriture dans TMR0 puis la comparaison de celui-ci avec la valeur que tu souhaite atteindre, puis l'écriture sur le port, etc. Pas essayé en IRQ, mais les instructions pour écrire dans TMR0, tester la cause de l'interruption, remettre le flag à 0,.... à 1uS l'instruction, c'est plus négligeable... Attention aussi au read modify write sur les pics n'ayant pas de registre LATx.

  4. #4
    RISC

    Re : Remplacer delay_us sous XC8

    Salut,

    Je crois que la fonction __delay_us(x) à une valeur minimum de x. En dessous elle n'est pas utilisable.
    Il ne faut bien sur pas oublier que si tu utilises l'oscillateur interne du PIC il a une précision de +/- y% (généralement +/-5% de -40 à +85C
    Cela dit en desous de 1us pour un PIC16 il vaut mieux mettre des Nop(); Cela dépend bien sûr du PIC que tu utilises.
    Pour un PIC16F1xxx sur l'oscillateur interne (Fosc=32MHz) Fcy = 8MHz (125ns) donc 8 x NOP();
    Sur un PIC18 à Fosc =40MHz, Fcy = 10MHz (100ns), donc 10 NOP();

    Quel PIC utilises-tu ?
    Quel délai veux-tu générer ?

    a+

  5. A voir en vidéo sur Futura
  6. #5
    paulfjujo

    Re : Remplacer delay_us sous XC8

    bonjour,

    un exemple utilisé sous MikroC , mais en assembleur pour une tempo de 500µS
    La tempo n'est valable QUE SI IL N'Y A PAS DE TRAITEMENT D''INTERRUPTIONS dans le programme !
    exemple avec FOSC=16MHZ cycle de 4/FOSC=0.25µS

    Code:
     short N1;
          
     N1=100;  // initialise once the variable , to be reconized by compiler
     // tempo de 500,0µS
     // formula :   = 0,25+0,25 +(N1*(16*0,25+0,5+0,25))-0,25+(4*0,25)
     //               Load counter    N1 Loops  times ( 16 Nop + Decrement Counter + Branch loop) - Branch (skiped )+
    //  final adjust by 4 nop.
    
     asm
     {        
            MOVLW 105 ;
            MOVWF _N1;   // 8 bit counter
     ici:        
            nop ;   //1
            nop ;
            nop ;
            nop ;
            nop ;
            nop ;
            nop ;
            nop ;
            nop ;
            nop ; //10
            nop ;
            nop ;
            nop ;
            nop ;
            nop ;
            nop ; //16
            decfsz _N1 ,F ;   //decr counter, skip over next instruction if equal to zero  
            bra ici   ;
            nop;
            nop;
            nop;
            nop;  // add 4x0.25=1µS to round tempo pile poil to 500µS
     }
      asm nop ;  // external nop final used as Break point to measure exact cycles and times . ...gives 500.0µS

Discussions similaires

  1. Fonction delay_us()
    Par invitea5db0ae5 dans le forum Programmation et langages, Algorithmique
    Réponses: 2
    Dernier message: 26/07/2014, 21h54
  2. Probleme avec delay_us()
    Par invite49060bcb dans le forum Électronique
    Réponses: 16
    Dernier message: 31/12/2011, 11h17
  3. Pourras-t-on remplacer un jour remplacer les centrales nucléaires?
    Par invite9dbf4462 dans le forum Technologies
    Réponses: 25
    Dernier message: 15/11/2011, 20h57
  4. Réponses: 3
    Dernier message: 01/09/2009, 21h10
  5. Comment intégrer des données sous Excel dans un StringGrid sous C++ Builder ?
    Par invite386d297b dans le forum Logiciel - Software - Open Source
    Réponses: 0
    Dernier message: 29/05/2007, 12h56
Dans la rubrique Tech de Futura, découvrez nos comparatifs produits sur l'informatique et les technologies : imprimantes laser couleur, casques audio, chaises gamer...