Bienvenue aux nouveaux arrivants sur FantasPic !

- Pensez à lire les règles durant votre visite, il n'y en a pas beaucoup, mais encore faut-il les respecter .
- N’hésitez pas à faire des remarques et/ou suggestions sur le Forum, dans le but de l'améliorer et de rendre vos prochaines visites plus agréables.
- Vous pouvez regarder votre "panneau de l'utilisateur" afin de configurer vos préférences.
- Un passage par "l'utilisation du forum" est recommandé pour connaître les fonctionnalités du forum.

--- L’équipe FantasPic ---
Forum général sur le langage C !

Modérateur : Jérémy

Fonction DELAY à partir de TIMER0 qui ne marche pas
Superphénix
Débutant
Débutant
Messages : 54
Enregistré en : mars 2020

#1 Message par Superphénix » jeu. 25 mai 2023 04:42

Bonjour

Je veux créé une fonction DELAY() qui créé simplement un retard comme son nom l'indique.
Pour ça, j'utilise le TIMER0 d'un PIC18LF2620. Mais mon timer à un comportement bizarre. Enfaite il marche de temps en temps. Et quand il marche pas il fait ce genre de chose :
J'ai réduit le programme au maximum pour le poster ici. Ce que fait donc le bout de code ci dessous est qu'il inverse mes 2 DELAYs. J'ai l'impression que'il fait en premier DELAY(165, 171) ; puis AFF7SEG('1') ; puis DELAY(254, 199) ; puis AFF7SEG(' ') ; etc....
Je suis sur qu'il s'agit encore d'un problème évident, un oubli quelque part, mais là j'ai passé toute la soirée et je ne trouve pas. :cry:

Code : Tout sélectionner

#include <XC.h>
#include <stdio.h>
#include <stdlib.h>

#pragma config OSC = ECIO6
#pragma config FCMEN = OFF
#pragma config IESO = OFF
#pragma config BOREN = OFF
#pragma config MCLRE = OFF
#pragma config PBADEN = OFF
#pragma config WDT = OFF
#pragma config LVP = OFF
#pragma config STVREN = OFF

#define _XTAL_FREQ 8000000

void DELAY(unsigned char, unsigned char) ;
void AFF7SEG(unsigned char) ;

int main(int argc, char** argv)
{
    TRISA   = 0b10000000 ;
    TRISB   = 0b00111100 ;
    TRISC   = 0b00011000 ;
    PORTA   = 0b00000000 ;
    PORTB   = 0b00000000 ;
    PORTC   = 0b00000000 ;

    T0CON = 0b00000101 ;        // EN:0(pour l'instant) , 16bits:0 , F=CLK/4:0 , low-to-high_transition:0 , Prescalar:OUI:0 , PRE=1/64:101

    PORTBbits.RB0=1 ; PORTBbits.RB1=1 ;

    AFF7SEG('1') ; DELAY(165, 171) ; AFF7SEG(' ') ; DELAY(254, 199) ;
    AFF7SEG('2') ; DELAY(165, 171) ; AFF7SEG(' ') ; DELAY(254, 199) ;
    AFF7SEG('3') ; DELAY(165, 171) ; AFF7SEG(' ') ; DELAY(254, 199) ;
   
    return (EXIT_SUCCESS);
}

void AFF7SEG(unsigned char n)
{
    switch(n)
    {
        case '1' : PORTA = 0b01000001 ;
        break ;
        case '2' : PORTA = 0b00111011 ;
        break ;
        case '3' : PORTA = 0b01101011 ;
        break ;
        default : PORTA = 0b00000000 ;
    }
}

void DELAY(unsigned char TMRH, unsigned char TMRL)
{
    TMR0L = TMRL ;
    TMR0H = TMRH ;
    T0CONbits.TMR0ON = 1 ;
    while(INTCONbits.TMR0IF==0) ;
    T0CONbits.TMR0ON = 0 ;
    INTCONbits.TMR0IF = 0 ;
}
/*
DELAY(254, 199) ; // 10ms +0,1600%
DELAY(165, 171) ; // 740ms +0,0000%
*/

Fonction DELAY à partir de TIMER0 qui ne marche pas
satinas
Expert
Expert
Messages : 1225
Enregistré en : novembre 2015

#2 Message par satinas » jeu. 25 mai 2023 05:26

Bonjour,
Même remarque que pour albertdela. Le timer 0 est un timer 16 bits sur un processeur 8 bits. On lit ou on écrit TMR0 en 2 instructions, et si entre ces 2 instructions TMR0H a été incrémenté le résultat est incorrect. Pour éviter cela, ils ont créé un double buffer pour TMR0H, permettant de donner un accès simultané à TMR0H et TMR0L.
On a pas un accès direct au TMR0H interne du timer, sa valeur est retournée ou modifiée uniquement à l'instant où on lit ou écrit TMR0L. Le registre TMR0H joue le rôle d'intermédiaire. On lit toujours TMR0L avant TMR0H. On écrit toujours TMR0H avant TMR0L.
Lorsque tu écris TMR0H, cela ne va pas dans le registre interne du timer, il stocke cette valeur en attendant de l'utiliser lors de l'écriture de TMR0L. C'est ce qui explique ce décalage, seul TMR0L était correctement initialisé, TMR0H récupérait la valeur de l'appel précédent à Delay. Et si ce n'est pas cela on en reparle.
En cas de problème il est utile de lire les premières pages du datasheet, celles du timer0 parle de ce double buffer, sans doute pas évident à comprendre la première fois :)

Fonction DELAY à partir de TIMER0 qui ne marche pas
Superphénix
Débutant
Débutant
Messages : 54
Enregistré en : mars 2020

#3 Message par Superphénix » jeu. 25 mai 2023 16:26

Effectivement, ça a résolut mon problème. Merci !
En plus je l'avais lu ça, il y a quelques mois au début du projet, mais depuis complètement oublié... :roll:

Fonction DELAY à partir de TIMER0 qui ne marche pas
SarahJoly789
Membre
Membre
Messages : 2
Enregistré en : mai 2023
Contact :

#4 Message par SarahJoly789 » ven. 23 juin 2023 13:58

Salut,
Je pense que ton problème vient du fait que tu n'as pas configuré correctement ton timer0 pour créer un retard. Tu dois vérifier que tu as choisi le bon mode de fonctionnement, le bon prescaler et la bonne valeur initiale du timer0
Tu dois aussi t'assurer que tu acquittes bien le flag TMR0IF à chaque débordement du timer0
Tu peux aussi utiliser un oscilloscope ou un multimètre pour mesurer la fréquence de ton signal et vérifier si elle correspond à ton attente.
Voilà ce que je peux te dire pour t'aider. Bon courage !
Visiter notre site : MultiHardware


Retourner vers « Langage C »

Qui est en ligne

Utilisateurs parcourant ce forum : Aucun utilisateur enregistré et 44 invités