mardi 29 mai 2012

télécommande sur entrée microphone suite

Pour faire suite à ma chronique d'hier voici une version à 7 boutons de la télécommande sur entrée microphone avec le code source associé. Resterais à écrire le programme pour PC hote qui doit décoder les tonalités et les traduire en commandes. Un controle activeX dans ce genre .

shéma électronique



code source

#include

__CONFIG _WDTE_OFF & _MCLRE_OFF & _CP_OFF

;;; constantes ;;;;;;;;;;;;;;;;;
OPTION_INI EQU 0x01
TRIS_INI EQU B'1011' ; GP2 en mode sortie

; fréquences tonalités
FR1 EQU .697
FR2 EQU .770
FR3 EQU .852
FR4 EQU .941
FR5 EQU .1209
FR6 EQU .1336
FR7 EQU .1477
FR8 EQU .1633

; demi-péridodes
HPT1 EQU ~(.125000/FR1)
HPT2 EQU ~(.125000/FR2)
HPT3 EQU ~(.125000/FR3)
HPT4 EQU ~(.125000/FR4)
HPT5 EQU ~(.125000/FR5)
HPT6 EQU ~(.125000/FR6)
HPT7 EQU ~(.125000/FR7)
HPT8 EQU ~(.125000/FR8)


; comptes pour une durée de 20msec
LAPSE1 EQU ~(FR1*.20/.1000)
LAPSE2 EQU ~(FR2*.20/.1000)
LAPSE3 EQU ~(FR3*.20/.1000)
LAPSE4 EQU ~(FR4*.20/.1000)
LAPSE5 EQU ~(FR5*.20/.1000)
LAPSE6 EQU ~(FR6*.20/.1000)
LAPSE7 EQU ~(FR7*.20/.1000)
LAPSE8 EQU ~(FR8*.20/.1000)


;;; macros ;;;;;;;;;;;;;;;;;;
#define SW1 GPIO, GP0
#define SW2 GPIO, GP1
#define SW3 GPIO, GP3
#define SW4 GPIO, GP1
#define SW5 GPIO, GP3
#define SW6 GPIO, GP0
#define SW7 GPIO, GP3

#define TONE_OUT GPIO, GP2



delay_half_period macro
movfw half_period
movwf TMR0
movfw TMR0
skpz
goto $-2
endm

;;; variables ;;;;;;;;;;;;;;
cblock 8
delay_cntr : 1
button : 1
half_period : 1
endc

;;; code ;;;;;;;;
org 0
init
movwf OSCCAL
movlw OPTION_INI
option
movlw TRIS_INI
tris GPIO

main
call read_buttons
movf button, F
skpnz
goto main
call tone
; movlw .30
; movwf delay_cntr
; call delay_ms
goto main

delay_ms
movlw 5
movwf TMR0
movfw TMR0
skpz
goto $-2
decfsz delay_cntr
goto delay_ms
retlw 0

tone
movfw button
call lapse_table
movwf delay_cntr
movfw button
call tones_table
movwf half_period
tone01
bcf TONE_OUT
delay_half_period
bsf TONE_OUT
delay_half_period
incfsz delay_cntr
goto tone01
retlw 0

read_buttons
movfw GPIO
movwf button
comf button, F
movlw 0xB
andwf button, F
movlw 4
subwf button, F
skpc
addwf button, F
return



tones_table
addwf PCL, F
dt 0
dt HPT1
dt HPT2
dt HPT3
dt HPT4
dt HPT5
dt HPT6
dt HPT7
dt HPT8

lapse_table
addwf PCL, F
dt 0
dt LAPSE1
dt LAPSE2
dt LAPSE3
dt LAPSE4
dt LAPSE5
dt LAPSE6
dt LAPSE7
dt LAPSE8

end



dimanche 27 mai 2012

alimenter un MCU par l'entrée microphone

L'entrée microphone des ordinateurs fournis un voltage car les microphones actuels sont à base d'électret. Hors ces microphones contiennent un transistor JFET pour amplifier le signal provenant de l'électret, il faut donc alimenter ce transistor. J'ai mesuré le voltage à circuit ouvert sur différent ordinateurs et il varie d'un ordinateur à l'autre. Par exemple sur mon PC Dell il est à 5 volt alors que sur mon portable HP Pavilion il est à 3,3 volt comme sur d'autres ordinateurs portables sur lequel j'ai pris une mesure. Hors la majorité des MCU PIC acceptent une alimentation entre 2volt et 5,5 Volt. Certains modèles fonctionnent avec une alimentation comprise entre 1,8 et 3,6 volt. Mais cette alimentation sur l'entré microphone ne peut fournir qu'un très faible courant. Quoi qu'il en soit je me suis demandé si on pourrait alimenté un petit MCU avec ça, et la réponse est oui. Dans cette chronique je vais présenter le résultat de mes expériences.

