TIMER0 sur atmega8 ne se déclenche pas

Do you have a question? Post it now! No Registration Necessary

Translate This Thread From French to

Threaded View
Bonjour à tous

Je sollicite votre aide car je suis depuis plusieurs jours sur un  
problème que je ne parviens pas à résoudre.
J?ai débuté l?étude des microcontrôleurs.
J?ai réalisé le traditionnel « Hello world » de la led qui clignote pour  
valider que tout fonctionne parfaitement.
Maintenant je souhaite passer l?étape suivante : multiplexage + timer  
pour faire un basic compteur 3 chiffres.
Voir mon programme plus bas
Le multiplexage est OK j?ai bien 999 qui s?affiche correctement.
Pour la clarté du programme je n?ai pas détaillé les fonctions :

clear_all()         efface les chiffres
DigitTo7SegEncoder    renvoies les digits à allumer
OutPort()          allume effectivement les digits fournit par DigitTo7SegEncoder
affiche()  elle appelle les 3 fonctions précédentes pour l?affichage des  
3 chiffres

J?ai choisi le timer0  (c?est le plus simple et je ne cherche pas pour  
le moment de précision temporelle) pour décrémenter le compteur  
(variable compte)
Là où se situe mon problème c?est concernant le timer ; il ne se  
déclenche JAMAIS !!!
J?ai même mis une led « mouchard » pour vérifier si la procédure est  
exécutée au moins une fois (elle ne s?est jamais allumée)
Après avoir épluché le web en long en large et en travers, je suis en  
manque d?idée.
D?ailleurs vous remarquerez une fonction delay que j?ai réécrit.
Avant j?utilisais delay_loop_1 ou 2 de delay.h car j?avais lu que ces  
fonctions utilisaient les timers et j?ai pensé que le problème pouvait  
venir de là mais apparemment non.

Précision peut être utile :
Micro : ATMEGA8 16PU (sans quartz - 1Mhz)  les fuses ont été laissé  
défaut usine
Compilé avec atmel studio 6 (en procédure debug  pas à pas le timer est  
bien exécuté)
Optimisation compilation: -O2
Programmateur : série
Logiciel : ponyprog

Je me vois mal continuer sur les micros sans utiliser les timer ;-)
Merci d?avance pour votre aide

Mon chef d??uvre un peu bancal :

#define F_CPU    1000000UL
#include <avr/io.h>
#include <avr/interrupt.h>

/*Global Variables Declarations*/
volatile uint16_t  compte = 999;
unsigned char digit1;
unsigned char digit2;
unsigned char digit3;

  /*Function Declarations*/
unsigned char DigitTo7SegEncoder(unsigned char digit);
void clear_all();
void affiche();
void OutPort(unsigned char val);
void delay();

void main()
{
// paramétrage du timer
TCCR0|=(1<<CS02);
TIMSK|=(1<<TOIE0);
TCNT0=0;
sei();

DDRC=0b00111111; // PC0 à PC5 en sorties pour les digit 2..3..4....7
DDRB=0b00000011; // PB1 en sortie pour le digit 1
//PB2 comme « mouchard » du timer
DDRD=0b11100000; //  3 bits du port D pour piloter les 3 chiffres
                    
PORTB&=~_BV(PB2) ; // je m'assure que la led « mouchard » est éteinte
                    
    digit1=compte/100;
    digit2=(compte-100*digit1)/10;
    digit3=compte-100*digit1-10*digit2;
    
        while(1)
        {
            affiche();
        }
}

void delay()     
void affiche()  
void clear_all()
unsigned char DigitTo7SegEncoder(unsigned char digit)  
void OutPort(unsigned char val)  

ISR(TIMER0_OVF_vect)     // Le microcontroleur n'arrive jamais ici !!!
{
PORTB|=_BV(PB2);  // allume la LED si le timer
                    //est déclenché même une  seule fois
                   // elle ne sera plus jamais éteinte
compte--;
}

Re: TIMER0 sur atmega8 ne se déclenche pas
Le 14/05/2013 14:26, Eric a écrit :
Quoted text here. Click to load it


Bien sûr!

Quoted text here. Click to load it

