Cette rubrique PicTrain est toute nouvelle, elle a débuté il y trois semaines ! Vous pouvez aisément nous rattraper et sauter en marche !
Aujourd´hui à notre menu :
4.
4.1.
4.2.
4.3.
4.3.1.
4.3.2.
4.3.3.
4.3.4.
 Application 1: le Youbitonmatic
 Conception générale
 L´électronique
 Le programme
   Début du programme
   Boucle principale
   Les “timers” et les interruptions
   Principe de l´interruption Timer1
4. Notre première application :
le Youbitonmatic
Un des aspects ennuyeux de la programmation est qu´il faut retenir tout un tas de signes sans grande signification, car toujours des abréviations ou acronymes venus de l´anglais. Désolé, là je n´y peux rien, mais il faut par exemple se souvenir que GPIO est le surnom du registre qui contient les valeurs des bits d´entrée/sortie. Savoir que ça veut dire “General Purpose Input Output register” n´est pas obligatoire.
Dans l´applications que nous allons étudier maintenant, j´introduirai au fur et à mesure les instructions dont nous avons besoin. Le YouBiTonMatic, on va l´examiner globalement, puis ligne par ligne de programme.
FAQ   Je n'ai rien compris à la présente page, je suis largué, je suis foutu, je pense que suis un c*n.... — JIDÉ : Non, c'est faux. Il y a dans cette page, et dans la suivante un concentré de connaissances totalement nouvelles qui doit être longuement digéré, et en plusieurs fois. Lire, re-lire, re-re-lire... Et j'ai eu la même réaction que vous quand je l'ai lue pour la première fois !
4.1. Conception générale
Je reprends le même montage que celui du Meccano électronique, c´est-à-dire un klaxon S.N.C.F. à deux tons de 370 Hz (grave, ta) et 660 Hz (aigu, ti). Je combine ces sons en une séquence ti-ti-ti-ta-ta-ti-ti (tiiii très long, taa long, tii long).
[N.D.L.R. Pour écouter le son réel de ce klaxon, rendez-vous sur la page Youbitonmatic, où nous l´avions déjà construit, mais cette fois-là avec des composants électroniques “discrets”, c'est-à-dire séparés, non intégrés...]
4.2. L´électronique
Le schéma est des plus simple , il ne comprend plus qu´un bouton poussoir pour déclencher le son, un haut-parleur (8 ohms) avec une résistance de 150 Ω, un condensateur de 1 µF, et un condensateur de découplage de 10 ou 100 nF. (Ce dernier sera présent dans tous nos montages.)
Le branchement du microP est donné ci-dessous :
Beaucoup de sigles, n´est-ce pas ? On y trouve :
Broche 1 : le plus (plus 5 volts stabilisés) de l´alimentation,
Broche 8 : la masse (zéro volt) de l´alimentation.
Toutes les autres pattes peuvent servir à plusieurs emplois, jusqu´à cinq ! Elles portent donc des surnoms complexes. Retenons simplement celles soulignées en jaune  :
Broches 2 à 7 : les 6 entrées/sorties (E/S) du microP. Attention, elles sont en l´occurrence dans l´ordre inversedes numéros de pattes : de GP5 à GPØ, dans le sens des aiguilles d´une montre),
Dans le montage d´aujourd´hui de Pictrain, n´utilisera que deux bornes (en plus de l´alimentation !), l´entrée (bouton poussoir) sur l´entrée/sortie GP5 ; la sortie vers le haut-parleur sur l´entrée/sortie GP1 ; il faudra tenir compte de ceci dans le programme.
4.3. Le programme