Circuit de test

Fonctionnement

A chaque bouton SW1 à SW3 est à associée une tonalité de fréquence différente. Lorsqu'on presse un bouton la tonalité correspondante est envoyée via GP2 à l'entrée microphone. La résistance R1 limite l'amplitude du signal et la diode D1 empêche C1 et C2 de se décharger à travers R1 lorsque GP2 est à bas niveau.Sur mon HP Pavilion lorsqu'aucun bouton n'est enfoncé la tenstion sur Vdd est de 2,3 Volt lorsque je garde un bouton enfoncé la tension baisse à 1,87Volt. Même si la spécification du PIC10F202 indique un Vdd minninum de 2Volt ça fonctionne quand même. Pour rester dans les spec. et empêcher Vdd de tomber sous les 2 Volts j'ai limité la durée des tonalités à 20msec et inséré un délais de 30msec entre chaque tonalité. Ça permet aux condensateurs C1 et C2 de se recharger. Avec cette technique Vdd demeure au dessus de 2 volt. L'inconvénient est que la tonalité entendue dans le haut-parleur. est entrecoupée. J'ai fait un enregistrement avec et sans interruption sonore. Les fichiers .WMA sont avec délais et sans délais. Même en enlevant le condensateur C2 du circuit ça fonctionne mais le timbre est altéré car l'onde devient triangulaire plutôt que carrée.

code source

#include

__CONFIG _WDTE_OFF & _MCLRE_OFF & _CP_OFF

;;; constantes ;;;;;;;;;;;;;;;;;
OPTION_INI EQU 0x01
TRIS_INI EQU 0xB ; GP2 en mode sortie
; fréquences tonalités
FR1 EQU .697
FR2 EQU .770
FR3 EQU .852
FR4 EQU .941
FR5 EQU .1209
FR6 EQU .1336
FR7 EQU .1477
FR8 EQU .1633

; demi-péridodes
HPT1 EQU ~(.125000/FR1)
HPT2 EQU ~(.125000/FR2)
HPT3 EQU ~(.125000/FR3)
; comptes pour une durée de 20msec
LAPSE1 EQU ~(FR1*.20/.1000)
LAPSE2 EQU ~(FR2*.20/.1000)
LAPSE3 EQU ~(FR3*.20/.1000)



;;; macros ;;;;;;;;;;;;;;;;;;
#define SW1 GPIO, GP0
#define SW2 GPIO, GP1
#define SW3 GPIO, GP3
#define TONE_OUT GPIO, GP2

delay_us macro
movfw half_period
movwf TMR0
movfw TMR0
skpz
goto $-2
endm

;;; variables ;;;;;;;;;;;;;;
cblock 8
half_period : 1
delay_cntr : 2
endc

;;; code ;;;;;;;;
org 0
init
movwf OSCCAL
bcf OSCCAL, 0
movlw OPTION_INI
option
movlw TRIS_INI
tris GPIO

main
btfss SW3
goto tone3
btfss SW2
goto tone2
btfsc SW1
goto kill_time
tone1
movlw LAPSE1
movwf delay_cntr
movlw HPT1
goto main01
tone2
movlw LAPSE2
movwf delay_cntr
movlw HPT2
goto main01
tone3
movlw LAPSE3
movwf delay_cntr
movlw HPT3
main01
movwf half_period
call tone
kill_time
goto main
; ajouter ce délais si le Vdd descent trop bas
; va permettre à Vdd de remonter
; mais la tonalité sera interrompue pendant 30msec à tous les 20msec.
movlw .30
movwf delay_cntr
call delay_ms
goto main


tone
bcf TONE_OUT
delay_us
bsf TONE_OUT
delay_us
incfsz delay_cntr
goto tone
retlw 0

delay_ms
movlw .5
movwf TMR0
movfw TMR0
skpz
goto $-2
decfsz delay_cntr
goto delay_ms
retlw 0


end

Mais à quoi ça peut servir?