Je ne connais pas ce µC, donc je ne pourrais que donner des pistes  
générales, souvent simples ... mais par expérience ... pro
bables.

Ce que vous nous présentez, comme code, dépend fortement de
l'environnement (que que vous mettez dans les "#include"); on ne voit
donc pas précisément dans quel environnement on est, mais:

- attendre une interruption suppose qu'on l'a autorisée; souvent (se
lon
   le µC), on a deux bits d'autorisation
   . celui d'une interruption particulière (ici le timer0)
   . celui des interruptions qui est général (autorise/dès
-autorise
     toutes les interuptions)
   parfois plus (rare)

- faire tourner le timer suppose une source ... qui "tourne" ...

Quoted text here. Click to load it

Relisez bien votre initialisation du timer ... et surtout ce qu'en
donne l'environnement par rapport à la datasheet du composant ...
(que sont "CS02", "TOIE0", et les états initiaux de "TCCR0" et "TIMS
K",
  - vous utilisez un |= - ... sei(sans argument) ... )

Quoted text here. Click to load it


Parfait; cela vaut un oscillo (surtout pour du transitoire) mais
essayez plutôt d'appliquer ce genre de philosophie à ce qui doi
t
déclencher (et non à l?interruption)

Quoted text here. Click to load it

Cordialement,
--  
|Claude Safon, AgriPacTe,                        ( snipped-for-privacy@wanadoo.fr)|
|----------------------------------------------------------------------|
We've slightly trimmed the long signature. Click to see the full one.
Re: TIMER0 sur atmega8 ne se déclenche pas
Merci pour votre réponse


Quoted text here. Click to load it

TIMSK|=(1<<TOIE0)        bit TOIE0 du registre TIMSK à 1, c'est là qu'on  
active le timer0

Quoted text here. Click to load it

sei() met le bit 7 (I) de SREG à 1 c'est là qu'on active l'ensemble des  
interruptions

Quoted text here. Click to load it

CS02 CS01 CS00 définissent celà
aucun problème (je pense) de ce côté
prescaller à 256 par rapport à l'oscillo interne
1Mhz / 256 : on bip tous les 3906 fois par seconde
compteur 8 bit : on déborde à 256 : donc déclenchement de l'interruption  
3906/256 = environ 15 fois par seconde
Quoted text here. Click to load it

vu plus haut ;-)

Quoted text here. Click to load it

je ne vois pas d'autres bits de registres à modifier.
je tente de revoir la datasheet mais je sèche, d'autant que différents  
exemples sur internet ne mentionnent aucun problème spécifique.

cordialement


Re: TIMER0 sur atmega8 ne se déclenche pas
Le 14/05/2013 15:30, Eric a écrit :
Quoted text here. Click to load it
e l'interruption

Dans la boucle principale avant affiche, rajoutez quelque chose comme  
compte = timer0 (le registre du timer) pour voir si il bouge ...
(avec une tempo si vous voulez mieux voir, mais si ça bouge, ça
 bouge)

Quoted text here. Click to load it
rents
e.

Ok. Attendons l'avis de ceux qui connaissent plus spécifiquement ce  
µC.

Cordialement,
--  
|Claude Safon, AgriPacTe,                        ( snipped-for-privacy@wanadoo.fr)|
|----------------------------------------------------------------------|
We've slightly trimmed the long signature. Click to see the full one.
Re: TIMER0 sur atmega8 ne se déclenche pas
Le 14/05/2013 16:06, AgriPacTe(News) a écrit :
 >
 > Dans la boucle principale avant affiche, rajoutez quelque chose comme
 > compte = timer0 (le registre du timer) pour voir si il bouge ...
 > (avec une tempo si vous voulez mieux voir, mais si ça bouge, ça bouge)

une erreur s'est glissé dans mon programme il devrait effectivement y  
avoir du code.
c'est ce qui arrive à force de "bidouiller" le code à la volée
  mais çà ne remet pas en cause le non déclenchement de l'interruption  
puisque la led ne s'allume pas
néanmoins j'ai suivi votre conseil .... la boucle principale devient donc :

while(1)
        {
            char c=TCNT0;
            digit1=c/100;
            digit2=(c-100*digit1)/10;
            digit3=c-100*digit1-10*digit2;
            affiche();
        }