Remarque (une nouvelle fois) pour les puristes : très souvent je ferai l´impasse sur certaines explications, et il m´arrivera même d´être à la limite de la vérité, uniquement parce que je souhaite présenter les microP de la manière la plus simple possible. Je ne parle donc que de ce qui est strictement nécessaire pour comprendre ce que nous faisons, pour le reste vous trouverez des commentaires plutôt du style “c´est comme ça et ne cherchez pas à comprendre”, car cela n´apporte rien à notre propos.
Plus tard, pour ceux que cela intéresse vraiment, il y a sur Internet des tas de bonnes présentations des microP, vous pourrez vous y reporter si vous devenez “mordus”.
Par ailleurs, installez-vous confortablement, éteignez la télé et concentrez-vous un peu. Ce qui suit n´est pas difficile, mais malheureusement on va se retrouver, comme déjà dit, avec pas mal de sigles et abréviations, toujours basés sur la langue anglaise, et de l´attention est nécessaire si on ne veut pas être perdu. N ´ayez pas peur, nous vous prenons par la main, mais il faudra peut-être quand même lire tout ça deux ou trois fois !
4.3.1. Début du programme
Cette première partie comprend d´abord des commentaires généraux, puis des éléments de paramétrages du microP. C´est obligatoire, absolument standard (dans nos montages) et donc oubliez tout ça.
Dans cette partie , on regroupe toutes les définitions des registres généraux que nous utiliserons dans le programme (il y en a 64 disponibles). Un registre ne peut être utilisé que s´il est identifié ici.
Chaque registre est “nommé”, ici CPT_256, SAV_TMR1H et SAV_TMR1L, le ‘:1´ indiquant qu´un seul octet est utilisé. C´est ce nom qui sera utilisé plus loin lorsque l´on utilisera un registre. ‘CBLOCK 0x020´ et ‘ENDC´ ne sont que des indications de début et de fin des définitions.
J´avais indiqué plus haut que notre microP comprend 35 registres spéciaux, qui servent à paramétrer les différentes fonctions, mais que à notre niveau nous n´en utiliserons que 3 ou 4. Il faut cependant mettre des paramètres correspondant à nos besoins dans ces registres, valeurs qui sont toujours les mêmes dans tous nos programmes.
La commande '#include' signifie qu´il existe un fichier externe appelé ' 'Param_Std_12F.inc' qui fait partie de notre programme. Le contenu de ce fichier est donc un morceau de programme (d´une centaine de lignes), mais qui n´apparaît pas dans notre liste d´instructions, ce qui améliore sa lisibilité (de toute façon vous n´avez pas besoin, pour l´instant, de savoir ce qu´il contient).
list0404
;***********************************************************************
; PARAMETRES SPECIFIQUES
;***********************************************************************
BANK1 ;
clrf TRISIO ;port en sortie
bsf TRISIO,5 ;sauf 5 pour déclenchement
bsf WPU,5 ;résistance de rappel sur le port 5
; registre controle interruptions
clrf INTCON ;
bsf INTCON,GIE ;interruptions activées en permanence
bsf INTCON,PEIE ;autorise interruption périphériques
;(notamment Timer1)
; registre interruptions périphériques
clrf PIE1 ;autorise les interruptions Timer1
bsf PIE1,TMR1IE
BANK0
bcf GPIO,1 ; sortie à 0
Dans cette partie , on initialise justement les registres spéciaux spécifiques à notre programme. Pour l´instant, oubliez cette partie, nous y reviendrons plus tard, je ne la laisse ici que parce que la construction du programme fait qu´elle se trouve ici.
4.3.2. Boucle principale
Nous revoilà dans notre boucle principale telle que définie précédemment.
;***********************************************************************
; BouclePrincipale
;***********************************************************************
BouclePrincipale
btfsc GPIO,5 ; attente déclenchement
goto BouclePrincipale
call SON_Tii ; appel des sons
call SON_Tii
call SON_Tii
call SON_Taa
call SON_Taa
call SON_Tii
call SON_Tii
goto BouclePrincipale
Si vous avez un peu de mémoire vive, cela doit quand même vous rappeler quelque chose.
Que ce passe-t-il dans ce morceau de programme ?
D´abord on teste l´entrée du bouton poussoir par btfsc GPIO,5 ! Oui ça parait incompréhensible, mais pas tant que ça  :
GPIO est un registre spécial qui contient la valeur lue (ou écrite) sur les entrées/sorties ; comme il y a 6 E/S dans mon microP, j´ai 6 bits (numérotés de 0 à 5) dans GPIO et qui me donnent l´état de mes 6 E/S.
Mon entrée, correspondant au bouton poussoir (voir le montage électronique) est la 5, je vais donc tester GPIO,5, ce qui veut dire tester le bit 5 du registre GPIO.
Je teste par l´instruction btfsc (Bit Test File, Skip if Clear) ce qui donne en français “test d´un bit d´un registre et saut s´il est à 0”.
En clair, je vais donc tester le bit 5 du registre GPIO, et “sauter”´ s´il est à 0 (c´est-à-dire si le bouton poussoir est appuyé). Sauter dans ce cas veut simplement dire que je saute l´instruction suivante, qui est un goto. Sauter l'instruction ne veut pas dire Sauter à l'instruction !
En d´autres termes, si mon bit est à 1 (je ne saute pas), j´exécute le goto, c´est-à-dire que je retourne à BouclePrincipale (= au début), sinon, si mon bit est à 0, je saute le goto, et je me retrouve donc sur l´instruction call SON_Tii, c´est-à-dire que je lance la séquence d´émission des sons.
On exécute alors l´appel des sous-programmes SON_Tii et SON_Taa, et finalement on retourne au début par le goto BouclePrincipale.
Nous avons ici le principe général de tous les tests : on teste si un bit est à 1 (Set) ou a zéro (Clear), et si oui on saute UNE instruction. Les deux instructions sont btfsc, test d´un bit à 0 (Skip if Clear) et btfss, test d´un bit à 1 (Skip if Set).
On va donc souvent retrouver la construction :
Test du bit,
Si le test n´est pas OK, goto pour aller ailleurs,
Si le test est OK, suite des instructions.
Et deux instructions de plus !