En fait cette idée mais venue en voyant sur internet un gamepad pour iPhone connecté à celui-ci par l'entré micro. J'ai donc essayé d'imaginer comment ça fonctionnait et j'ai testé l'idée. L'ordinateur n'a qu'à utiliser un programme FFT pour décoder les tonalités et convertir celle-ci en commandes pour les jeux. J'ai testé une variante qui consiste au lieu d'associé à chaque bouton une tonalité, à envoyer un code binaire pour chaque touche par AFSK (Audio Frequency Shift keying). Cette technique était utilisé dans les années 70 pour enregistrer et lire des programmes sur cassettes audio. La fonction pour envoyer un code binaire à l'entrée microphone est la suivante.

afsk ; audio frequency shift keying
movlw .10
movwf bitcnt
movfw button
movwf temp
bcf STATUS, C
next_bit
movlw 2
btfsc STATUS, C
movlw 4
movwf cyclecnt
movlw ZERO_TONE
btfsc STATUS, C
movlw ONE_TONE
movwf half_period
bit_loop
bcf TONE_OUT
delay_us
bsf TONE_OUT
delay_us
decfsz cyclecnt
goto bit_loop
decf bitcnt,F
skpnz
retlw 0
bsf STATUS, C
rrf temp,F
goto next_bit

idée de projet

En utilisant un PIC12F1822 qui est un modèle XLP (ultra low power) et en le faisant fonctionner à la plus basse fréquence possible pour réduire la consommation au mininum il serait possible de fabriquer un mini-synthéseur alimenter par la prise micro et qui se servirait de l'ordinateur pour amplifier et faire entendre les notes. On pourrait enregistrer ses propres créations musicales. Voici de quoi pourrait avoir l'air un tel circuit. Avec 5 entrée Digitale pour les switch et des diodes 1N4148 on peut coder 31 touches de clavier. On réserve RA5 pour la sortie. Seul inconvénient un seule touche peut-être utilisé à la fois.





lundi 21 mai 2012

utilisation du WDT

Ajourd'hui je vais présenter le Watch Dog Timer (minuterie chien de garde), abrégé WDT dans la suite. Tous les micro-controlleurs même le plus simple possède un périphérique WDT. Ce nom peut paraître curieux pour un périphérique de micro-controlleur mais à l'orgine cette minuterie a été conçu pour contrôler le bon fonctionnement du MCU. Dans ce rôle le logiciel remet le compteur du WDT à zéro à intervalle régulier avant qu'il n'expire. Si il y a une malfonction du système et que la minuterie n'est pas réinitilisé à l'expiration du délais le WDT déclenche un RESET et la routine POST1 au redémarrage du MCU peut vérifier si la réinitialisation a été causé par le WDT et agir en conséquence par exemple en signalant une alarme, d'où le nom du périphérique.
A moins d'être désactivé le WDT fonctionne continuellement même lorsque le MCU est en mode inactif car il possède son propre oscillateur RC. Dans l'exemple que je vais donné il s'agit d'un MCU PIC10F202. Dans tous les projets que j'ai présenté jusqu'ici le WDT était désactivé par la directive de configuration:
__config  _WDTE_OFF
Pour l'activer la directive est:
__config  _WDTE_ON
Lorsque le WDT est actif sa minuterie roule continuellement et lorsque le compteur passe de 0xFF à 0x00 un événement est déclenché. Dans le cas du MCU PIC10F202 si le MCU est en mode exécution il sera réinitialisé par contre s'il est en mode inactif (standby) il est réininitialisé et mis en mode exécution. Dans le registre STATUS il y a 2 bits d'état reliés au WDT le bit /TO pour Time Out et le bit /PD pour Power Down. Lors de la mise sous tension les 2 bits sont mis à 1. Lorsque la minuterie du WDT expire le bit /TO est mis à zéro. Lorque le MCU est en mode exécution et que l'instruction sleep est exécuté, le bit /PD est mis à zéro et le MCU passe en mode inactif. Ces 2 bits sont utilisés pour déterminer quel événement a déclenché une réinitialisation du MCU.

A part sa fonction de chien de garde le WDT peut-être aussi utilisé pour économiser l'énergie. Dans l'exemple très simple que je vais présenté ici c'est ce à quoi il est utilisé. Il y a 2 instructions qui réinitialisent le compteur du WDT, CLRWDT et SLEEP. la première est utilisée lorqu'on veut éviter que le WDT déclenche une réinitialisation du MCU et la deuxième lorsqu'on veut faire passé le MCU en mode inactif. Dans ce dernier cas lorsque la minuterie du WDT expire le MCU réinitialise et repasse en mode normal.

