Répondre à la discussion
Affichage des résultats 1 à 21 sur 21

timer0 pic18f4550



  1. #1
    titoff

    timer0 pic18f4550


    ------

    Bonjour,

    Je voudrais régler l'échantillonnage de l'ADC du pic18f4550 à une fréquence de 160Hz. J'utilise un quartz extérieur de 20Mhz.

    D'après mes recherches il est nécessaire d'utiliser le timer0.

    Je ne programme pas avec MPLAB mais avec PCW CCS (code C).

    Pouvez vous m'indiquer la démarche à suivre ?

    Je vous remercie des réponses

    -----

  2. Publicité
  3. #2
    vede

    Re : timer0 pic18f4550

    Bonjour,

    je viens de jeter un oeil au datasheet,
    il ne parlent du timer0 pour régler la
    fréquence de l'échantillonage...mais
    plutot de calculs, basés sur la fréquence
    d'horloge (ici 20Mhz)...et du choix d'un
    facteur de "division" (2,4,8...Tosc)...

    page 259, section 21.3...

    vede
    ;O]

  4. #3
    vede

    Re : timer0 pic18f4550

    ps : en fait, c'est plutot de
    "temps d'un d'echantillonage"
    qui est décrit page 259?

    et pour échantilloner à 160Hz tu
    veux utiliser l'interruption du timer0?

    pour avoir une fréquence "plus stable"
    qu'avec une simple temporisation style
    delay_us(6250) ??

    vede
    ;O]

  5. #4
    titoff

    Re : timer0 pic18f4550

    Citation Envoyé par vede Voir le message
    ps : en fait, c'est plutot de
    "temps d'un d'echantillonage"
    qui est décrit page 259?

    et pour échantilloner à 160Hz tu
    veux utiliser l'interruption du timer0?

    pour avoir une fréquence "plus stable"
    qu'avec une simple temporisation style
    delay_us(6250) ??

    vede
    ;O]

    oui avec le timer0 c'est beaucoup plus stable.
    En fait j'ai surtout un problème au niveau du calcul de la valeur à implémenter dans le timer0 (ici "suivant")pour retomber sur une fréquence de 160hz.

    J'ai repris le travail d'un collègue et je n'arrive pas à comprendre sa démarche.

    le code :

    #include <18F4550.h>
    #device ICD=TRUE
    #device adc=10

    #include <string.h>


    #FUSES NOWDT //No Watch Dog Timer
    //#FUSES WDT128 //Watch Dog Timer uses 1:128 Postscale
    #FUSES HSPLL //High speed Osc (> 4mhz)
    #FUSES NOPROTECT //Code not protected from reading
    #FUSES BROWNOUT_NOSL //Brownout enabled during operation, disabled during SLEEP
    #FUSES BROWNOUT //Reset when brownout detected
    #FUSES BORV20 //Brownout reset at 2.0V
    #FUSES NOPUT //No Power Up Timer
    #FUSES NOCPD //No EE protection
    #FUSES STVREN //Stack full/underflow will cause reset
    #FUSES NODEBUG //No Debug mode for ICD
    #FUSES LVP //Low Voltage Programming on B3(PIC16) or B5(PIC18)
    #FUSES NOWRT //Program memory not write protected
    #FUSES NOWRTD //Data EEPROM not write protected
    #FUSES IESO //Internal External Switch Over mode enabled
    #FUSES FCMEN //Fail-safe clock monitor enabled
    #FUSES PBADEN //PORTB pins are configured as analog input channels on RESET
    #FUSES NOWRTC //configuration not registers write protected
    #FUSES NOWRTB //Boot block not write protected
    #FUSES NOEBTR //Memory not protected from table reads
    #FUSES NOEBTRB //Boot block not protected from table reads
    #FUSES NOCPB //No Boot Block code protection
    #FUSES MCLR //Master Clear pin enabled
    #FUSES LPT1OSC //Timer1 configured for low-power operation
    #FUSES NOXINST //Extended set extension and Indexed Addressing mode disabled (Legacy mode)
    #FUSES PLL5 //Divide By 5(20MHz oscillator input)
    #FUSES CPUDIV1
    #FUSES USBDIV //USB clock source comes from PLL divide by 2
    #FUSES VREGEN //USB voltage regulator enabled
    #FUSES ICPRT //ICPRT enabled

    #use delay(clock=20000000)
    #use rs232(baud=9600,parity=N,xmit= PIN_C6,rcv=PIN_C7,bits=8)



    #int_RTCC // interruption pour un échantillonnage régulier
    void RTCC_isr(void)
    {

    if (++suivant>144) // incremente suivante et on compare à 144 soit 160Hz (96= 238hz, 48 =480hZ) reglage de la fréquence d'échantillonnage
    { // temps d'echantillonnage= 256 x cycle horloge x nbre cycle x 2 avec cycle horloge=1/4Mhz=0.25µs
    //output_high(PIN_B5);
    suivant=0;

    if (echant_lu+1<_MAX && echant_lu<echant_traite+1) // si l'échantillon est bon
    {
    ++echant_lu; // échantillon pour lecture
    usb_cdc_putc('E');

    for(j=0;j<2;j++)
    x[j]=x[j+1];

    x[2]=read_adc(); // lecture de l'échantillon On écrit dans x[2] le signal d'entrée puis on décale le coup d'après
    }

    }
    }

  6. #5
    vede

    Re : timer0 pic18f4550

    re

    je comprend pas bien le principe de ce code,
    où est le timer0? et son interruption?
    et les registres associés (INTCON,TMRO,TMROL,...)

    vede
    ;O]

  7. A voir en vidéo sur Futura
  8. #6
    RISC

    Re : timer0 pic18f4550

    Salut,

    Le plus simple pour avoir un échantillonnage précis avec le convertisseur A/N dans la famille PIC18, est d'utiliser une unité CCP en mode compare qui déclenche automatiquement le lancement d'une conversion. L'unité CCP peut fonctionner à partir du timer1 ou du timer3.

    En choisissant Event Trigger la conversion est directement lancée par le TIMER1 ou 3 ;=)

    A toi de trouver les macros qui vont bien dans CCS...pour moi c'est uniquement le C18 ;=)

    a+

  9. Publicité
  10. #7
    titoff

    Re : timer0 pic18f4550

    Citation Envoyé par vede Voir le message
    re

    je comprend pas bien le principe de ce code,
    où est le timer0? et son interruption?
    et les registres associés (INTCON,TMRO,TMROL,...)

    vede
    ;O]
    RTCC est associé au timer0

  11. #8
    vede

    Re : timer0 pic18f4550

    bonjour,

    avec un 4550...

    bon disons que le timer0 est
    utilisé dans sa configuration
    par défaut, au reset, cad:
    -compteur sur 16bits
    -prescaler=2 et activé
    -utilisation en mode "Internal instruction cycle clock"

    et avec un quartz à 20Mhz, on a
    une instruction executée toute
    les 0,2us...

    et on veut une interruption toute
    les 6,25ms (160Hz)...

    je fais les calculs comme ça:
    0,2 * 2 * x = 6250us
    donc x = 15625...
    et ensuite 65535-15625=49910
    49910/256=194
    49910%256=246
    (65535 c'est l'overflow qui interruptionne)

    aprés dans mon (pseudo)code ça donne:

    void interrupt()
    {
    INTCON.TMR0IF=0 're-enable interrupt
    TMR0L=246 ' on re-positionne le compteur sur 49910
    TMR0H=194 ' on re-positionne le compteur sur 49910
    ADC=.... ' mes routines à executer toutes les 6,25ms...
    }

    void main
    {
    T0CON.TMR0ON=1 'start timer0
    INTCON = %10100000 ' enable timer0 interruption
    TMR0L=246 ' on positionne le compteur sur 49910
    TMR0H=194 ' on positionne le compteur sur 49910
    while (true) wend 'boucle infinie...attente interruption
    }

    et voilà...
    l'interruption est "appelée" toutes les 6,25ms...
    vede
    ;O]
    Dernière modification par vede ; 21/08/2009 à 13h51.

  12. #9
    vede

    Re : timer0 pic18f4550

    Hi .O]

    je crois que j'ai fait fuir titoff ;O]

    vede
    ;O]

  13. #10
    titoff

    Re : timer0 pic18f4550

    Citation Envoyé par vede Voir le message
    Hi .O]

    je crois que j'ai fait fuir titoff ;O]

    vede
    ;O]
    c clair, j'ai pas tous saisi
    Mais je vais regarder ton code de plus près demain matin !!!
    En fait dans ma question du départ, je voulais savoir pourquoi l'étudiant avait mis la valeur 144 dans la variable "suivant" et qu'elle était la valeur du prescaler choisi.

  14. #11
    vede

    Smile Re : timer0 pic18f4550

    Citation Envoyé par titoff Voir le message
    c clair, j'ai pas tous saisi
    Mais je vais regarder ton code de plus près demain matin !!!
    En fait dans ma question du départ, je voulais savoir pourquoi l'étudiant avait mis la valeur 144 dans la variable "suivant" et qu'elle était la valeur du prescaler choisi.
    hi,

    avec 144 comme valeur,
    surement envoyée dans
    TMR0L, en 8 bits, et avec
    0 envoyé dans TMROH si
    c'est en 16bits...
    c'est bizarre...
    car on est pas à 160Hz...
    quelque soit le prescaler...

    j'essaie de t'en dire +, si temps...
    vede
    ;O]

  15. #12
    vede

    Re : timer0 pic18f4550

    re

    si c'est avec la configuration "par défaut"/"au reset"
    du pic, cad, quartz 20Mhz donc 0.2us/instruction et
    compteur 16bits et prescaler=2, on arrive à une période de :

    65535-144=64391
    64391*0.2=13078us
    13078/2=6,53ms...
    =153,..Hz

    vede
    ;O]

  16. Publicité
  17. #13
    vede

    Re : timer0 pic18f4550

    rere

    delà pourquoi 144...
    va falloir lui demander...
    à l'étudiant...

    mais souvent il y a une "dérive"...
    type due au quartz... à la température...
    peut-être qu'avec ce 144, aprés tatonnements,
    il à trouvé un beau 160Hz...en sortie...oscillo...

    vede
    ;O]

  18. #14
    vede

    Re : timer0 pic18f4550

    ps

    avec tout le code, on pourrait
    surement t'en dire plus....

    vede
    ;O]

  19. #15
    vede

    Re : timer0 pic18f4550

    reps : dans ta portion de code,
    on voit pas la config. du prescaler...
    ni du compteur en 8 ou 16bits...
    ni du timer0, et son interruption...
    en fait rien pouvant aider...
    en dehors de : suivant=144

    vede
    ;O]

  20. #16
    vede

    Smile Re : timer0 pic18f4550

    Citation Envoyé par RISC Voir le message
    Salut,

    Le plus simple pour avoir un échantillonnage précis avec le convertisseur A/N dans la famille PIC18, est d'utiliser une unité CCP en mode compare qui déclenche automatiquement le lancement d'une conversion. L'unité CCP peut fonctionner à partir du timer1 ou du timer3.

    En choisissant Event Trigger la conversion est directement lancée par le TIMER1 ou 3 ;=)

    A toi de trouver les macros qui vont bien dans CCS...pour moi c'est uniquement le C18 ;=)

    a+
    re,

    je n'ai jamais utilisé ce mode CCP...
    mais c'est vrai que ça parait idéal...

    vede
    ;O]

  21. #17
    vede

    Re : timer0 pic18f4550

    ps

    et j'ai peut-etre écrit quelques conneries,
    je me rapelle jamais si quand prescaler=2,
    cela veut dire diviser ou multiplier la période...

    hips ;O]....

    et donc je branche toujours une led...
    et je la fait clignoter...via le timer...
    afin de vérifier...le calcul...
    pour commencer...;O]

    vede
    ;O]

  22. #18
    titoff

    Re : timer0 pic18f4550

    Citation Envoyé par vede Voir le message
    ps

    et j'ai peut-etre écrit quelques conneries,
    je me rapelle jamais si quand prescaler=2,
    cela veut dire diviser ou multiplier la période...

    hips ;O]....

    et donc je branche toujours une led...
    et je la fait clignoter...via le timer...
    afin de vérifier...le calcul...
    pour commencer...;O]

    vede
    ;O]
    salut
    As tu un programme qui permet d'allumer une led à chaque interruption ?
    Merci par avance

  23. Publicité
  24. #19
    vede

    Re : timer0 pic18f4550

    hi,

    en reprennant mon exemple creant une interruption
    toute les 6,25ms...et en ajoutant un compteur...
    comptant jusqu'à 1000/6,25=160...(1000=1s)
    on aura une frequence de clignotment de 0,5Hz...
    avec une led sur RB0...

    void interrupt()
    {
    INTCON.TMR0IF=0 're-enable interrupt
    TMR0L=246 ' on re-positionne le compteur sur 49910
    TMR0H=194 ' on re-positionne le compteur sur 49910
    compteur=compteur+1
    if compteur =160
    [
    RB0=not(RB0) 'on inverse l'etat de la sortie/la led....
    compteur=0
    ]
    }

    void main
    {
    compteur=0
    T0CON.TMR0ON=1 'start timer0
    INTCON = %10100000 ' enable timer0 interruption
    TMR0L=246 ' on positionne le compteur sur 49910
    TMR0H=194 ' on positionne le compteur sur 49910
    while (true) wend 'boucle infinie...attente interruption
    }

    vede
    ;O]

  25. #20
    vede

    Re : timer0 pic18f4550

    re,

    et si l'on ne veut pas utiliser de compteur,
    mais génerer directement une interruption
    à chaque seconde, il faut refaire les calculs,
    et utiliser le prescaler, sur 256 par exemple...
    car avec un prescaler de 2, on ne peux arriver
    à une periode de 1s...car...0,2 * 2 * 65535 =26,614ms...
    (on aurait aussu pu prendre prescaler=128...
    mais pas moins...car 0,2 * 64 * 65535 =838,848ms...)

    donc on refait les calculs avec:
    0,2 * 256 * x = 1000000us
    donc x = 19531...
    et ensuite 65535-19531=46004
    46004/256=179
    46004%256=180

    et le code

    void interrupt()
    {
    INTCON.TMR0IF=0 're-enable interrupt
    TMR0L=180 ' on re-positionne le compteur sur 46004
    TMR0H=179 ' on re-positionne le compteur sur 46004
    RB0=not(RB0) ' routine qui s'execute chaque seconde.
    }

    void main()
    {
    T0CON= %10000111 'start timer0 avec prescaler sur 256
    INTCON = %10100000 ' enable timer0 interruption
    TMR0L=180 ' on positionne le compteur sur 46004
    TMR0H=179 ' on positionne le compteur sur 46004
    while (true) wend 'boucle infinie...attente interruption
    }

    voilà, une led sur RB0, clignotera à 0.5Hz...

    vede
    ;O]

  26. #21
    vede

    Re : timer0 pic18f4550

    hi,

    alors...ça clignote bien ? ;O]

    vede
    ;O]

Sur le même thème :

Discussions similaires

  1. Timer0
    Par 1ergel dans le forum Électronique
    Réponses: 6
    Dernier message: 08/06/2009, 19h16
  2. Pic 16f887 timer0
    Par Snoopy85 dans le forum Électronique
    Réponses: 30
    Dernier message: 11/03/2009, 08h43
  3. Timer1 et timer0
    Par guifou dans le forum Électronique
    Réponses: 4
    Dernier message: 18/01/2009, 06h16
  4. Problème Timer0 PIC
    Par guijac92 dans le forum Électronique
    Réponses: 14
    Dernier message: 01/11/2008, 11h06
  5. 4 secondes Timer0
    Par bimo dans le forum Électronique
    Réponses: 8
    Dernier message: 29/06/2006, 15h53
Découvrez nos comparatifs produits sur l'informatique et les technologies.