Résumé des instructions rencontrées jusqu´ici
Instruction Opérande Fonction
goto étiquette Déplace l´exécution du programme vers un autre endroit identifié par étiquette
call étiquette Appel un sous-programme identifié par étiquette
return pas d´opérande Fin de sous-programme, le programme revient à l´instruction suivant le call
btfsc registre, bit Test du bit bit dans le registre registre, si le bit est à 0, on saute l´instruction suivante, sinon on l´exécute
btfss registre, bit Test du bit bit dans le registre registre, si le bit est à 1, on saute l´instruction suivante, sinon on l´exécute
Vous avez suivi ? Si oui, vous avez à peu près tout compris de la programmation des microP, sinon faites ‘goto page1´ et revenez au début du texte...
PTI+   Anti-rebond : puisque vous suivez les montages du Meccano électronique, vous devez vous souvenir des problèmes de “rebond” qu´engendrent les boutons poussoirs.
Notre programme élimine ce problème : en effet, à l´appui sur le bouton (GPIO,5), on déclenche la séquence d´émission des sons, et durant tout ce processus le programme ne teste pas l´entrée et donc le bouton est inactif.
Ce n´est qu´à la fin de cette séquence que l´on revient au test du bouton et que le ti-ta peut de nouveau être déclenché.

4.3.3. Les “timers” et les interruptions
Dans ce paragraphe nous allons aborder les deux derniers éléments un peu difficiles que sont les timers et les interruptions.
Les timers (compteurs) : c´est tout simplement... des compteurs qui comptent les tic-tac de l´horloge. Ils vont nous servir à retrouver les fréquences, tout simplement en comptant les microsecondes correspondant à la période du son que nous voulons émettre.
Il y a deux timers dans le 12F675, le Timer0 qui compte jusqu´à 256 et le Timer1 qui compte jusqu´à 65536 c´est-à-dire 256 fois 256). Dans ce montage, nous allons utiliser le Timer1.
Le principe des timers est simple : à chaque tic d´horloge ils s´incrémentent de 1 ; lorsqu´ils arrivent à 255 (Timer1) ou 65535 (Timer0), ils repassent à zéro et continuent de compter. Mais au moment où ils sont revenus à zéro, ils ont déclenché une interruption.
Les interruptions : ce terme barbare recouvre exactement la même notion que votre réaction lorsque votre épouse vous appelle pour dîner alors que vous êtes en train de ballaster 10 mètres de voie sur votre réseau.
Normalement, vous allez interrompre votre travail (et sans maugréer !), mais vous ne laissez pas tout en plan comme ça : vous allez ranger — fermer le bocal de colle et celui de ballast, mettre le pinceau dans l´eau pour qu´il ne sèche pas, etc. Après le dîner, vous récupérez pinceau et ballast, et vous continuez.
Dans notre microP, c´est un peu la même chose : durant l´exécution du programme normal (notre BouclePrincipale), il peut y avoir des interruptions qui font arrêter ce qui est en cours, font exécuter un sous-programme particulier, et on reprend le programme principal à la fin du sous-programme.
En détail, il se passe :
Déclenchement de l´interruption, votre femme vous appelle,
Sauvegarde de l´état du programme, vous rangez le pinceau,
Exécution du sous-programme, vous dînez,
Restauration de l´état du programme, vous récupérez le pinceau,
Suite du programme principal. vous continuez le ballast.
Heureusement, toutes les parties un peu compliquées (sauvegarde et restauration) sont toujours les mêmes, et je les ai donc cachées (elles sont dans le fameux fichier Param_Std_v1_0.inc que nous avons vu au début).
Il ne nous reste donc que deux choses à faire :
Paramétrer les interruptions,
Ecrire le sous-programme.
Plusieurs sources d´interruptions sont possibles, nous n´en utiliserons qu´une pour l´instant, celle attachée au Timer1.
4.3.4. Principe de l´interruption Timer1
Le Timer1 est un des registres spéciaux, qui permet le comptage des tics de l´horloge (rappelez-vous le paragraphe “Et pourtant il tourne”). C´est donc un “compteur de temps écoulé”.
À quoi ça sert ? Ici cela nous servira à trouver les fréquences de 370 et 660 Hz pour notre klaxon, en divisant la vitesse du microP (1·000·000 Hz) par la valeur adéquate pour obtenir des interruptions aux fréquences voulues.
Regardons d´abord comment générer un signal comme ci-contre. En pratique, on va, à chaque demi-période, inverser la valeur de la sortie de 0 à 1 et de 1 à 0 (basculement).
On voit que cette fréquence des basculements devra donc être le double de la fréquence du signal de sortie.
Pour la fréquence de sortie de 370 Hz, la fréquence des basculement devra être de 740 Hz, et donc la période de 1/740 de seconde , soit 1,3513 millisecondes, ou en d´autres termes, il faut 1·351 tics entre chaque basculement.
On va donc utiliser le Timer1 pour déclencher une interruption tous les 1·351 tics, et on inversera la sortie à chaque interruption.
Attention : un compteur... compte (1, 2, 3, 4... il ne sait pas “décompter” :  4, 3, 2, 1), et comme l´interruption se déclenche au maximum (65·535 dans notre cas), il nous faut charger 65·535 moins 1·351, soit 64·184 dans le compteur.
Petite difficulté : comme toutes les valeurs dans notre microP, le Timer1 est basé sur les registres spéciaux, qui sont des octets ne contenant au maximum que 255. Il est donc nécessaire d´avoir deux octets pour stocker des valeurs qui vont jusqu´à 65·535, octets appelés TMR1H et TMR1L (H pour high, octet de poids fort et L pour low, octet de poids faible).