L'utilisation est la suivante, on met le MCU en mode inactif avec l'instruction sleep. Dans ce mode l'oscillateur principal est arrêté et l'exécution est suspendu mais le WDT fonctionne toujours. En mode inactif le MCU dépense environ 150nA ce qui évite de drainer même la plus petite pile. Lorsque la minuterie du WDT expire le MCU réinitialise et exécute à nouveau les instructions à partir de l'adresse 0x00. Dans cet exemple d'un vérificateur de continuité quelques instructions sont utilisées pour vérifier l'état de l'entrée GP3. Si elle est à zéro c'est que les sondes sont en court-circuit et donc que l'appareil est utilisé. Alors le logiciel boucle avec une instruction clrwdt à chaque tour pour éviter que le MCU ne soit réinitialisé par le WDT. Dans cette boucle on vérifie continuellement l'état de l'entrée GP3 et on fait entendre le son qui signale la continuité. Tant que GP3 demeure à zéro la boucle s'exécute sinon ont sort de la boucle et on remet le MCU en mode inactif.

Ce détecteur de continuité peut fonctionner avec une pile au lithium CR2032 et tant que les sondes sont ouvertes il ne dépense qu'une quantité insignifante de courant, la pile peut donc demeurée branchée en permanance. Lorsqu'il n'y pas de diviseur affecté au WDT celui-ci expire à tous les 18 millisecondes. Dans cet exemple j'ai affecté le diviseur au WDT avec un diviseur de 1:16. de sorte que la minuterie du WDT expire à tous les 288 millisecondes. Donc à cet intervalle le MCU repart et l'état sur GP3 est vérifié et si c'est à 1 le MCU est remis en mode inactif. Donc le MCU ne fonctionne que quelques micro-secondes à toutes les 288 millisecondes. Mais pour l'utilisateur c'est comme si l'appareil était toujours en fonction car au moment ou il met les sondes en court-circuit la DEL s'allume et il entend la tonalité. En réalité il y a un délais maximal de 288 millisecondes entre le moment ou il court-circuite les sondes et le moment ou la DEL et la tonalité sont activé. Lorsque les sondes sont en court-circuit, avec une alimentaion de 3 volt le courant est de 12 milli-ampères.

code source

  include <P10F202.INC>
   __config _WDTE_ON & _MCLRE_OFF & _CP_OFF

;;; constantes ;;;;;;;;;;;;;;

#define AUDIO GPIO, GP2
#define PROBE GPIO, GP3
#define LED GPIO, GP0
#define OPTION_INI 0x9C
#define TRIS_INI 0x0A

FREQUENCY EQU .4000 ;
HALF_PERIOD EQU .2000000/FREQUENCY

;;;;;;;;;; macros ;;;;;;;;;;;

delay_us macro delay
   movlw ~(delay/3)
   movwf delay_cntr
   incfsz delay_cntr
   goto $-1
   endm

audio_pulse macro
   bsf AUDIO
   delay_us HALF_PERIOD
   bcf AUDIO
   delay_us HALF_PERIOD
   endm

;;;; variables ;;;;;;;;;;;;;

delay_cntr EQU 8

;;;;; code ;;;;;;;;;;;;;;;;;

   org 0
   btfsc STATUS, NOT_TO ; on initialise OSCCAL
   movwf OSCCAL ; seulement à la mise sous-tension.
   bcf OSCCAL, 0
   movlw OPTION_INI
   option
   movlw TRIS_INI
   tris GPIO
   clrf GPIO

;;;;; procedure principale ;;;;;;
main
   bsf LED
   btfsc PROBE
   goto sleep_mode
   clrwdt
   audio_pulse
   goto main
sleep_mode
   bcf LED
   sleep

   end


mercredi 16 mai 2012

Micro Simon complété

J'ai finalement complété le projet Micro Simon. tous les fichiers sont ici.

Caractéristiques