je vois les digit s'affoler, donc le compteur compte
il y a donc bien un problème sur le déclenchement lors du débordement du  
compteur

 >
 >>> ...
 >>>> ...
 >> je ne vois pas d'autres bits de registres à modifier.
 >> je tente de revoir la datasheet mais je sèche, d'autant que différents
 >> exemples sur internet ne mentionnent aucun problème spécifique.
 >
 > Ok. Attendons l'avis de ceux qui connaissent plus spécifiquement ce µC.

 >
 > Cordialement,


Re: TIMER0 sur atmega8 ne se déc lenche pas
"Eric"
Quoted text here. Click to load it


D'aprés le code ci-dessus, le char 'c' déclaré en local
n'est initialisé à la valeur de TCNT0 qu'une seule fois,
lors de sa déclaration ... donc la valeur de 'c' ne devrait
jamais bouger, même si TCNT0 bouge ...
Si les digits bougent alors le bug est
peut-être en amont dans la fonction affiche()

 while(1)
 {
 char c;
 c = TCNT0; // recharge TCNT0 à chaque tour de boucle
 digit1=c/100;
 digit2=(c-100*digit1)/10;
 digit3=c-100*digit1-10*digit2;
 affiche();
 }

PS : Parenthèser les calculs pour digit[1,2,3] ou utiliser
la fonction 'modulo' ( '%' ou '' suivant le compilo )
  


Re: TIMER0 sur atmega8 ne se déc lenche pas
// suggestion
while(1)
{
char c;
c = TCNT0; // recharge la valeur courante
digit3 = c % 10; // unités
digit2 = (c /= 10) % 10; // dizaines
digit1 = c / 10; // centaines
affiche();
}

// test
while(1)
{
char c;
c = 123; // pour tester l'affichage
digit3 = c % 10;
digit2 = (c /= 10) % 10;
digit1 = c / 10;
affiche();
}

void affiche(void)
{
// ... ?
}

  


Re: TIMER0 sur atmega8 ne se déclenche pas
"Eric"
Quoted text here. Click to load it

Es-tu sûr que ce n'est pas plutôt :

TCCR0 |= CS02;
TIMSK |= TOIE0;

... ?
  


Re: TIMER0 sur atmega8 ne se déclenche pas
Le 14/05/2013 18:23, Jean-Christophe a écrit :
Quoted text here. Click to load it

Il faut voir cela dans les "#include" ...
c'était ma question sur l'environnement.

Si CS02 est le n° de bit (=2) c'est lui qui est bon ...
Si CS02 est le masque du 2ème bit (=4) c'est toi qui est bon ...

Cela se lit dans l'environnement, mais d'après les exemples donné
s sur
le web, c'est son hypothèse qui semble juste; sauf ... copie  
intempestive d'erreur (cela arrive plus souvent qu'on ne croit parfois)

Cordialement,
--  
|Claude Safon, AgriPacTe,                        ( snipped-for-privacy@wanadoo.fr)|
|----------------------------------------------------------------------|
We've slightly trimmed the long signature. Click to see the full one.
Re: TIMER0 sur atmega8 ne se déc lenche pas
Quoted text here. Click to load it



Oui c'est bien ca ( j'ai vérifié depuis )

Par contre, sa LED étant connectée sur le PORTB bit 2
( c'est-à-dire 0b00000100 ) il doit configurer cette pin
en sortie ( DDRB = 0b00000100 ) alors qu'il initialise
DDRB = 0b00000011 donc même si l'interruption tombe
et qu'elle met cette sortie à 1 ( PORTB =| 4 )
la LED ne s'allumera pas ...
  


Re: TIMER0 sur atmega8 ne se déclenche pas
"Eric"
Quoted text here. Click to load it

Si PB2 est bien le bit [ 0b00000100 ]
alors il te faut
DDRB = 0bxxxxx1xx; // PB2 comme « mouchard » du timer

Puis dans l'interruption

 ISR(TIMER0_OVF_vect)     // Le microcontroleur n'arrive jamais ici !!!
 {
 PORTB |= 4;  // allume LED si timer déclenche
 compte--;
 }

  


Site Timeline