TIMER0 sur atmega8 ne se déclenche pas

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

/*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

Reply to
Eric
Loading thread data ...

Le 14/05/2013 14:26, Eric a écrit :

Bien sûr!

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" ...

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)

Cordialement,

--
|Claude Safon, AgriPacTe,                        (agripacte@wanadoo.fr)| 
|----------------------------------------------------------------------| 
|- Pour une nouvelle agriculture méditerranéenne, écologiq 
ue, durable -| 
?---------------------------------------------------------------- 
------?
Reply to
AgriPacTe(News)

Merci pour votre réponse

TIMSK|=(1 toutes les interuptions)

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

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

vu plus haut ;-)

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

Reply to
Eric

Le 14/05/2013 15:30, Eric a écrit :

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)

rents

e.

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

Cordialement,

--
|Claude Safon, AgriPacTe,                        (agripacte@wanadoo.fr)| 
|----------------------------------------------------------------------| 
|- Pour une nouvelle agriculture méditerranéenne, écologiq 
ue, durable -| 
?---------------------------------------------------------------- 
------?
Reply to
AgriPacTe(News)

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

Reply to
Eric

"Eric"

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 )

Reply to
Jean-Christophe

// 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) { // ... ? }

Reply to
Jean-Christophe

"Eric"

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

Reply to
Jean-Christophe

Le 14/05/2013 18:23, Jean-Christophe a écrit :

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,                        (agripacte@wanadoo.fr)| 
|----------------------------------------------------------------------| 
|- Pour une nouvelle agriculture méditerranéenne, écologiq 
ue, durable -| 
?---------------------------------------------------------------- 
------?
Reply to
AgriPacTe(News)

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 ...

Reply to
Jean-Christophe

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.