Il y a 3 modes jeux:

  1. Simon mode 1 (bouton rouge), lorsque le joueur réussi à répéter la séquence de notes, celle-ci est allongée d'une note supplémentaire tirée au hasard. Un échec termine la partie.
  2. Simon mode 2 (bouton vert), lorsque le joueur réussi à répéter la séquence de notes, une nouvelle séquence complète est générée au hasard. La séquence s'allonge de 1 à chaque succès du joueur, un échec termine la partie.
  3. mode 2 joueurs (bouton jaune), le premier joueur cré une séquence que l'autre doit répété. Chaque succès donne un point au joueur. Avant de commencer la partie les joueurs doivent choisir la longueur de la séquence et celle-ci ne varie pas durant la partie. bouton rouge pour 6 notes, vert 8 notes, jaune 10 notes et bleu 12 notes. le score maximal pour les joueurs 1 et 2 sont enregistrés dans l'EEPROM et peuvent être visualisé avec le bouton bleu hors partie.

opération

A la mise sous tension ou après que le bouton réinitalisation a été enfoncé, la routine POST est exécutée. Cette routine consiste à allumer séquenetiellement les 4 DEL en faisant ententre la note associée à chacune d'elle. L'ordre est rouge,vert,jaune,bleu.
Après le POST la routine t'attente de sélection du jeux est exécutée. Durant cette routine les DEL clignotent en séquence dans le même ordre que durant le POST mais il n'y a pas de son. Le joueur doit sélectionner le jeux en pesant sur le bouton correspondant.
Dans les modes 1 et 2 une musique de félicitation est jouée à tous les multiples de 6 notes et après la musique la longueur de la séquence est affichée selon le code lummineux indiqué plus bas.
Le bouton BLEU en dehors de tout jeux sert à afficher le pointage maximal obtenu par chacun des joueurs pour les parties à 2 joueurs. 1 beep se fait entendre avant l'affichage du pointage du joueur rouge et 2 beep avant celui du joueur vert.

code d'affichage

Les valeurs numériques sont affichées selon le code de couleur suivant:

  • La DEL rouge indique les unitées et clignote de 1 à 4 fois.
  • La DEL verte indique les multiples de 5 et ne clignote jamais plus d'une fois.
  • La DEL jaune indique les multiples de 10 et clignote de 1 à 4 fois.
  • La DEL bleu indique les multiple de 50 et clignote de 1 à 5 fois.
Le compte maximal qui peut être affiché est 255 ce qui donne bleu clignote 5 fois suivi de vert 1 fois, 5*50+5.

Mode à 2 joueurs

Le fonctionnement du mode à 2 joueurs est le suivant. Au départ les joueurs s'entendent sur la longueur de la séquence à jouer et doivent peser sur le bouton avant le délais de 3 secondes sinon la longueur par défaut de 6 notes est sélectionnée.
Au début de chaque manche 2 beep se font entendre avec 1 clignotement de la DEL rouge. Le joueur rouge doit alors entrer une séquence. Lorsqu'il a saisi toutes les notes de sa séquence, 3 beep se font entendre et la DEL verte clignote 1 fois. Le joueur vert doit alors répété la séquence. S'il réussi la musique de félicitation est entendu et son pointage augmente de 1. Ce pointage est affiché après la musique selon le code d'affichage mentionné au paragraphe précédent. Ensuite s'est son tour d'entrer une séquence (2 beep avec sa lumière qui allume). Après quoi 3 beep avec la lumière rouge indique à ce joueur de répéter la séquence.
Pour sortir de ce jeux il faut enfoncer le bouton de réinitialisation.

code assembleur

Ce qui distingue principalement le code de Micro Simon par rapport à Pocket Simon est l'utilisation des interruptions. On dispose aussi sur le PIC12F675 de plus de mémoire RAM 64 octets au lieu de 24 je n'ai donc pas eu besoin de compacter la séquence, chaque note occupe 1 octet au lieu de 2bits dans Pocket Simon. J'ai aussi utilisé l'EEPROM pour sauvegarder la mélodie au lieu d'une table dans l'espace programme. Le code assembleur montre donc comment lire et comment écrire dans l'EEPROM.

dimanche 6 mai 2012

vérificateur de continuité - montage final

J'ai complété le projet vérificateur de continuité. J'ai cependant fait une petite modification au schéma. J'ai trouvé dans un magasin un light stick pour environ 3$. Avant de l'acheter je l'ai ouvert et ayant constaté qu'il utilisait 3 piles LR44, je me suis dit que je pourrais utiliser ce porte-piles pour mon projet. De plus directement attaché au porte-piles il y a une DEL bleu. J'ai donc enlevé la DEL verte que j'avais monté directement sur la platine par un connecteur et j'ai utilisé la DEL qui était fixée au porte-piles. Cependant la DEL du porte-piles avait l'anode soudée au positif de l'alimentation, hors dans mon projet initial la DEL était avec la cathode au négatif de l'allimentation et l'anode était pilotée par la sortie du MCU. Une modification mineure au code a permis d'utiliser la DEL en anode commune.