PTI+   Poids fort, poids faible ?
Prenant comme exemple la date de la Révolution , on a vu qu´on donnait, même “en français de tous les jours”, une importance différente aux chiffres selon leur position dans un nombre. Si un élève se trompe sur le 9 et met un 5, ça donne 1785 : il perd un point mais ne redouble pas sa classe. S´il se gourre sur le 7, en écrivant 1089 par exemple, c´est la catastrophe, les parents sont convoqués... Donc le 7 est un chiffre de poids plus fort que le 9... Et le 1 est le plus fort de tous.
Dans les octets informatiques, c´est pareil. Admettons qu´on soit riches, au point d´acheter un "super-microP" qui ait des registres de 16 bits, comme ci-dessous. Avec ce nombre, on pourrait compter de 0 à 65·535 (c´est-à-dire 32·768 + 16·384 + 8·192..., etc.) Le bit n° 0, bit de poids faible, vaudrait un ; celui de poids fort, le 15e, vaudrait 32·768 !
Hélas, nous sommes des pauvres : notre petit microB (!) à huit pattes ne connaît que des registres à huit bits ;¬( Pour compter jusqu´à 65·535, il faut qu´il mette deux octets à la queue-leu-leu ! On a donc non seulement dans chaque octet un bit faible et un bit fort, mais aussi un octet de poids faible et un octet de poids fort... Le bit 0 de l´octet de gauche vaut deux fois le poids du plus gros bit de droite.
Notons, enfin, que pour une fois les anglophones sont bien embêtés — l´abréviation LSB (last significant bit, bit de poids faible) est la même que LSB (last significant byte, octet de poids faible). La différence est... dans le contexte ! Le contraire est MSB (most significant bit ou byte). [Tout cet encadré est de Jidé.]
Dans l´octet de poids fort on stocke les multiples de 256, et dans l´octet de poids faible le reste ; exemple : 64·184 est composé de 250 fois 256 plus 185, on mettra donc 250 dans l´octet de poids fort (TMR1H) et 185 dans l´octet de poids faible (TMR1L).
Vous suivez ? Dans notre programme, on fera donc :
Chargement de l´octet de poids fort,
Chargement de l´octet de poids faible,
Lancement du Timer1, (il compte)
A l´interruption (Timer1 = 0), il se sera écoulé exactement 1·351 µS, et on recommence.
Si à l´interruption on inverse la sortie du haut-parleur, on génère un son de 370 Hz. Si vous avez compris, vous êtes capables de faire le même calcul pour la fréquence de 660 Hz :
Fréquence des basculements : 660 x 2 = 1·320,
Nombre de tics entre deux basculements : 1·000·000 / 1·320 = 757 tics,
A charger dans le Timer1 : 65·535 – 751 = 64·778,
C´est-à-dire 253 dans TMR1H et 10 dans TMR1L.

Durée d´un son
Pour simplifier le programme et ne pas vous égarer, on ne va pas introduire ici le contrôle exact d´une demi-seconde pour la durée de chaque son.
On va simplement utiliser un registre général tout simple, et compter les basculements jusqu´à 256. Nous aurons donc :
256 x 1·351 = 345·856 µS, soit 0,35 seconde pour le son ta (370 Hz).
256 x 757 = 193·792 µS, soit 0,2 seconde pour le son ta (660 Hz).
Pour les besoins de la démonstration, je pense que cette approximation est suffisante, on fera peut-être mieux dans une version finale du montage (vous devinez qu´on peut utiliser l´autre compteur Timer0 pour réaliser des durées précises d´une demi- seconde).

Psi

15/12/07
N.B. — Textes, schémas, programmes © Psi pour Ptitrain. Photos Jidé ou D.R. quand signalé. — Toutes vos remarques et commentaires sont bienvenus, et les pages de Ptitrain ne sont pas statiques : les erreurs sont corrigées sitôt connues, les améliorations, éclaircissements, etc. feront l´objet de mises à jour fréquentes.
Ptitrain, l´e-magazine du train éclectique. — Directeur de la publication : Christophe Franchini.
Rédacteur en chef : Jean-Denis Rondinet