schéma révisé

Le haut-parleur est collé au dos de la platine, séparée de celle-ci par un carton mince.

Le fil jaune est celui qui contrôle la DEL sur le porte-piles. Lorsque la DEL allume on voie très bien la lumière bleu au travers du tube.

Le diamètre du porte-piles étant plus petit que l'intérieur du tube. J'ai collé des morceaux de cartons à chaque extrémitée pour que ça s'ajuste au diamètre intérieur du tube.

Le résultat final. J'ai utilisé un étui de brosse à dent comme boitier. Encore un fois une push pin m'a servie d'extension pour atteindre le bouton mode qui est sur la platine.

samedi 5 mai 2012

le bogue se cachait dans un détail

Ce qui est complexe dans la programmation des MCU ce n'est pas d'apprendre l'assembleur mais plutôt de maîtriser tous les détails des périphériques. C'est pourquoi j'ai débuté ce blogue avec le MCU le plus simple possible en terme de périphérique. Mais avec le projet Micro Simon on monte d'un échelon en utilisant un PIC12F675, 2 timers, 1 convertissseur A/N, 1 comparateur et il supporte les interruptions. Pour le projet Micro Simon j'ai décidé d'utiliser le TIMER0 pour contrôler la fréquence de la note à jouer et le TIMER1 comme minuterie. Les 2 périphériques déclenchent une interruption. Ce matin j'ai donc écris la routine de service des interuptions en commençant avec quelque chose qui ressemblait à ceci, j'omets les détails non pertinent à la démonstration.

 org 4
isr ; interrupt service routine
; code pour la sauvegarde de W et STATUS ici
 btfsc INTCON, T0IF
 goto timer0_isr
timer1_isr
;code de gestion de l'interruption
; TIMER1 ici
 goto sortie_isr
timer0_isr
; code pour la gestion de l'interruption
; du timer0 ici
sortie_isr
; code de sortie interruption ici
; restauration de W et STATUS avant de sortir

J'ai écris la partie concernant le TIMER1 et je décide de tester pour voir ci ça fonctionne. Sans succès, je relis mon code, je cherche l'erreur, je ne trouve rien. Comment déboguer sans déboggeur? J'y parviens quand même en utilisant les DEL du jeux Micro Simon comme indicateurs de déroulement du code. Je constate que timer1_isr n'est jamais exécuté. Pour mes tests j'ai désactivé l'interruption du TIMER0 et mis T0IF à zéro donc l'instruction btfsc INTCON, T0IF devrait faire un saut vers timer1_isr. Ce n'est pas le cas, pourquoi? Et bien comme le diable des anglophones, les bogues se cachent parfois dans les détails. Il est important de bien lire la documentation et de la relire. La documentation fournie par Microchip est pourtant claire à ce sujet et je connaissais ce détail mais il n'était tout simplement pas présent à mon esprit dans ce contexte, car si j'avais écris le code pour servir l'interruption du TIMER0 le tout aurait fonctionné mais ce n'était pas le cas. Les indicateurs d'interruption des périphériques sont activés si une condition d'activation se présente même si l'interruption du périphérique concerné est désactivée. C'est même écris dans la documentation dans un encadré pour qu'on ne le manque pas. Donc même si l'interruption du TIMER0 était désactivée le TIMER0 continuait lui à incrémenter et lorsqu'il passait de 0xFF à 0x00 l'indicateur T0IF était mis à 1 même si aucune interruption n'était générée. Lorsque l'interruption du TIMER1 était déclenchée, le test sur T0IF en début était positif et au lieu d'exécuter timer1_isr s'était timer0_isr qui était exécutée. Et comme cette partie du code était vide le programme tombait directement sur la sortie d'interruption.

Ce qu'il faut retenir de cette anecdote c'est qu'il faut lire, relire et conserver à porté de lecture la documention du MCU sur lequel on travaille et si référer continuellement. Même lorsqu'on l'a déjà lu 10 fois plutôt qu'une.


NOTES
1) ICD pour In Circuit Debugger. Outil de déboguage en circuit comme le Microchip ICD2 ou ICD3.