You are on page 1of 35

http://www.didel.

com/

info@didel.com

http://www.bricobot.ch/

info@bricobot.ch
www.didel.com/pic/Prog877.pdf

Apprendre programmer avec le 16F877A


--plus mis jour voir http://www.didel.com/pic/Cours877-1.pdf etc Le but est dapprendre crire des programmes en assembleur pour des application utilisant un code efficace sur des microcontrleurs en gnral plus petits. Notre dmarche est de tester les programmes sur un 16F877 qui a 4 ports dentre-sortie, ce qui facilite la comprhension du fonctionnement. Le Microdule 16F877 est aussi idal pour mettre au point des applications utilisant des processeurs en boitier 6, 8, 14 pattes. En plus de la carte 877, 4 cartes Microdules et des composants aident pour les tests. La grande ide des Microdules est que vous ne les utilisez pas dans votre application. Ils restent toujours prts pour tester des routines et prparer des nouveaux projets. Notons encore que pour viter dallonger ce document avec des informations essentielles pour matriser tous les aspects dun PIC, mais pas indispensables quant on na pas encore le besoin pour son application, beaucoup de renvois sont fait aux documents crits depuis plus de 10 ans, qui se rfrent parfois des cartes de dveloppement primes ou des processeurs qui ne prsentent plus dintrt. En particulier, le cours de 2002, partiellement repris ici, est souvent cit pour des points plus spcialiss. Voir www.didel.com/picg/picg87x/CoursPicg87x.html . Une approche moins systmatique avec des programmes pour clignoter et faire de la musique se trouves sous www.bricobot.ch/programmer/CalmBimo.pdf Matriel ncessaire Pickit2 65.Kit Microdule A2840 complt 45.16F877A 10.Doc sous www.didel.com/pic/Prog877kit.pdf La doc gnrale sur les Microdules est sous www.didel.com/pic/Microdules.pdf
Nouveau : composants supplmentaires pour tester les programmes

Table des matires 1 Introduction 2 Ports dentre-sortie 3 Toutes les instructions 4 Timers et interruption 5 Entres analogiques 6 Commande de moteurs 7 Transferts srie 8 EeProm et bootloader 9 Tables 10 Accs indirect 11 Squencement et multitche 12 Arithmtique 13 Macros et .If 14 Structure et mise en page 15 Dpannage et complments 16 Programmes de test 17 Routines et programmes exemple

1 Introduction
Avant de pouvoir faire les exercices de ce document, il faut installer SmileNG www.didel.com/pic/SmileNG.zip Pour la documentation de lditeur SmileNG et ses ordres de mise en page, voir http://www.didel.com/pic/SmileNG.pdf . Pickit2 www.bricobot.ch/docs/Microchip.zip La procdure dinstallation se trouve en www.didel.com/pic/InstallPic.pdf A peu prs la mme chose, avec le brochage du connecteur de programmation sous www.didel.com/pic/Pickit2.pdf Si vous avez des problmes avec un circuit qui refuse de se programmer, regardez www.didel.com/pic/RecupPic.pdf Les exemples de programmes associs ce document se trouvent sous www.didel.com/pic/Prog877Sources.zip Mettre ces fichiers dans un dossier Prog877. Il faut ensuite connecter le Microdule 877, tester les sorties avec le programme T877Cli.hex (ce programme sera expliqu plus loin). Dplacer lafficheur sur les ports pour vrifier que cela clignote partout. 1.1 Comment travailler ? Chacun a besoin dexplications diffrentes pour bien comprendre. Ce document va trop lentement ou trop vite pour vous. O trouver dautres explications ? Le danger est de se disperser lire des documents qui disent la mme chose diffremment et ne font pas progresser. Si vous avez une incertitude concernant une instruction, le fichier www.didel.com/pic/CalmInstr877.pdf rsume les instructions et leffet sur les flags (section 3). Cest bien de lavoir toujours sous les yeux. Le Help de Smile est plus lent et un peu plus dtaill. 1.2 Notions de base : bits, octets, constantes, variables, registres, Si ces notions sont nouvelles pour vous, le mieux est de lire la brochure Dauphin que vous pouvez obtenir gratuitement chez Zigobot et que vous pouvez lire sous http://www.epsitec.ch/Dauphin.zip Cette brochure vous apprend programmer un processeur invent, la fois plus simple et plus riche que les PICs. Le notions de nombre, constantes, variables, etc sont expliques avec plus de dtails dans le fichier www.didel.com/pic/Bases.pdf dont la lecture est recommande maintenant ou plus tard, quand vous aurez fait quelques exercices. 1.3 Architecture des PICs Les PICs ont une architecture simple, avec une mmoire dinstructions 12 ou 14 bits, des variables 8 bits et des priphriques 8 bits dans le mme espace que les variables. Cet espace des variables est coup en 4 banques, ce qui complique la slection : on travaille principalement en banque 0 en passant brivement dans dautre banques lorsque cest ncessaire. Comprendre larchitecture interne nest pas essentiel. Si cela vous intresse, la doc de Microchip est naturellement la rfrence. Le document www.didel.com/pic/Architecture.pdf prsente les lments importants, pour maintenant ou plus tard. Les priphriques ont plusieurs fonctions et il faut initialiser la bonne selon lapplication. On expliquera les plus utiles dans des exemples. Les programmes PicTests www.didel.com/pic/PicTests.pdf vitent de se perdre dans la doc dtaille de Microchip pour les utilisations standard. Si vous voulez en savoir plus sur des bits qui dfinissent le comportement des priphriques, il faut chercher la documentation du fabricant sous ww1.microchip.com/downloads/en/DeviceDoc/39582b.pdf ou utiliser une traduction en franais, parfois un peu amliore, par Bigonoff ou Oumnad. Les livres de Tavernier ont la mme approche. 1.4 Lassembleur CALM Les rgles de lassembleur et les pseudo-instructions apparatront petit petit, pafois sans explications. Le Help de SmileNG vous donnera quelques lments dexplication. Si une

prsentation systmatique vous est ncessaire avant de voir des exemples de programme, lisez www.didel.com/pic/Calm.pdf

2. Entres et sorties
Lintrt des microcontrleurs est quil ont des sorties sur lesquelles on peut brancher des diodes lumineuses, dans amplis pour commander des moteurs, un haut-parleur. Ils ont des entres pour connecter des poussoirs et interrupteurs, pour lire des signaux analogiques, pour mesurer des dures dimpulsions. Ces fonctions sont programmables et varient un peu dun PIC lautre, influanant le choix du microcontrleur et le cblge. 2.1 Registre de direction Pour dcider si une broche du processeur est une entre ou sortie, il faut que le contrleur aie des aiguillages commands par un registre de direction appel Tris. Si le bit Tris est 1 (input) la broche du circuit est connecte au bus et amne linformation dans le registre W, si linstructionMove Port,W est excute. Si le bit Tris vaut 0 (output), cest linformation qui vient du bus qui est mmorise dans le registre et active en sortie.

Ladresse du registre Tris est la mme que pour le port correspondant, mais dans la banque 1, slectionne en activant le bit RP0 du registre Status. La section 2.6 montre comment programmer la direction. 2.2 Affichage de test LB8 et module dentre Sw8 Pour visualiser ltat 0 ou 1 dune sortie, une diode lumineuse est utilise. Elle peut tre branche de deux faons diffrentes. Les transistors de sortie sont un peu meilleurs pour soutirer du courant (max 10 mA), donc on voit souvent dans des applications la solution avec la cathode vers le processeur, donc un zro allume. La valeur de la rsistance fixe la luminosit de la diode. Avec lanode ct processeur, ltat 1 allume la diode.. Le microdule daffichage Lb8 utilise des diodes bicolores et une paire de rsistance qui affichent le zro (en rouge), le 1 (en vert) et ltat flottant en entre avec les deux diodes allumes en demi-intensit (on voit surtout le rouge). Pour agir sur les entres, on branche un interrupteur ou poussoir avec une rsistance pull-up. Linterrupteur ferm relie la masse, donc impose un zro logique. On peut cbler linverse, avec une pull-down et imposer un 0 quand linterrupteur est ouvert. Cela ne se fait pas car les processeurs ont parfois des pull-up internes et on en profite.

La correspondance entre position haut/bas de linterrupteur et tat logique 0/1 sur lentre du port doit tre bien documente. Pour le processeur, dcider quun 0 est actif ou un 1 est actif, est tout aussi facile.

Le microdule Sw8 a 8 interrupteurs avec des pull-up de 1 kOhm et des rsistances en srie de 220 Ohm pour limiter le courant de court-circuit si linterrupteur est ferm et la broche du contrleur initialise en sortie et ltat 1. Sans rsistance, le courant de court-circuit serait de 20mA environ, ce qui nest heureusement pas destructeur si de courte dure. 2.3 Initialisation Linitialisation de la direction des entres-sorties dpend du schma de lapplication et se fait une fois au dbut. Une bonne habitude est de terminer cette initialisation par 3 clignotements. Sils ont lieu, le programme a dmarr correctement ; sil ne continue pas juste, cest une erreur dans votre programme. Une autre initialisation, appele configuration, est ncessaire pour dire par exemple si loscillateur est interne ou externe. Le mot de configuration doit tre crit ladresse 2007 et nas pas de raison dtre chang dans nos applications, donc on ne va donc pas lexpliquer. 2.4 Exemple : osciller le portC Le portA na que 6 bits dont un spcial (bit4). Le portB a deux lignes pour la programmation qui ont quelques contraintes. Sur les portC et D du 16F877 on peut faire ce quon veut et on va de prfrence les utiliser. Activer-dsactiver le portC, donc crer une impulsion positive, scrit de plusieurs faons. Il faut naturellement avoir dabord initialis le portC en sortie, donc mis des 0 dans le registre TrisC, ce qui se fait tout au dbut du programme. La premire et la 3e solutions sont identiques.
Move Move Move Move #211111111,W W,PortC #200000000,W W,PortC Move Move Clr #211111111,W W,PortC PortC Move Move Move Move #-1,W W,PortC #0,W W,PortC

On peut encore donner le paramtre en hexadcimal 211111111=16FF 210100101 = 16A5 Le dcimal est utilis pour initialiser des compteurs, mais il nest pas logique pour reprer les bits dun port. Toutefois, -1 = 16FF = 211111111 est trs pratique et jusqu 7, la conversion est immdiate : 6 = 200000110 = 1606 Pour plus de dtails sur le binaire et lhexadcimal, voir www.didel.com/pic/Bases.pdf Pour rpter ces instructions dactivation/dsactivation, on cre une boucle en mettant une tiquette au dbut de la boucle et en ajoutant une instruction qui saute cette tiquette, cest dire ladresse correspondante dans la mmoire du processeur. Bcle: Move #211111111,W ; 1 s
Move Move Move Jump W,PortC #200000000,W W,PortC Bcle

; 2 s Les PICs 4 MHz excutent une instruction par microseconde (2 s pour les sauts). Les 4 instructions prcdentes vont activer le port C pour 2 microscondes seulement, et dsactiver pour 3 microsecondes. On ne verra rien sans utiliser un oscilloscope.

2.5 Boucles dattente Pour que le processeur modifie les sorties une vitesse humaine , il faut insrer des boucles dattente. On initialise un compteur et on dcompte jusqu la valeur zro, que le processeur sait bien reconnatre.
Att: Move #250,W Move W,Cx1 Dec Cx1 ; 1 Skip,EQ ; 1 Jump Att ; 2 s s s

Ce bout de programme va faire 250 fois la boucle qui dure 4 microsecondes, donc la dure totale est de 1 milliseconde (plus les 2 microsecondes dinitialisation du dcompteur). A noter les trois nouvelles instructions. Dec Cx1 dcompte la variable mentionne. Comme le compteur dune voiture qui roulerait en marche arrire, le compteur ne se bloque pas en zro, mais continue avec la valeur maximum. Linstruction Skip,EQ permet de savoir si le compteur est zro (EQ equal). Si oui, le processeur saute linstruction suivante. Si non, il excute le saut qui lui fait attendre encore un tour.

Cest encore trop rapide pour notre oeil. On ne peut pas augmenter la valeur 250 au del de 255, car la variable Cx1 est un mot de 8 bits et les PICs nont pas dinstructions pour des compteurs ou dcompteurs plus grands que 8 bits. On fait alors une 2e boucle qui appelle la premire et utilise une 2e variable. Vous voulez un dixime de secondes ? Il suffit de rpter 100 fois la boucle de 1ms.
; Boucle 100 millisecondes Move #100,W Move W,Cx2 Att2 : Move #250,W Move W,Cx1 Att: Dec Cx1 ; Boucle 1ms Skip,EQ Jump Att Dec Cx2 Skip,EQ Jump Att2

On pourrait naturellement compter et comparer quand on atteint la valeur 100 ou 250. Cest moins efficace avec le PIC. 2.6 Programme complet Il faut donc insrer nos boucles dattente de 100ms aprs avoir crit et aprs avoir effac le motif sur le PortC. Le programme doit aussi initialiser le PortC en sortie, et dclarer ladresse des variables Cx1 et Cx2. Il faut enfin configurer le processeur. Charger le programme T877Cli0.asm dans SmileNG et assembler (F5). Lassembleur convertit ce programme en binaire, et cre un fichier avec lextension .hex. Il faut le transfrer dans le Pickit2 et on peut voir le code dans la fentre Program memory. Excuter en cliquant sur On la fin du Write.
\prog;T877Cli0|Clignote les sorties du portC \b; RC0..RC7 oscille, ;priode 0.65 s a 4 Mhz ; Ne pas utiliser si des sorties sont court-circuites ou connectes a des sorties d'interface ; Voir T877Cli pour une criture plus lgante .Proc 16F877 .Ref 16F877 CX1 CX2 = 16'20 ; Dbut des var = 16'21 .Loc Deb: Move Move Loop: Move #Motif1,W Move W,PortC ; attente 100ms Move #100,W Move W,Cx2 Att2: Move #250,W Move W,Cx1 Att: Dec Cx1 Skip,EQ Jump Att Dec Cx2 Skip,EQ Jump Att2 #0,W ; out W,TrisC 0 Move #Motif2,W Move W,PortC ; attente 100ms Move #100,W Move W,Cx2 Att2b: Move #250,W Move W,Cx1 Attb: Dec Cx1 Skip,EQ Jump Attb Dec Cx2 Skip,EQ Jump Att2b Jump ;Configuration .Loc 16'2007 .16 16'3F39 .End Loop

Motif1 = 16'55 ; 2'01010101 Motif2 = 16'AA ; 2'10101010

2.7 Optimisation ou simplifications Linstruction DecSkip,EQ remplace les deux instructions de la boucle dattente. Si on na pas besoin dune dure prcise, on peut ne pas recharger les compteurs. Aprs tre arrivs zro, ils recommencent un tour de 256 pas. La faon la plus simple de faire une attente de 256x256x3 s =~ 0.2 secondes est dcrire
A$: DecSkip,EQ Jump A$ DecSkip,EQ Jump A$ Cx1 ; A$ est une tiquette dite locale Cx2

Le programme T877Cli.asm utilise cette nouvelle attente et clignote tous les ports en inversant le motif avec un ou-exclusif que lon comprendra plus loin. Le programme est nettement plus court. On remarque que linitialisation du portA ncessite dagir sur le registre AdCon1. On reparlera de lanomalie des registres Tris et de la 2e banque. T877Cli.asm est un programme de test que lon recharge toutes les fois que lon veut vrifier que le processeur fonctionne et que toutes les sorties sont connectes. Sil ne tourne pas, cest que loscillateur interne nest pas initialis.

2.8 Routines Ce nest pas trs lgant, ni trs efficace, de devoir crire deux fois la mme boucle dattente, comme dans le programme T877Cli0.asm. On crit une seule fois le module, appel routine, et on peut lappeler autant de fois que lon veut. Linstruction Call fait lappel et la fin de la routine, linstruction Ret (return) retourne linstruction qui suit le Call. Ecrivons une routine AttWx1ms avec un paramtre en entre.
\rout:AttWx1ms|Attente de (W) fois 1ms \in:W nombre de ms \mod:W Cx1 Cx2 AttWx1ms: Move W,Cx2 A$: Move #250,W Move W,CX1 B$: Nop DecSkip,EQ CX1 ; boucle 1ms Jump B$ DecSkip,EQ Cx2 ; boucle (W) fois 1ms Jump A$ Ret

Cette routine est le premier lment dune bibiothque de routines que chaque programmeur se constitue. Les 3 premires lignes contiennent toute linformation ncessaire pour lutiliser. 2.9 Agir sur une seule ligne de sortie On veut souvent modifier une sortie sur un port sans modifier celles qui sont ct sur le mme port. Une premire solution est de lire le port, modifier avec les bonnes instructions, et r-crire la valeur. Par exemple, si on veut mettre 1 le signal LedV du portC (sur le bit2 en 3e position) on peut crire
Move Or Move bLedV Set PortC,W #200000100,W W,PortC ; force le bit2 1, ne modifie pas les autres

Une instruction fait exactement cela :


= 2 ; 3e position car on numrote 0 1 2 .. depuis la droite PortC:#bLedV ;

Pour mettre le bit bLedV zro (ce qui allumera ou teindra la LED verte selon le cblage, il faut crire :
Move And Move Clr PortC,W #211111011,W W,PortC PortC:#bLedV ; force le bit2 0, ne modifie pas les autres

Une instruction fait exactement cela : Si le ET (And) et le OU (Or) logique ne vous sont pas familiers, regardez le document www.didel.com/pic/Bases.pdf. Le Ou exclusif du programme T877Cli.asm y est aussi expliqu. 2.11 Lire un port Pour mettre un port en entre, il suffit de mettre des 1 partout dans le registre Tris associ.
Set Move Move Clr Status:#RP0 #211111111,W W,PortC ; TrisC Status:#RP0

Copier un port sur un autre scrit simplement


Move Move PortC,W W,PortD ; initialis en entres ; initialis en sorties

Il ny a pas besoin de boucle dattente dans ce cas, mais il peut y avoir de bonnes raisons den mettre une. Le programme T877CopyCD.asm lit les interrupteurs sur le portC et copie sur le portD. Modifier ce programme pour lire sur le PortB. Il peut y avoir problme, car le programmateur utilise RB6 et RB7 pour crire dans le 16F877. Un interrupteur ferm peut perturber, malgr la rsistance srie.

2.12 Lire un poussoir isol On peut naturellement lire tout le port et ensuite isoler le bit pour savoir sil vaut un ou zro. Linstruction AND permet ce masquage dun ou plusieurs bits dans un mot. Par exemple, un poussoir est connect sur le bit4 du port C initialis en entre. Le poussoir actif ferme le contact et impose un zro sur lentre.
bPous = 4 Move PortC,W And #200010000,W ; seul le bit 4 reste dans son tat Skip,EQ ; le rsultat est nul si le bit 4 est zro Jump PousInactif Jump PousActif

On doit trs souvent savoir si un bit dun port ou dune variable est un ou zro, une instruction unique remplace les 3 instructions de masquage dune ligne:
TestSkip,BC PortC:#bPous Jump PousInactif Jump PousActif (skip if bit clear) saute si bit 4=0

Pour tester si un bit est un, on a linstruction


TestSkip,BS PortC:#bPous Jump PousActif Jump PousInactif (skip if bit set)

Les trois instructions (Move And Move) sont toujours utilises si on veut tester un groupe de bits. Pare exemple, si 4 poussoirs sont presss, le AND permet de savoir quil y en a un qui est activ, mais il faut ensuite dcider lequel. 2.13 Mlange dentres et sorties sur un mme port Le registre Tris permet de mlanger des entres et sorties, mais il peut y avoir des directions prioritaires, par exemple si le convertisseur analogique est dclar. Les programmes de test mettront en vidence quelques cas simples. La documentation du fabricant sur 300 pages les dcrit tous ! Comme exemple, cblons une LED sur le bit 2 du PortC et un poussoir sur le bit 4. Dcidons que les 4 bits de poids faibles sont des sorties, et les 4 bits de poids forts sont des entres. Les instructions spcifiques cet exemple sont :
bLed = 2 bPous = 4 DirC = 211110000 ... Move Move ... TestSkip,BS Clr PortC TestSkip,BC Set PortC PortC: bPous :#bLed PortC: bPous :#bLed #DirC,W W,TrisC ; en banque 1

Le programme T877SwapC.asm est plus intressant, car la moiti gauche du portC est en entre et la moiti droite en sortie. Linstruction
Swap PortC,W

permute les 2 moitis en transfrant dans W. Question : peut on remplacer les 2 instructions
Swap Move PortC,W W,PortC PortC

par
Swap

Essayez, ca marche en fait pour toutes les variables ; cest parfois pratique de pouvoir permuter les deux moitis..

Notons que le portA a des entres analogiques, en service par dfaut lenclenchement. Il faut dsactiver (positionner un aiguillage pour mettre le convertisseur hors circuit) avec les 4 instructions que lon voit dans le programme T877Cli.asm:
Clr Set Move Move PortA Status:#RP0 #16'06,W W,AdCon1

On a pass en banque 1, il ne faudra pas oublier de revenir! 2.14 Pull-ups Sur une entre non connecte, le potentiel nest pas bien dfini. Si on connecte un poussoir, il faut une rsistance qui impose une tension sur lentre, en gnral le +5V (tat 1), et le poussoir court-circuite avec la masse (tat 0). Cette rsistance peut tre programme de faon plus ou moins lgante selon le processeur. Sur les anciens processeurs comme le 16F877, un seul bit met en service les pull-ups du port B seulement. Sur les processeurs plus rcents, des registres permettent de commander individuellement toutes les sorties avec ou sans pull-ups. Comment vrifier ? Initialisons le portB en entre, avec copie sur le portC. Ajoutons deux instructions qui connectent des pull-ups sur les entres du portB.
Move Move #0,W W,Option ; ce registre est spcial, on en reparlera

On remarque leffet en touchant les lignes du portB avec les doigts, laffichage sur le portC reste 1. Sans les pull-ups, (et sans interrupteurs ou affichage microdule) le doigt amne du 220V qui fait varier les entres, donc la copie sur le portC. 2.15 Rebonds de contact Si on veut compter les actions dun poussoir, le programme ne doit compter quune fois par action, et ne pas compter quand on presse, ni quand on relche. Il faut donc deux boucles dattente. Linterrupteur Microdule nest pas pratique comme poussoir, on peut en cbler un avec 3 fils (+ pour la pull-up, -, signal). Les contacts mcaniques ont des rebonds, pendant 0.1 2 millisecondes et le processeur peut les voir comme des actions spares si on chantillonne trop souvent. On chantillonne donc plus de 2ms, et moins de 0.1s pour ne pas rater les actions humaines les plus rapides. Le cur du programme pour compter contient donc des boucles dattente de 20ms (routine Del20ms) et scrit
AtPous : Call Del20ms TestSkip,BS PortC :#bPous Jump AtPous ; On attend laction Inc Compte AtRel : Call Del20ms TestSkip,BC PortC :#bPous Jump AtRel ; On attend le relchement Jump AtPous ; On recommence

Pour visualiser le compteur, on le copie par exemple dans le portD initialis en sortie. On peut aussi directement utiliser le portD comme compteur et remplacer Inc Compte par Inc PortD. Le programme T877CntPous.asm permet de tester ces rebonds. Mettez un ; (commentaire) devant les instructions Call Del20ms. Le processeur va compter les rebonds de plus de quelques microsecondes. Ajoutez dans le logiciel le test dun bit du portC pour faire une remise zro du compteur. Vous ne voyez pas comment ? Dans la boucle AtPous, testez un autre bit et sil est actif, il faut excuter linstruction Clr PortD.

2.16 Tester la dure daction sur un poussoir On veut savoir combien de temps, ou quand on a press sur un poussoir. Il faut dans la boucle dattente, surveiller le signal du poussoir, toutes les 50 millisecondes au moins si on veut tre assez prcis, et pas trop souvent si on ne veut pas mesurer la dure dun rebond de contact. Si on veut mesurer une dure, pour voir par exemple comment on peut tre rapide, on met un compteur zro, on attend quelques secondes avant dallumer une LED et on compte partir de cet instant. Le cur du programme est donc :
TestReflexe: Clr PortC:#bLed Call Attente ; attente 1-5 secondes Set PortC:#bLed Clr PortD AtPous: Call Del20ms Inc PortD ; Dure en multiple de 20ms TestSkip,BS PortC :#bPous Jump AtPous Fini: Jump Fini ; Jump APC idem, car APC = adresse de linstruction

On se pose naturellement beaucoup de questions avec ce programme. Comment compter en dcimal et pas en binaire, comment mettre un affichage 7 segments, comment faire un programme attractif. Cela viendra ! On voit la fin de ce programme linstruction Jump Fini ; il ny a plus rien faire pour nous, mais si on ne met pas cette instruction, le processeur va prendre les positions mmoire suivantes comme des instructions, et on ne peut pas deviner ce qui va se passer. 2.17 Musique Jouer une frquence audible se fait avec une boucle dattente. Nimporte quel haut-parleur avec une rsistance en srie de 100 Ohm peut tre branch entre la sortie dun port et le +5V. Un 0 va attirer la membrane, un 1 la relcher. A basse frquence (avec le programme T877Cli) on entend un clic lorsque la membrane est attire et relche. A frquence audible, lintensit est pafois trs variable cause des frquences de rsonnance du haut parleur. Plusieurs programmes sont expliqus sous www.didel.com/bot/sons/Sons.doc et les programmes cits peuvent tre trouvs sur le site et facilement adapts (il faut supprimer le .Ins Dev877.asi , remplacer le IOFF par linitialisation du port sur lequel est cbl le HP, et remplacer (ou crer) les macros HpOn HpOff. 2.17 Infrarouge Les tlcommandes infrarouges transmettent des trains dimpulsion 36-40 kHz. Un circuit IRM (Infra Red Module) filtre et donne sur sa sortie lenveloppe du signal, en impulsions ngatives de 0.8 3 ms en gnral.

Le plus simple est de brancher lIRM sur une entre, et de reconnatre laction dune tlcommande de TV quelconque, comme si ctait un poussoir avec des rebonds.Essayez le programme T877CntPous.asm avec une attente dfinir. Un oscilloscope est ncessaire pour mettre au point des programmes non triviaux. Le principe des tlcommandes Emir est expliqu brivement sous www.didel.com/Ir/EmirSpecs.pdf Les tlcommandes PicoZ sont expliques sous http://www.didel.com/Ir/IrControl.pdf . Le format RC5 utilis dans la plupart des tlcommandes commerciales est abondamment document sur le Web.

3. Toutes les instructions


Rappelons que chaque instruction a ventuellement un effet sur des bits stocks dans le registre d'tat (status). Le bit Z ( ou flag Z) indique si l'octet transfr est nul (zro). Il n'est pas activ par toutes les instructions qui devraient ou pourraient le faire, il faut donc vrifier sur la feuille de codage avant d'imaginer soi-mme la logique du processeur. Le bit C indique qu'une opration arithmtique a eu un dpassement de capacit. Le PIC ne ragit pas comme d'autres processeurs et il faudra faire attention avant de tester ce bit. Le bit D est exceptionellement utilis pour les calculs en dcimal. La feuille de codage compacte est en dernire page. www.didel.com/pic/CalmInstr877.pdf Imprimez quelques copies, cest indispensable den avoir toujours une sous la main pour vrifier que linstruction existe et quel est son effet sur les flags. Sur cette feuille et ci-dessous, les flags modifis sont indiqus entre crochets. En premire colonne, la notation de microchip est rappele pour ceux qui y sont familiariss. Le passage de Microchip CALM est facile, mais il y a des variantes de lassembleur Microchip avec diffrentes notations. 3.1 Instructions de dplacement (Move) On notera que le flag Z n'est pas toujours modifi. MOVLW VAL Move #Val,W [none] MOVWF REG Move W,Reg [none] MOVF REG,0 Move Reg,W [Z] MOVF REG,1 Test Reg [Z] Rappelons que le signe dize # prcde une valeur numrique. S'il est oubli, le processeur va chercher une variable cette position. L'assembleur signalera une erreur si le nombre est suprieur 16'7F, puisque le processeur ne peut pas adresser plus de 127 variables. Autrement le programme a de bonnes chances de drailler. Des instructions spciales agissent sur le registre OPTION et sur les registres de direction des PICs 28 broches au plus. TRIS PORTA Move W,TrisA [none] TRIS PORTB Move W,TrisB [none] TRIS PORTC Move W,TrisC [none] OPTION Move W,Option [none] CLRWDT ClrWDT [none] SLEEP Sleep [none] Pour les instructions trs spciales ClrWdt et Sleep, consultez la documentation de Microchip. Note : les trois instructions Move W,TrisA etc seront remplaces prochainement par TrisA etc et TrisA B C D E deviendront des adresses en banque1 avec les mmes valeur numriques que PortA B C D E. Attention, actuellement Move W,TrisD Move W,TrisE sont accepts par lassembleur mais nont pas deffet. Ces instructions seront correctes quand lassembleur sera modifi, mais en banque 1 seulement. 3.2 Instructions logiques (AND OR XOR) Toutes ces instructions modifient le bit Z (Z = 1 si le rsultat est zro). ANDLW VAL And #Val,W [Z] ANDWF REG,0 And Reg,W [Z] ANDWF REG,1 And W,Reg [Z] IORLW VAL Or #Val,W [Z] IORWF REG,0 Or Reg,W [Z] IORWF REG,1 Or W,Reg [Z] XORLW VAL Xor #Val,W [Z] XORWF REG,0 Xor Reg,W [Z] XORWF REG,1 Xor W,Reg [Z] Rappelons que le ET logique (And) garde les bits qui sont un dans les deux oprandes. Le OU (Or) garde tous les bits. Le Ou exclusif (XOR) garde les bits qui sont complmentaires (diffrents). On utilise souvent le XOR pour dcider si les deux nombres/contenus de registres sont gaux.
11010010 10101010 -------And 10000000 11010010 10101010 -------11111010 11010010 10101010 -------Xor 01111000 11010010 11010010 -------00000000 (Z=1)

Or

Xor

3.3 Instructions arithmtiques (Add,Sub) L'addition modifie les tros bits d'tat [C,D,Z]. ADDLW VAL Add #Val,W [C,D,Z] Val + (W) W ADDWF REG,0 Add Reg,W [C,D,Z] (Reg) + (W) W ADDWF REG,1 Add W,Reg [C,D,Z] (W) + (Reg) Reg La notation (W) signifie contenu de W. Le processeur additionne les deux valeurs, transfres dans le registre W.
+ + 11010010 Add 10101010 -------[C=1] 01111100 + 11000010 Add 00101010 -------[C=0] 11101100 +++++++ reports 01010010 Add 10101110 -------[C=1 Z=1) 00000000

Pour la soustraction, CALM utilise la notation Motorola: le 1er oprande est soustrait du second. Contrairement la majorit des processeurs, les PICs font la soustraction par addition du complment 2. SUBLW VAL Sub W,#Val,W [C,D,Z] Val + -(W) W SUBWF REG,0 Sub W,Reg,W [C,D,Z] (Reg) + -(W) W SUBWF REG,1 Sub W,Reg [C,D,Z] (Reg) + -(W) Reg (equiv. to Sub W,Reg,Reg)
Sub - 11010010 10101010 -------++ + ++ 11010010 Add 01010110 -------[C=1] 00101000 (#Val ou Reg) + (-W)

On voit que le Carry est invers par rapport l'opration usuelle de soustraction. La soustraction d'une valeur immdiate est trs diffrente de tous les autres processeurs et la notation CALM montre bien que l'on prend la valeur et soustrait le contenu de W. Si l'on doit soustraire une valeur une variable, on ajoute le complment 2 de la valeur: Add #-Val,W La soustraction est souvent utilise pour comparer deux variables (c'est dire les nombres 8 bits contenus dans ces variables): Move Var1,W Sub W,Var2,W Si le carry est un (CS Carry Set), Var2 est suprieur Var1. Si le bit Z est un, les deux nombres sont gaux. Les soustractions, comparaisons et gestion des nombres ngatifs peuvent tre tudies quand on en a besoin, voir en particulier www.didel.com/pic/Arith.pdf. Cest assez rare ; un microcontrleur manipule des bits, mesure des temps, passe par des tables, et nest pas fait pour calculer ! 3.4 Incrmentation/dcrmentation (INC, DEC) INCF REG,1 Inc Reg [Z] INCF REG,0 Inc Reg,W [Z] DECF REG,1 Dec Reg [Z] DECF REG,0 Dec Reg,W [Z]

(Reg)+1 (Reg)+1 (Reg)-1 (Reg)-1

Reg W, (Reg) Reg W, (Reg)

Reg Reg

Attention, Inc Reg,W ne modifie pas Reg. Si lon veut la fois incrmenter Reg et en avoir une copie dans W, il faut deux instructions, incrmenter et copier 3.5 Complment et effacement (NOT, CLR) COMF REG,1 Not Reg [Z] inv(Reg) COMF REG,0 Not Reg,W [Z] inv(Reg) CLRF REG Clr Reg [Z=1] 0 Reg CLRW Clr W [Z=1] 0 W Reg W, (Reg)

Reg

Le complment (complment 1) est une inversion de tous les bits. On peut le faire avec un Ou exclusif, ce qui est ncessaire pour inverser le registre W.
Xor #16'FF,W Xor #2'11111111,W Xor # -1,W

Le complment arithmtique (complment 2) est diffrent. C'est la diffrence zro que l'on obtient par soustraction. Sub W,#0,W On peut aussi appliquer la rgle que le complment 2 est gal au complment 1 plus 1, ce qui convient mieux pour complmenter une variable. Not Reg Inc Reg [Z] -(Reg) --> Reg La notion de complment a 2 est lie aux nombres ngatifs. Prudence ! 3.6 Rotation et permutation (RRC, RLC, Swap) Les dcalages droite ou gauche se font travers le carry. RRF REG,1 RRC Reg [C] RRF REG,0 RRC Reg,W [C] (Reg) not modified RLF REG,1 RLC Reg [C] RLF REG,0 RLC Reg,W [C] (Reg) not modified SWAPF REG,1 Swap Reg SWAPF REG,0 Swap Reg,W (Reg) not modified Attention de nouveau, RRC Reg,W ne modifie pas Reg. Il faut en gnral prparer le carry avant de faire un dcalage si on ne veut pas injecter une valeur alatoire droite ou gauche. Par exemple pour dcaler droite un nombre de 16 bits contenu dans deux variables, on crit
ClrC RRC RRC High Low

Swap permute les deux moitis d'un mot de 8 bits. Cela ne remplace pas 4 dcalages, puisque la rotation se fait au travers du carry et ncessite 9 dcalages pour un tour complet.
11010010 swap 00101101

3.7 Instructions sur des bits Le PIC est trs performant pour forcer ou tester un bit sur un port ou une variable. L'instruction doit spcifier la variable, et le numro du bit, qui est une valeur immdiate, donc prcde d'un signe #. BCF REG,bNumber Clr Reg:#bNumber [none] BSF REG,bNumber Set Reg:#bNumber [none] BTFSC REG,bNumber TestSkip,BC Reg:#bNumber [none] BTFFS REG,bNumber TestSkip,BS Reg:#bNumber [none] Des exemples ont t vus prcdemment. L'instruction Not Reg:#bNumber qui permettrait d'inverser un bit manque souvent. On la remplace en faisant intervenir un OU exclusif, ce qui malheureusement modifie W:
Move Xor #2**bNumber,W W,Reg

Les instructions logiques (And, Or, Xor) peuvent de faon similaire agir sur plusieurs bits la fois pour mettre un, mettre zro ou inverser. Le registre de status qui contient les indicateurs C, D et Z peut tre modifi par des set et clr bits. Calm documente les instructions suivantes, pratiques utiliser: BSF STATUS,0 SetC [C=1] Set carry BCF STATUS,0 ClrC [C=0] Clr carry BSF STATUS,1 SetD [D=1] Set D, decimal carry flag BCF STATUS,1 ClrD [D=0] Clr D BSF STATUS,2 SetZ [Z=1] Set Zero flag BCF STATUS,2 ClrZ [Z=0] Clr Zero flag BTFSC STATUS,0 Skip,CC Skip if Carry Clear BTFSS STATUS,0 Skip,CS Skip if Carry Set BTFSC STATUS,1 Skip,DC Skip if Digit carry Clear BTFSS STATUS,1 Skip,DS Skip if Digit carry Set BTFSS STATUS,2 Skip,EQ Skip if Equal BTFSC STATUS,2 Skip,NE Skip if Non Equal

3.8 Instructions de saut L'instruction de saut a une limitation d'adresse 1k (10 bits d'adresse). Il y a naturellement un moyen pour tendre l'accs dans les PICs ayant plus de mmoire. GOTO ADDR Jump Addr Il n'y a pas dans les PICs des instructions de saut conditionelles comme dans les autres processeurs. Le Skip conditionnel est un peu moins agrable crire, mais tout aussi efficace. INCFSZ REG,0 IncSkip,EQ Reg [none] Increment Reg and Skip if result is Equal to zero INCFSZ REG,1 IncSkip,EQ Reg,W [none] (Reg) not modified Copy Reg in W, then increment W and Skip if result is Equal to zero. DECFSZ REG,0 DecSkip,EQ Reg [none] DECFSZ REG,1 DecSkip,EQ Reg,W [none] (Reg) not modified On remarque que les instructions IncSkip,NE DecSkip,NE n'existent pas. On les remplace facilement par deux instructions: Inc Reg Skip,NE 3.9 Appel de routines (Call, Ret, RetI) On ne peut imbriquer que 8 appels de sous-programmes. C'est rarement une limitation, sauf sur les processeurs 12F et 10F qui nont que deux niveaux et o cela alourdit parfois lcriture. CALL Addr Call Addr (call routine) RET Ret (return from subroutine) RETFIE RetI (return from interrupt) RETLW Val RetMove #Val,W (load W and return) L'instruction RetI (return from Interrupt) active le bit GIE (General Interrupt enable) en plus de recharger l'adresse de retour (section 4). L'instruction RetMove #Val,W est trs intressante, on le verra plus loin. Elle charge une valeur dans W au moment du retour, comme la syntaxe CALM l'exprime clairement. 3.10 Banques de registres et pages mmoire Larchitecture des PICs a t dveloppe en 1973 quand la mmoire se mesurait en bytes et pas en gigabytes. Avec leurs instructions de 12 ou 14 bits, les PICs sont trs efficaces pour des programmes courts avec peu de variables. Des trucs permettent daugmenter ces capacits dadressages limites, mais sil vous faut juste un peu plus de variables et de mmoire, apprenez programmer efficacement, et sil en faut beaucoup plus, changez de processeur ! Les PICs ont jusqu 4 banques de registres, de 128 octets au maximum, dans lesquelles se trouvent les priphriques et leurs registres de contrle, plus des variables selon le processeur. On change de banque en modifiant des bits dans le registre Status. Le plus clair est de dfinir des macros comme dans lexemple I2C donn plus loin. Avoir des variables dans plusieurs banques alourdit le programme. Notre conseil est que le programme principal ne travaille quavec des variables en banque 0, les commutations de banques nayant lieu qu lintrieur de routines bien dfinies. Le compteur dadresse des PICs na que 11 bits, limitant les sauts dans 2k de mmoire. Le document www.didel.com/picg/doc/DocPage.pdf montre comment passer des adresses suprieures. Il y a encore dans la mmoire des PICs des frontires toutes les 256 instructions que linstruction gniale Add W,PCL ne sait pas franchir. Il y a enfin dans les PIC 10F et 12F avec instructions 12 bits des limitations tudier dans les documents www.didel.com/picg/doc/DopiComp.pdf et www.didel.com/pic/Compati200.pdf

4.Timers et interruptions
Les PICs ont 1,2,3 timers. Ce sont des compteurs avec de la logique autour pour compter plus ou moins vite et mesurer ou gnrer des signaux. Ce document se limite au TMR0, qui existe dans tous les PICs 10F, 12F, 16F. Les autres timers doivent tre tudis avec les programmes de test mis disposition et avec la documentation du fabricant ou des traductions. 4.1 Timer 0 Le timer 0 est un exemple simple dun circuit programmable. Le TMR0 est un compteur que le programme peut lire ou crire comme une variable. Il tourne toujours, et quand il dborde, il active une bascule, appele TOIF (Timer Overflow Flag). Cette bascule est dans le registre IntCon. Le compteur est prcd dun prdiviseur programmable, cest dire que loscillateur qui fait tourner le processeur peut tre divis par une valeur code sur 3 bits pour avoir un compteur qui tourne 1 MHz, 0.5 Mhz, 3.9 Khz (processeur 4 MHz). Il y a encore une possibilit pour compter des impulsions extrieures propres (sil y a des rebonds, ils seront tous compts).

Le schma-bloc est trs clair. On voit que pour compter le front descendant dun signal cbl sur RA4 sans prdivision, il faut charger 200111000 dans Option. Testons la fonctionnalit du TOIF en incrmentant un compteur (PortD) quand le TMR0 dborde. On compte si TOIF est actif, et on efface immdiatement TOIF (on r-arme la bascule), donc on ne compte quune fois par tour.
Move #200000111,W ; prdiviseur max Move W,Option Clr TMR0 Clr Option :#TOIF Clr PortC At$: TestSkip,BS Intcon:#TOIF Jump Ato ; on attend Clr Intcon:#TOIF ; on pourrait initialiser TMR0 une valeur qui raccourcirait le cycle Inc PortC
; on pourrait utiliser le PortC comme compteur 16 bits, (voir T877T0c.asm)

Jump At$ Le programme T877Tmr0.asm permet de tester. Modifiez la valeur de prdivision dans Option.

4.2 Mesures de dures Le timer peut compter plus vite quune boucle dattente, et il compte sans ralentir le programme. Pour mesurer la dure dune impulsion sur le poussoir (ou limpulsion plus rapide dune tlcommande infrarouge), on met le compteur zro au dbut de limpulsion et on attend la fin de limpulsion pour faire la mesure.
; le signal est sur bPous sur le portC Atp: TestSkip,BS PortC :#bPous Jump Atp ; on attend laction Clr TMR0 ; Prdiviseur selon les dures mesurer Atr: TestSkip,BC PortC :#bPous Jump Atr Move TMR0,W ; W contient la dure. On peut lafficher ou lutiliser.

A vous de faire le programme, cette fois ! Mais attention, le temps maximum mesurable est 256X255 microsecondes = 60ms, trop peu pour un poussior. Il faut ajouter un compteur, qui mesure par exemple le centime. Le truc est expliqu plus loin si vous ne voyez pas..

4.3 Timer par interruption Dans lexemple prcdent, on voit que le timer augmente la prcison de la mesure, mais le programme est bloqu surveiller le poussoir. Linterruption permet davoir une tche qui sexcute quand il le faut, en suspendant lexcution du programme principal, qui en fait ne se rend pas compte quil est interrompu. La routine dinterruption est ladresse 4. Le programme principal doit sauter par dessus.. Prenons un exemple trop simple. Le programme principal compte de faon visible sur le portC, toutes les 0.1s par exemple. Linterruption du timer remet zro ce compteur toutes les secondes. En plus de linitialisation du port qui compte et du timer, il faut initialiser linterruption, ce qui veut dire activer 2 bits dans le registre IntCon, une pour une activation gnrale des interruptions (GIE General Interrupt Enable) et une pour linterruption spcifique du Timer0 (TOIE Timer0 Interrupt Enable). Ce quil faut faire chaque interruption due la bascule TOIF, cest de quittancer le TOIF, et utiliser un compteur auxiliaire pour effacer le PortC toutes les secondes (on ne peut pas ralentir le timer suffisamment). Le cur de la routine dinterruption est donc
; On dsactive le bit qui a demand l'interruption Clr Intcon:#TOIF Move #IniTmr0,W Move W,TMR0 Inc CInt ; Compteur auxiliaire par 256 pour ralentir Skip,NE Clr PortC ; Chaque 256 x 256 x 16 us = ~1s

On voit que ce programme, qui va tre appel sans avertir quand le timer dborde, utilise le regitre W. Il ne faudrait pas que le registre W, frquemment utilis par le programme, soit modifi par linterruption. On doit donc rajouter 3 instructions au dbut et 5 instructions la fin pour que la routine dinterruption sauve et rtablisse W, ainsi que les flags Z et C. Le programme T877T0Int.asm, est le suivant :
\prog;T877T0Int.asm|Timer par interruption ; Le programme principal compte ~15Hz sur le ; PortC et l'interruption mets zro ce portC toutes les 256 boucles d'interrupt. ; On voit que le compteur ne vas jamais trs loin. ;Agir sur IniOption et sur IniTmr0 .Proc 16F877 .Ref 16F877 \var;Registres| SaveF = 16'20 SaveW = 16'21 CInt = 16'22 CX1 = 16'23 CX2 = 16'24 \var;Ports| \b;PortC comme compteur DirC = 0 \const; Initialisation IniOption = 2'0000001 ; :16 IniTmr0 = -200 ; 256-200 .loc Jump 0 Deb \b;Programme principal Deb: Set Status:#RP0 Move #DirC,W Move W,PortC Clr Status:#RP0 Move #IniOption,W ; Prescaler :16, 16 us Move W,Option Clr IntCon:#TOIF Move #2**GIE+2**TOIE,W Move W,IntCon Loop: Inc PortC ; Attente pour incrmenter env 15 fois par seconde A$: DecSkip,EQ CX1 Jump A$ DecSkip,EQ CX2 Jump A$ Jump Loop .Loc .16 .End 16'2007 16'3F39

.loc 4 ; Interrupt tous les 256x16 us Move W,SaveW ; Ne modifie pas F Swap F,W ; Truc Move W,SaveF ; On dsactive le bit qui a demand l'interruption Clr Intcon:#TOIF Move #IniTmr0,W Move W,TMR0 Inc CInt ; Compteur auxiliaire par 256 pour ralentir Skip,NE Clr PortC ; Chaque 256 x 256 x 16 us = ~1s F$: Swap SaveF,W Move W,F Swap SaveW Swap SaveW,W RetI

Rappelons que le TMR0 est un compteur. Si on veut que TOIF sactive aprs un comptage de 200, il ne faut pas linitialier avec la valeur 200 (il augmentrait de 200 256=0 et TOIF sactiverait), mais avec la valeur 256-200, identique pour lassembleur -200. 4.4 Timer1 Le timer 1, quand il est disponible comme sur le 16F877, est un compteur 16 bits avec prdiviseur. Le programme T877T1Int.asm teste son fonctionnement. Il peut tre coupl 2 pins sur lesquelles on branche un quartz horloger 32 Khz, ce qui permet de programmer une horloge prcise.. Le timer2 est beaucoup plus riche et permet du PWM (voir section 6.2) et une mesure plus efficace de dures dimpulsions.

5. Entres analogiques
Les PICs nont pas tous des canaux analogiques. Si oui, ils ont la mme structure avec une prcision de 10 bits, et nous utiliserons le mode qui laisse tomber les 2 bits de poids faible : il faut une construction qui respecte plusieurs rgles pour avoir des mesures fiables en 10 bits. Le document de Bigonoff traduit de faon trs claire toutes les possibilits offertes par Microchip http://www.abcelectronique.com/bigonoff/ . Nous allons simplifier au maximum. Si le PIC na pas dentres analogiques, on peut lire trs efficacement des signaux analogiques en mesurant des temps de charge et dcharge de condensateurs. Voir http://www.didel.com/picg/doc/DopicAD.pdf 5.1 Initialisation Le 16F877 a 8 canaux analogiques possibles sur le portA et le portE. Il en suffit souvent dun ou deux, et on veut garder les autres lignes pour des entres-sorties tout-ou-rien. Sur le 16F877, 4 bits du port AdCon0 offrent quelques combinaisons, et il faut bien rflchir pour cbler son application. Les processeurs plus rcents offrent une plus grande flexibilit. Il faut comprendre que dans linitialisation, on dit quels sont les canaux analogiques en service (registre AdCon1), mais le programme lit un canal la fois et il faut dire lequel on lit (registre AdCon0, nomm AnSel sur dautres PICs). Pour la lecture, il faut slectionner le canal, attendre 20 microsecondes que les aiguillages internes se positionnent, dmarrer la conversion et attendre quelle soit termine, avec le rsultat dans AdResH (on a dcid doublier la partie poids faibles AdResL, mais on peut la lire sur les bits 7 et 6).

Par exemple, on veut initialiser seulement RA0 en entre analogique et la lire. Dans les dfinitions on va dclarer
DirA = 2010001 ; ou 2111111 IniAdCon0 = 2'00001110 ; sel RA0 seul SelAd0 = 2'11000001; sel AD0 en mode8 bits

Dans linitialisation on doit avoir


Clr Set Move Move Move Move Move Move Clr PortA Status:#RP0 #IniAdCon1,W W,AdCon1 #DirA,W W,PortA #0,W W,TrisC Status:#RP0

Et dans le programme
Move #SelAd0,W Move W,AdCon0 Call Del20 ; attente 20 us Set AdCon0:#Go ; C'est parti TestSkip,BC AdCon0:#Go Jump C$ ; On attend Move AdResH,W Move W,PortC ; On affiche la valeur

C$:

Pour le test, il faut brancher un potentiomtre avec le point milieu sur RA0 et utiliser le programme T877Ana.asm Sans potentiomtre, si on touche avec le doigt, on perturbe lentre haute impdance. 5.2 Lecture par interruption Lattente sur la conversion prend 100 200 microseconde. On a donc avantage lire les canaux analogiques par interruption. Passez plus loin si cela semble compliqu. Le timer dclanche toutes les 20ms une interruption qui dmarre une cascade dinterruptions pour lire les canaux sur RA0, RA1, RA3 (RA2 est spcial). Au moment de linterruption, il faut dcider do elle vient, et un pointeur doit mettre les valeurs lues dans une zone mmoire.

Dans les dfinitions, il faut dclarer


IniOption = 2'00000110 ; divise par 128 IniTmr0 = -156 ; 156 x 128us = 20ms IniAdCon310 = 2'00000100 ; sel RA3 RA1 RA0 SelAd0 = 2'11000001; sel AD0 en mode8 bits SelAd1 = 2'11001001 SelAd2 = 2'11010001

Dans les variables, il faut dclarer


Var Var Var Var Var Var Clr Set Move Move Move Move Move Move Clr Move Move Clr Move Move SaveF SaveW NCanal Canal0 Canal1 Canal2 PortA Status:#RP0 #TrisA,W W,PortA #TrisC,W W,PortC ; Affichage #IniAdCon310,W W,AdCon1 Status:#RP0 #IniOption, ; Le timer W,Option IntCon:#TOIF #2**GIE+2**PEIE+2**TOIE,W W,IntCon

Linitialisation contient les instructions

; Timer seul

La routine dinterruption contient les instructions


TestSkip,BC IntCon :#TOIF Jump InterTimer TestSkip,BC PIR1 :#ADIF Jump InterAna Jump Error InterTimer : Clr IntCon:#TOIF Move #IniTmr0,W Move W,TMR0 Clr IntCon:#TOIE ; Coupe les interrupt timer ; On met en route 3 interrupt Ana Move #3,W Move W,NCanal Move #SelAd0,W Move W,SaveSelAD Set PIE1:#ADIE DebAna: Clr PIR1 :#ADIF Move SaveSelAD,W Inc SaveSelAD Move W,AdCon0 Move #200001000,W Add W,SaveSelAD Call Del20 Set AdCon0:#Go ; C'est parti Jump Rt ; Suite au prochain interrupt Ana InterAna : ; AdCon0:#Go a dclanch linterrupt ; Il faut sauver AdResL au bon endroit Move Canal0,W Move W,FSR Move NCanal,W Add W,FSR Move AdResH,W ; mets zro Go Move W,{FSR} ; voir section 6 ?? ; on prepare la lecture suivante DecSkip,EQ NCanal Jump Rt ; On a lu les 3 canaux, on repasse in interrupt timer Clr PIE1:#ADIE Set Intcon :#TOIE Rt :

Le programme complet se trouve sous T877AnaInt.asm On voit que grer plusieurs vnements par interruption nest pas trs simple. Pour une tlcommande infrarouge qui doit lire trois potentiomtres et envoyer un train dimpulsions toutes les 40 us, les interruptions ne sont pas utilises car les deux tches effectuer ne sont pas simultanes. Lcriture du programme est trs simple.

6 Commande de moteurs
Il existe plusieurs types de moteurs de puissance trs varie. Seuls les moteurs de faible puissance nous intressent. La commande en tout-ou-rien dun moteur ou lectro-aimant sapparente la commande dune LED, avec ventuellement un transistor amplificateur, donc rien de plus dire, si ce nest que les pointes de courant au dmarrage du moteur peuvent perturber le fonctionnement du processeur. On vrifie en remplaant les moteurs par des LEDs. 6.1 Moteurs bidirectionnels Les moteurs courant continu ont deux fils et se commandent comme des diodes bicolores, mais en gnral aux travers damplificateurs appels ponts en H. Si le courant demand est entre 10 et 50mA, on peut lier des sorties du processeur entre elles pour augmenter le courant. Microchip parle de 20mA par sortie, mais cest en court-circuit ! 6.2 PWM (Pulse Width Modulation) Le principe du PWM est de varier la largeur dune impulsion rptitive. Les processeurs performants ont des canaux PWM obtenus en programmant le timer 2 ou le timer3, mais il faut utiliser les sorties prvues sur le microcontrleur. Ce nest pas trs simple si le sens du moteur doit tre invers. Il faut bien lire la documentation du fabriquant et passer du temps sur le programme de test. En logiciel, le principe est simple et efficace, et permet de commander autant de moteurs que lon veut, sur les sorties que lon veut, une frquence et rsolution adquates pour des application non industrielles. Les explications gnrales sont donnes sous www.didel.com/picg/picg87x/Picg75.pdf page 28. Le programme de test T877Pwm.asm montre comment commander un moteur unidirectionnel et un moteur bidirectionnel en logiciel. Le programme de test T877PwmT2.asm utilise le Timer2.

6.3 PFM (Pulse Frequency Modulation) Le PFM est mal connu car il nest pas utilis sur les moteurs performants. Mais pour les moteurs jouet ou miniatures, il permet une commande faible vitesse trs intressante. La frquence est faible et facilite la programmation multi-tche. Les explications sont donnes sous www.didel.com/picg/picg87x/Picg75.pdf page 29. Le programme de test T877Pfm.asm montre comment commander un moteur unidirectionnel et un moteur bidirectionnel en logiciel. Pour des moteurs pager qui ont une tension de dmarrage importante cause du frottement, le PFM avec des impulsions de 2 5ms suffisantes pour faire dcoller le moteur permettent de couvrir toute la gamme de vitesses. 6.4 Moteur pas--pas Lavantage du moteur pas pas est que son angle de rotation dpend du nombre de pas, tant que le couple maximum nest pas dpass. Ces moteurs sont commands par 4 phases, avec des demi-phases possibles pour un mouvement plus rgulier. Une table dfinit la squence. Pour changer de sens on dplace le pointeur en sens inverse, en grant correctement le passage par les extrmits. Des explications gnrales se trouvent sous www.didel.com/picg/picg87x/Picg75.pdf page 27, mais les exemples de programmes concernent des moteurs 6 phases. La transposition est facile.

Les moteurs horlogers (Lavet) ont 6 phases (Switec, Wellgain). Des explications dtailles sont donnes dans le lien ci-dessus et sous www.didel.com/picg/doc/DopiSwi.pdf . Une doc plus rcente avec exemples se trouve sous www.didel.com/bot/step/Step.doc Avec du PWM ou du PFM, on peut lisser les phases pour se rapprocher dune excitation sinusoidale. Ceci ne prsente pas dintrt, mais ctait une recherche intressante ! http://www.didel.com/picg/doc/DopiSmoo.pdf et sous http://www.didel.com/picg/doc/DocLimot.pdf 6.5 Moteurs brushless Les moteurs sans collecteur sont des moteurs pas pas asservis par une lectronique qui permet dobtenir le couple maximum. Ils sont donc commands par des circuits extrieurs au microcontrleur qui reoivent les ordres de vitesse via une interface parallle ou srie (les modlistes avion utilisent des circuits avec une entre PPM comme les servos). 6.6 Servos de tlcommande et PPM Les servos de tlcommande ont une entre qui est une impulsion de 1 2ms rpte toutes les 20ms. La dure de limpulsion fixe la position du servo (Pulse Position Modulation). Pour un exemple de programme de codage simple (monotche), voir http://www.didel.com/picg/doc/DocServo.pdf. 6.7 Encodeur Pour connatre la position dun moteur continu ou dun axe, on utilise un encodeur (quadrature encoder) qui gnre des impulsions dphases. A dfaut de circuits spcialiss, un programme chantillonne et compte/dcompte les incrments jusqu des priodes de 100 us par transition. Des algorithmes efficaces sont expliqus sous http://www.didel.com/picg/doc/PicSoft.pdf (page 15-16) et http://www.didel.com/picg/picg87x/Picg75.pdf (page 29)

6.8 Capteurs de distance et autres Les capteurs gnrent des impulsions ou des niveaux analogiques que les microcontrleurs grent facilement. Les capteurs intelligents ont un contrleur propre et communiquent en gnral en srie. Une documentation sur les capteurs de distance par infrarouge se trouve sous http://www.didel.com/doc/sens/DocIr.pdf http://www.didel.com/doc/sens/DocIrt.pdf http://www.didel.com/doc/sens/DocSharp.pdf Internet permet de trouver beaucoup dinformation plus ou moins complte sur les capteurs et leurs interfaces.

Les capteurs intelligents, cest dire qui ont un prconditionnement des signaux, envoient souvent linformation en srie vers le processeur.

7 Transferts srie
Si une application comme un affichage a besoin de plusieurs lignes de commande, il est prfrable dutiliser un circuit spcialis et lui transfrer linformation en srie sur quelques fils, donc en nutilisant que 1 4 sorties du processeur. 7.1 Registres srie Linformation dun registre peut tre dcale en srie. A chaque impulsion dhorloge, un bit est dcal. Une impulsion Load charge au dbut linformation dans le registre srie (PISO Parallel In Serial Out), 8 impulsions CK dcalent. Si le registre destination (SIPO Serial In Parallel Out) a un registre en sortie une impulsion Store charge ce registre aprs les 8 impulsions de dcalage. La polarit de lhorloge et des impulsions dpend des circuits utiliss.

Le microcontrleur peut tre dun ct ou de lautre. Linstruction de dcalage va simuler le registre et les signaux ncessaires seront activs/dsactivs par programmation. Les routines dcriture et de lecture sont donnes sous www.didel.com/picg/picg87x/Picg76.pdf page 36. Le circuit Ext8i8o ajoute 8 entres et 8 sorties en nutilisant que trois lignes du processeur www.bricobot/kits/Ext8i8o.pdf Les signaux Load et Store sont gnrs lintrieur du module. Le programme T877Ext8i8o.asm teste ce module dextension. Notons encore que les registres dcalage peuvent tre cascads. Avec le mme nombre de lignes utilises sur le microcontrleur, on peut commander autant dentres sorties que lon veut, mais videmment cela prend du temps de transfert. 7.2 Transfert en criture La routine exemple ci-dessous doit tre adapte lapplication. Le dcalage ne doit pas ncessairement de faire droite, et la polarit des impulsions peut tre inverse.
\rout:Write|Transfer 8 bits serially \in:DataOut, transferred LSB first \mod:DataOut, C1 Write: Move #8,W Move W,CntCk L$: RRC DataOut Skip,CC Set PortA:#bData Skip,CS Clr PortA:#bData Clr PortA:#bCk Set PortA:#bCk DecSkip,EQ CcntCk Jump L$ Set PortA:#bStore Clr PortA:#bStore Ret

7.3 Transfert en lecture

\rout:Read|Get 8 bits serially \out:DataIn read, transferred LSB first \mod:DataIn, CntCk Read: Move #8,W Move W,CntCk Set PortA:#bLoad Clr PortA:#bLoad L$: ClrC TestSkip,BC PortA:#bData SetC RRC DataIn Clr PortA:#bData Clr PortA:#bCk DecSkip,EQ CntCk Jump L$ Ret

7.4 SPI Le SPI utilise 3 lignes pour le transfert et une ligne pour la slection de chaque esclave. http://en.wikipedia.org/wiki/Serial_Peripheral_Interface_Bus Une logique interne envoie et reoit linformation et active un flag quand le transfert est termin. Par interruption, des dbits importants, par exemple pour commander un affichage graphique, sont obtenus, mais les PICs sont rarement adapts pour ce type dapplication. Voir aussi la doc plus ancienne www.didel.com/picg/doc/DocSPI.pdf 7.5 I2C I2C est souvent intressant pour se relier des circuits horloge ou mmoire de stockage dinformation. Les PICs haut de gamme ont des circuits cbls pour grer le I2C, mais pour des applications simples et lentes, les routines logicielles sont tout aussi faciles matriser et prennent une centaine doctets. Pour plus de dtails, voir www.didel.com/picg/doc/DopicI2C.pdf . 7.6 USART Tous les PC avaient anciennement une entre dite RS232 trs pratique pour communiquer avec le microcontrleur. Voir www.didel.com/dev877/PdSerie.doc comme exemple. Avec un adaptateur USB-RS232 on obtient thoriquement le mme service. Ct PC, un programme terminal dialogue avec le clavier-cran via la ligne srie. Une fois la liaison tablie, il faut installer un programme de communication srie. Hyperterminal est difficile configurer. TeraTerm est facile demploi http://en.wikipedia.org/wiki/Tera_Term Il peut se tlcharger depuis www.didel.com/dev877/Ttermpro.zip.

Tous les microcontrleurs PIC qui ont un USART (Universal Serial Asynchronous Receiver and Transmitter) cbl semblent avoir les mmes registres de commande. Il faut dfinir la vitesse de transmission et grer le protocole qui est simple si on ne se proccupe pas de la gestion des erreurs de transmission. Pour envoyer, on crit dans le registre TxD et on surveille le bit TxIF pour savoir si on peut envoyer le byte suivant. Si on attend de linformation, on surveille un bit RcIF qui sactive quand un byte est arriv. La lecture dans le registre RcReg met zro RcIF. Le programme T877Alpha.asm envoie lalphabet sur lcran en rponse une touche presse. Le transfert se fait 2400 bits/s, ce que lon peut facilement changer par programmation ( la fois dans linitialisation et dans lUART tool.

Le document http://www.didel.com/picg/doc/DopicSer.pdf donne des routines pour contrleur sans interface srie et avec. A noter encore que le Pickit2 a un mode convertisseur srie-UART (menu Tools, dplacer le Pickit). Le microdule 2840, avec sauf erreur tous les PICs 28 et 40 broches, peut donc tre utilis trs facilement pour dvelopper des applications avec communication srie.

On peut taper sur le clavier, envoyer une chane de caractres.

On peut imaginer das applications ou le microcontrleur est un esclave du PC, rpond des ordres, donne ltat de ses capteurs. Lapplication principale tourne dans le PC et nest pas limite en complexit. 7.7 USART par logiciel Programmer un transfert srie compatible RS232 est facile, mais il faut respecter un timing prcis, et ne pas avoir dinterruption pendant le transfert. La vitesse de transfert est limite 2400 bits/s avec un processeur 4 MHz et les routines ncessaires utilisent moins de 50 instructions. Voir www.didel.com/picg/doc/DopicUti.pdf qui documente aussi des routines pour afficher des textes, valables dans tous les cas. 7.8 Transferts one-wire Dallas Dallas propose des circuits commands par 2 fils seulement : la masse (gnd) et lalimentation qui est pulse pour transfrer une information bien assez rapide pour beaucoup dapplications. Pour plus de dtails, voir http://www.maxim-ic.com/products/1-wire/ 7.9 Petra Le Bus Petra de Didel permet dadresser 16 units qui ont leur propre processeur, et davoir dans 16 variables successives limage des informations gres par ces units (par exemple une mesure de distance. Pour plus de dtails, voir http://www.didel.com/Petra.pdf 7.10 Autres bus Industriellement, le Can-bus est trs utilis, et les microcontrleurs haut de gamme le supportent. Pour les petites applications, on peut faire beaucoup avec des registres dcalage. Pour communiquer entre microcontrleur, ce que fait Petra, il faut une programmation trs attentive concernant les dures dexcution.

8 EeProm et bootloader
Seuls quelques PICs en boitier 6 et 8 pattes nont pas de mmoire Eeprom. Cette mmoire de 64 256 octets peut tre crite et lue par le programme. Quelques processeurs 28 et 40 pattes, dont le 16F877, ont une possibilit supplmentaire de lire et modifier la mmoire programme, dite mmoire Flash, ce qui permet de lire ou crire des grandes tables, et charger un programme sans passer par le programmateur, mais via une ligne srie. 8.1 Mmoire EeProm La lecture de la mmoire EeProm se fait en initialisant une variable adresse EeAdr et en lisant linformation dans la variable donns EeData. Ces variables ne sont pas dans la banque 0 avec les ports, et il faut changer souvent de banque.

Lcriture est tout aussi simple, mais un groupe dinstructions bizarres doit tre ajout pour se protger dune criture intempestive si le programme draille et lcriture dure quelques ms. Le bit WR du registre EECON1 en banque 3 est actif pendant que lcriture se fait. Le programme de test T877EeProm.asm contient les macros et routines que lon peut directement utiliser dans ses programmes, sils nutilisent pas linterruption. 8.2 Mmoire Flash La mmoire programme du 16F877 peut tre lue et crite. La lecture est facile comme pour lEeProm. Toutefois, le codage de ladresse et des donnes se fait sur des paires de variables, puisque la mmoire peut avoir 4k (adresse 2 bits) et les instructions ont 14 bits. Lcriture se fait instruction par instruction avec le 16F877, mais pour le 16F877A et le 16F882/884 lcriture se fait par groupes de 4 positions conscutives pour gagner du temps, ce qui pose de joli problmes dalignements. La routine a t dveloppe pour le bootloader du Dev877 et est disposition. 8.3 Boot loader Lintrt de lcriture en mmoire programme est que lon peut avoir dans une zone rserve du processeur qui ne sera jamais modifie, un programme appel boot loader qui charge depuis linterface srie le programme excuter. Ceci vite un programmateur de PIC, sauf naturellement pour mettre le boot loader en mmoire. Avec le Pickit2, on a le programmateur et linterface srie dans la mme unit. SmileNG peut tre configur pour transmettre en srie le .hex la fin de lassemblage, si on sait initialiser le bon COM port. Le Didelbot www.didel.com/bot/ et la carte Dev877 www.didel.com/07dev877/indexF.html utilisent cette facilit, qui est prvue dans le nouveau Wellbot.

9 Tables
Les PICs ont une instruction trs efficace pour grer des tables. Cette instruction ajoute une valeur au compteur dadresse, mais attention, laddition se fait sur 8 bits, donc on reste dans ce que lon appelle une page mmoire 8 bits. Le compteur dadresse PC (qui pointe les instructions) est coup en deux : PCLatH pour les poids forts (5 bits), PCL pour les poids faibles. Pour nos applications, travaillons en page 0, avec PCH=0, et toutes les tables en page 0. Le programme, les interruptions, les routines nont pas de containtes et peuvent se trouver aprs les tables. Les programmes commencent par
.Loc 0 Jump Debut .Loc 4 Jump Inter ; Tables longueur max 252 octets.

9.1 Tables de saut Un joli exemple considre 3 interrupteurs qui selon leur position dfinissent 8 comportements, conditions initiales, etc. Ces interrupteurs sont cbls sur les bits 2,1,0 du port C par exemple.
Loop: Move PortC,W And #2'111,W Add W,PCL ; on saute 0,1,..7 pos plus loin selon W Jump Do0 Jump Do1 Jump Do7 Do0: ce quil faut faire si tous les interrupteurs 0 Jump Loop Do1: Etc.

9.2 Tables de conversion Les tables de conversion utilisent une autre instruction particulire du PIC, linstruction RetMove #Val,W. Comme son nom lindique, cest un RET, retour de routine, qui en mme temps met la valeur dans W. On crit alors une routine aiguillage qui a autant de Return que

ncessaire. Par exemple, si on a besoin de commander un affichage 7 segments, lentre dans la table est une valeur de 0 16F dans W, et la sortie dans W est immdiatement utilise pour allumer les segments.
\in: W chiffre 4 bits \out: W code pour allumer les segments GetSegments : ; -gfedcba for bits 7..0 Add W,PCL RetMove #200111111,W ; 0 RetMove #200000011,W ; 1 ... RetMove #201111000,W ; F

La partie de programme qui affiche les segments est


Move Call Move Chiffre,W GetSegments W,PortC ; Variable qui contient un nombre de 0 9

Si Chiffre contient un nombre suprieur 16F, laffichage dpend des instructions qui suivent. Pour viter ce risque, on commencera la routine GetSegments par
Move And Add Chiffre,W #200001111,W W,PCL

9.3 Astuces Les tables dvolution pour un moteur pas pas se font tout naturellement avec cette technique, avec une astuce supplmentaire si lon met des instructions dans la table :
AvancePas : Move Pos,W ; le compteur par 6 qui dfinit lexcitation du moteur Inc Pos Add W,PCL RetMove #201111111,W RetMove #201111111,W RetMove #201111111,W RetMove #201111111,W RetMove #201111111,W Clr Pos RetMove #201111111,W

On voit quaprs le 6e pas, on recommence, sans avoir eu besoin de comparer si on tait arriv 6, ce qui aurait cot quelques instructions. 9.4 Protection Une table mal place ou mal accde peut crer des plantes difficiles analyser. Premier conseil : saturer le pointeur pour rester dans la table.. Par exemple, si le pointeur dans la table est Ptable, et la longueur MaxPtable, on crit
GetTable: Move #MaxPtable,W Sub W,Ptable Skip,CC Clr Ptable Add Ptable,W ; cest satur Add W,PCL RetMove # ...,W ...

Deuxime conseil : pour tre sr que lon ne dborde pas de la page, mettre un .If qui teste le compteur dadresse. Pour un message deereur si on nest plus en page 0 :
.If APC/256 .NE. 0 On dborde (pas de ; pour quun message derreur aparaisse .Endif

9.5 Calculs Les tables sont un outil puissant pour viter des calculs, les applications vises ayant en gnral besoin de peu de prcision. Si on a une conversion faire sur une valeur qui a une prcision de 3%, on ramne cette valeur entre 0 et 31 et on passe par une table pour avoir la valeur correspondante. Par exemple, 32 vitesses sont bien suffisantes pour un robot, mais on peut tre intress avoir une rponse logarithmique avec des vitesses trs lentes. Une table donne les valeurs PFM, signes si ncessaire.

10 Accs indirect
Un Move par exemple dplace une valeur qui peut tre immdiate (#Val), directe (Reg) ou indirecte, cest dire dans ce 3e cas que loprande contient ladresse.dune variable qui est ladresse. Vous avez gagn 100.- pour un concours On vous donne les 100.adressage immdiat On vous donne lendroit ou aller les chercher adressage direct On vous dit daller tel endroit ou on vous dira o aller adressage indirect (pratique si ce nest pas toujours au mme endroit) Les PICs sont trs primitifs avec un seul registre indirect, appel FSR (File Select Register). Par exemple, si une variable est ladresse Toto = 1643, on peut lire son contenu de deux faons :
Move Toto,W #Toto,W W,FSR {FSR},W ; Adressage direct

ou
Move Move Move ; FSR connat ladresse de notre variable ; Adressage indirect

Lintrt est que si on veut maintenant lire le contenu de ladresse qui suit en mmoire, il suffit daugmenter FSR de 1. On peut ainsi dans une boucle, parcourir une table de variables. 10.1 Effacer une zone mmoire Dans linitialisation de tout programme, il est conseill de mettre toutes les variables zro, mme celles qui ne sont pas utilises. Cela prend peu de temps, et on ne risque pas de dmarrer avec des variables qui nont pas la mme valeur chaque enclenchement. La variable en premire position de la zone des variables est utilise comme dcompteur. Le fichier de rfrence insr au dbut de chaque programme (.Ref 16F877) connat le dbut et la fin de la zone des variables.
\b; On efface toutes les variables - 500 us Move #DebVar+1,W Move W,FSR Move #FinVar-DebVar-1,W Move W,DebVar L$: Clr {FSR} Inc FSR DecSkip,EQ DebVar Jump L$

Sil y a des variables dans une 2e banque, il faut aussi les effacer. 10.2 Besoin de 2 pointeurs ? Si on doit grer un pointeur dans la routine dinterruption et un autre dans le programme principal, il faut sauver en mmoire les valeurs des deux pointeurs et commuter lorsque cest ncessaire : Move FSR,W Move W,SaveFSR1 Move SaveFSR2,W Move W,FSR On donnera naturellement des noms plus explicites SaveFSR1 et SaveFSR2.

11 Squencement et multitche
On doit souvent faire plusieurs choses en mme temps, et chaque chose se fait en plusieurs tapes successives. Par exemple, si on attend un signal infrarouge tout en commandant la vitesse des moteurs, la tche infrarouge est surveille et un compteur suit lvolution. Si on doit surveiller un ascenseur, une tche surveille les demandes et une tche soccupe du dplacement de lascenseur. Il y a beaucoup de faons de procder, selon les applications. 11.1 Exemple 1 Clignotement vitesse variable Prenons un cas simple avec deux tches, une qui clignote une LED, et une qui surveille un poussoir pour modifier la vitesse de clignotement.

Toutes les 20ms puisque les tches sont trs lentes, on soccupe successivement des deux tches, qui partagent la variable VitCligno, qui dfinit le temps entre les impulsions lumineuses. Clignotement : La routine TaskCli a deux sous-tches dfinies par le compteur TkCli. - Allumer la Led pendant 0.1s (IniLedOn=5 cycles compt par la variable CntLed) - Eteindre pendant VitCligno cycles compt par la variable CntLed Poussoir : La routineTaskPous a trois sous-tches dfinies par le compteur TkPou - Attendre que lon pse - Attendre que lon relche en mesurant la dure - Agir sur la variable VitCligno Dtaillons les instructions ncessaires pour ces tches.
Tkcl1: Clr PortC:#bLed ; allum DecSkip,EQ CntLed Ret ; on reste dans la mme tche

; On prpare la tche suivante


Move VitCligno,W Move W,CntLed Inc TkCli Ret Tkcl2: Set PortC:#bLed ; teint DecSkip,EQ CntLed Ret ; on reste dans la mme tche ; On prpare la tche suivante Move #IniLedOn,W Move W,CntLed Clr TkCli Ret

Pour la tche poussoir, on veut distinguer les actions courtes, qui vont augmenter la frquence de clignotement, et les actions longues, qui vont diminuer cette frquence. Ceci peut se faire avec un dcompteur de dure de laction, et le truc de saturer le compteur zro. On initialise le compteur pour quil arrive zro au bout dune seconde (IniCntPous = 50 puisque 50x20ms = 1s)
TkPou1: TestSkip,BS PortC :#bPous Ret ; on attend ; Action sur le poussoir, on prpare la tche Move #IniCntPous,W Move W,CntPous Inc TkPous Ret TkPou2: Dec CntPous Skip,NE Inc CntPous ; Sature 1 TestSkip,BC PortC :#bPous Ret ; on attent le relchement ; On dcide si on augmente ou diminue VitCligno DecSkip,EQ CntPous Jump Augmente Diminue: Dec VitCligno Skip,NE Augmente: Inc VitCligno ; sature 1 Clr TkPous Ret

Le programme complet doit dfinir les constantes et les variables, initialiser les pointeurs de tche zro et appeler dans une boucle synchronise par le timer 20ms les deux tches.
Loop: TestSkip,BS Intcon:#TOIF Jump Loop ; On attend 20ms Clr Intcon:#TOIF Move #IniTmr0,W Move W,TMR0 ; Rinit les 20ms Call DoTaskCli Call DoTaskPous Jump Loop

DoTaskCli: Move Add Jump

TkCli,W W,PCL TkCli1

Jump DoTaskPous: Move Add Jump Jump

TkCli2

TkPou,W W,PCL TkPou1 TkPou2

Suivent les tches dcrites plus haut. Le programme complet est sous T877TaskCli.asm 11.2 Exemple 2 Robot vitant les obstacles Un robot a deux capteurs de distance en tout ou rien ou deux moustaches. On veut programmer un vitement dobstacles o le robot va reculer et tourner pour viter au mieux lobstacle. Il faut donc se souvenir de quelle moustache a touch jusqu ce que la manuvre dvitement soit termine. Le robot est de type voiture avec une variable Vitesse qui dfinit le PFM du moteur et une variable Virage en tout ou rien. Il faut bien se mettre daccord sur le squencement propos, car il pourrait y avoir dautres solutions. 1) Si pas de contact, on va tout droit 2) Si contact droite, on inverse la vitesse pour DureeRecul=50 (50x20=1s) en tournant droite. 3) Idem gauche. Cela fait 3 sous-tches pour le dplacement (tche TkDepl), et une tche pour les capteurs qui ne semble pas ncessaire ; on sen occupe pendant la tche davance normale seulement.
TkDepl0 : ; On avance en surveillant les capteurs dobstacles TestSkip,BC PortC :#bObstDroit Jump ODroit TestSkip,BC PortC :#bObstGauche Jump OGauche Ret Odroit : ; On passe en tche 1 -- on modifie la vitesse en tournant gauche Inc TkDepl Ret OGauche : -- on Inc Inc Ret ; On passe en tche 2 modifie les vitesses en tournant droite TkDepl TkDepl

TkDepl1 : ; On recule pendant 1 s --- on dcompte le temps Ret ; le temps nest pas coul ; on prpare pour reprendre la ligne droite (ou courbe) Clr TkDepl Ret TkDepl2 : ; On recule pendant 1s -- on dcompte le temps Ret ; le temps nest pas coul ; on prpare pour reprendre la ligne droite (ou courbe) Clr TkDepl Ret

A vous de complter les instructions. Elle nont pas t crites pour vous montrer la faon dont on crit le programme : on se proccupe de la structure avant de coder le dtail des actions, et simultanment on complte les liste des constantes et des variable. Il ne doit pas y avoir de nombres dans le programme. Toutes les valeurs doivent tre dclares au dbut pour tre facilement changes. Le programme complet pour une carte BimoPlus se trouve sous xxxx ?? 11.3 Exemple 3 Ascenseur 3 tages Un ascenseur a 3 tages, soir un moteur, trois poussoirs pour appeler ltage (bAppel1 etc) et trois fin de course pour dtecter larrive de lascenseur chaque tage (bStop1 etc).

Les entres sont sur le portC, les 2 sorties de commande de moteur sur le portA. Dfinissons 9 tches Etage0 : ; arrt ltages 0, surveille appel1 et appel2 Appel01 : ; on a pes sur le bouton dappel de ltage 1 et lascenseur monte jusquau fin de course 1 Appel02 : ; on a pes sur le bouton dappel de ltage 1 et lascenseur monte jusquau fin de course 2 Etage1 : ; etc Ecrivons le dbut de ce programme, aprs les initialisations gnrales, y compris les instructions qui amnenent lascenseur ltage zro, sil ny est pas.
Clr TaskAsc ; Lascenseur est ltage zero au dbut Loop : Call DoAsc ; rien dautre faire ? Jump Loop DoAsc : Move Add NoTk0 = 0 Jump Jump Jump NoTk1 = 3 Jump Etc TaskAsc,W W,PCL Etage0 Appel01 Appel02 Etage1

Etage0 : TestSkip,BC PortC :#bAppel1 Jump Ap01 TestSkip,BC PortC :#bAppel2 Jump Ap02 Ret ; On attend Ap01: Move #Monte,W Move W,PortC Inc TaskAsc,W ; continue en Appel01 Ret Ap02: Move #Monte,W Move W,PortA Inc TaskAsc,W Inc TaskAsc,W ; continue en Appel02 Ret Appel01 : ; on attend le fin de course de ltage 1 TestSkip,BS PortC :#bStop1 Ret Move #Stop,W Move W,PortA Move NoTk1,W Move TkAsc,W Ret ; On continue en Etage1 Appel02 : ; on attend le fin de course de ltage 2 TestSkip,BS PortC :#bStop2 Ret Move #Stop,W Move W,PortA Move NoTk2,W Move TkAsc,W Ret ; on continue en Etage2

Etc, cest vraiment facile crire, facile tester et facile modifier. Le programme complet sappelle T877TaskAsc.asm 11.4 Rsum Dcomposer un application en tches qui se droulent suffisamment souvent est plus simple quune gestion par interruption. Les tches peuvent souvent se tester sparment en crivant des programmes simples. La difficult est de trouver une priode dchantillonage assez rapide pour que toutes les tches soient servies dans le temps voulu, et assez longue pour avoir assez dinstructions pour excuter chaque sous-tche.

Les interruptions sont rserves pour des communications rapides, RS232, I2C, et il faut veiller ce quelles soient servies aussi rapidement que possible.

12 Arithmtique
Les PICs ne savent quajouter et soustraire des nombres binaires de 8 bits. Sil y a dpassement de capacit, le bit C (Carry) est mis un. Si le rsultat est nul, le bit Z (Zero) est activ. Une addition peut donner un rsultat nul : 128+128=256=0 (le Carry est activ). La reprsentation du cercle arithmtique aide bien comprendre.

Pour la soustraction, le PIC est diffrent dautres processeur puisquil ajoute le complment plutt que de soustraire. Linstruction Sub est aussi inhabituelle, tant mieux si vous navez pas dhabitudes, CALM dit exactement ce que font les instructions arithmtiques. Le 1e oprande est soustrait du 2e, et le rsultat est mis dans le 3e oprande, sil y en a un 3e. Val est une valeur 8 bits, Reg est une variable ou un registre priphrique Add #Val,W ; #Val + W W ; pas sur 10F 12F Add Reg,W ; Reg + W W Add W,Reg ; W + Reg Reg Sub W,#Val,W ; #Val - W W ; pas sur 10F 12F Sub W,Reg,W ; Reg - W W Sub W,Var ; Var - W Var Evitez de soustraire, additionnez le complment ! Add # -5,W soustrait 5 de W et ne donne pas le mme rsultat que Sub W,#5,W qui soustrait W de 5 (bizarrerie du PIC). Pour un registre aussi, pour soustraire 5 de Reg, cest en gnral prfrable dcrire
Move #-5,W Add W,Reg

12.1 Complment 1 et 2 Le complment 1 inverse tous les bits, cest ce que fait linstruction Not. On utilise cette instruction par exemple si des interrupteurs branchs sur un port sont actifs zro et que lon voudrait convertir les zros en uns. Le complment 2 est le rsultat de lopration zro moins le nombre. Cest aussi le complment 1 plus 1. Larithmtique des nombres ngatifs est dlicate, des explications, des routines et des macros sont donns sous www.didel.com/pic/Arith.pdf 12.2 Comparaison

On a souvent besoin de comparer deux nombres positifs et on utilise la soustraction pour cela.
Move Sub Nb1,W W,Nb2,W

Si C est 1, Nb1 > Nb2 Si Z est 1, Nb1 = Nb2

La soustraction de deux nombres positifs peut donner un rsultat ngatif, reprsent en complment 2. Pour avoir sa valeur absolue, positive, on doit soustraire le rsultat de zro (prendre son complment 2)
Clr Sub Temp ; variable temporaire W,Temp,W ; W 0-W = -W ou W W

12.3 Saturation Souvent, un compteur doit avoir une bute et cela simplmente avec quelques instructions. Une addition peut aussi devoir tre sature ; cest un peu plus dlicat puisque le rsultat dune addition peut tre petit, sil y a dpassement de capacit. Avant daccder dans une table, il peut tre important de saturer la valeur pour viter de lire en dehors des valeurs prvues. Le document www.didel.com/pic/Satu.pdf traite les cas les plus frquents. 12.4 Multiprcision Ne parlons pas de la multiprcision et des nombres ngatifs difficiles matriser. Les PICs ne sont pas fait pour calculer, mais pour manipuler des bits. Toutefois, on doit parfois compare, modifier des nombres, et plus dinformation se trouve sous xxxx. Des routines et macros trs utiles sont dcrites sous www.didel.com/pic/Arith.pdf 12.4 BCD (Dcimal cod binaire) Le code BCD reprsente 2 chiffres dcimaus (0 9) sur les deux moitis dun octet. On peut additionner, soustraire, des nombres BCD, des exemples de routines sont donns sous xxxx ??. Compter et dcompter en BCD est souvent utile, si le rsultat doit tre prsent sur un affichage 7 segments. Convertir de binaire en dcimal est souvent ncessaire si on interagit avec un clavier cran. Voir www.didel.com/picg/doc/DopiBinD.pdf 12.5 Moyennes Calculer la moyenne de nombres conscutifs, par exemple pour filtrer un capteur, nest pas vidente. Le document www.didel.com/pic/Moyennes.pdf montre comment faire. 12.6 Rsum Pour mettre au point des routines arithmtiques, il est recommand de faire des programmes de test qui interagissent avec un PC via une liaison srie. Le PC transmet le code ASCII des chiffres et signes, quil est facile de convertir. Le microcontrleur renvoie les rsultats. Il faut toujours tester soigneusement les oprations particulires (rsultat nul, dpassements de capacit, etc.). Le document xxx ?? donne plusieurs exemples http://www.didel.com/picg/doc/AideDebug.html

13 Macros et .If
Les macros sont une belle invention pour remplacer des dfinitions et squences dinstruction par une seule ligne qui peut avoir des paramtre. Pour les dtails, consulter la page 47 de www.didel.com/picg/picg87x/Picg78.pdf Ce document dtaille aussi les pseudos, .Loc, .End si vous voulez en savoit plus. 13.1 Actions sur des priphriques

Il faut dfinir pour chaque priphrique des macros qui expriment la fonction, et qui codent la ralisation. Par exemple, faire clignoter une Led lenclenchement est pratique, la routine qui fait clignoter trois fois est identique pour tous les processeurs, mais elle nagit pas toujours sur le mme bit du mme port. Devoir mettre jour linstruction qui allume et teint la Led est source derreurs. Il faut dclarer dans le fichier xxDef.asi de definition des priphriques: .Macro LedOn Set PortC:#bLed .Endmacro .Macro LedOff Clr PortB:#bLed .Endmacro Ceci permet par la suite dcrire simplement LedOn LedOff dans les routines que lon passe dune application lautre sans devoir retouche le port et le bit. 13.2 Assemblages conditionnels - .If Les Microdules ont t dvelopps pour faciliter le dveloppement dapplication pour des petits processeurs, mis au point sur un processeur qui a des ports supplmentaires pour afficher des compteurs, variables dtat, impulsions observer loscilloscope. Le choix du processeur se fait en dclarant au dbut du programme principal T877 = 1 T630 = 0 Cest de prfrence dans un fichier spar xxSet.asi que lon dfinit ce qui caractrise le processeur .If T877 .If T630 \b;16F877 \b;16F676/630 .Proc 16F877 .Proc 16F630 .Ref 16F877 .Ref 16F630 \b;Configuration \b;Configuration .Loc 16'2007 .Loc 16'2007 .16 16'3F39 .16 16'3F94 .Endif .Endif Dans le fichier xx.Init.asi on mets les initialisations spcifiques chaque processeur en sparant par des .If ce qui nest pas commun. On a ensuite des fichiers spcifiques pour soccuper des capteurs, des moteurs, etc. qui nont pas de raison de dpendre du processeur. Le programme principal, xx03.asm (si on numrote les versions de cette faon) contient essentiellement des commentaire et des insertions de fichier (.Ins xxyy.asi). Comme exemple on peut ouvrir exemple avec BimoPlus

14 Structure et mise en page


Matriser la programmation prend du temps, et le problme traditionnel est que lon a de la peine reprendre danciens programmes pour les amliorer, car leur documentation de structure est incomplte. 14.1 Structuration La premire tape pour une bonne technique de programmation est de bien structurer et commenter les programmes. Un commentaire pour chaque ligne est absurde, une ligne vide est souvent un bon commentaire. Une dcomposition en fichiers ayant chacun une fonction claire permet de rcuprer plus facilement des modules de programmes. 14.2 Commentaires Les commentaires dans les programmes sont essentiels pour pouvoir se relire et se remettre dans le bain aprs quelques jours ou mois, et naturellement pour permettre un ami de sy retrouver. Bien commenter nest pas mettre un commentaire chaque ligne, mais un commentaire expliquant le rle dun groupe dinstructions. Une ligne vide est un bon commentaire puisquelle peut montrer comment regrouper la lecture des instructions.

14.3 Noms des variables Notons que c'est assez pratique de mettre un b minuscule comme premire lettre lorsqu'il s'agit d'un bit et non pas d'un mot de 8 bits. Il ne faut pas avoir peur de passer du temps choisir et taper des noms explicites; ce temps reste ngligeable vis--vis du temps pass trouver des erreurs de programmation. 14.4 Spcifications des routines Les routines doivent pouvoir tre utilises sans que cela soit ncessaire de lire leurs instructions. Le commentaire initial doit dire la fonction ralise, quels sont les registres et variables qui apportent linformation traiter, quels sont les registres et variables qui rendent de linformation, quels sont les registre utiliss et modifis. Par exemple une routine qui compte en dcimal et pas en binaire se documente et scrit :
\rout ;IncBCD incrmente en dcimal cod binaire ; On compte en binaire, mais si le comptage passe de 9 A sur les 4 bits de poids faible, ; on corrige en mettant zro et en incrmentant les 4 bits de poids fort. ; Si la valeur sur les poids forts passe de 9 A, on met zro et active le Carry \In; A registre avec une valeur BCD de 1 99 : 00 01 .. 09 10 99 \out; A registre augment de 1. C=1 si passage de 99 00 \mod; A, B, F IncBCD :

14.5 Mise en vidense boa Les ordres boa (car ils commencent par une Barre Oblique Arrire) et linsertion de fichier image (.bmp), avec limpression multi-colonne de SmileNG est un avantage considrable pour les grands programmes. On peut se limiter utiliser les squences suivantes :

On remarque quil est possible dinsrer des fichiers images en .bmp (prennent malheureusement beaucoup de place. Ceci aide considrablement la lisibilit des programmes, puisque lon peut insrer un schma, un organigramme, le timing dun oscilloscope, une photo dun testeur. SmileNG permet de dfinir dans son menu Tools-Editor options la couleur et la taille pour les dfinitions, instructions, commentaires. La touche F8 commute entre le mode qui interprte les squence boa et le mode qui les affiche en clair.

15 Dpannages et complments
15.1 Dverminage La mise au point des programmes nest pas toujours facile car on ne voit pas ce que fait le processeur. Des simulateurs existent, comme avec le Dauphin, mais le problme est en gnral

la 1000e instructions, et si on peut mettre un point darrt pour observer ltat, on ne peut pas bloquer les signaux entrants, une tlcommande infrarouge par exemple. Avec les processeurs simples, il ny a pas dautre solution que de laisser tourner le contrleur, mais on lui demande de crer des impulsions, afficher des valeurs sur des ports non utiliss par lapplication. Cest lintrt du 16F877 pour mettre au point les programmes pour des processeurs plus simples. Diffrentes techniques sont expliques dans www.didel.com/picg/doc/DopicBug.pdf 15.2 Sottisier Oui, vous ferez des btises de programmation, et des grosses ! Certaines font perdre beaucoup de temps. Un document liste les plus frquentes www.didel.com/pic/Sottisier.pdf 15.3 Compatibilit 12 bits La famille PIC a des processeurs en boitier 6, 8 et 14 broches qui ont des instructions 12 bits. Trois instructions sont supprimes, et les adresses sont limites. Avec quelques macros et .If, on dveloppe sur 877 des applications pour 10F 12F et transfre le programme test sur la petite puce 10F 12F au dernier moment. Voir http://www.didel.com/picg/doc/DopiComp.pdf 15.4 Optimisation de code Les PICs permettent parfois des solutions trs lgantes auxquelles on ne pense pas toujours La condition ET sur 2 bits est facilement programme dans un PIC. Par exemple, si on veut savoir que les bits 3 et 6 de la variable Cz sont 1, on crit
TestSkip,BC Cz:#3 TestSkip,BS Cz:#6 Jump La condition ET n'est pas ralise On continue ici si la condition ET est ralise

Ceci s'applique bien un compteur par 10 (ou 6, 12, etc), puisqu'il faut mettre le compteur zro l'tat limite est atteint. Si le compteur par 10 est programm sur le portB (dont seuls les 4 bits de poids faibles sont utiliss), on peut crire la routine qui incrmente le portB de la faon suivante:
IncBCD: Inc PortB TestSkip,BC PortB:#1 TestSkip,BS PortB:#3 Ret Clr PortB Ret

Le fichier Arith autres ex 15.5 Retards courts On a vu comment faire des retards longs. Lorsque lon doit gnrer des impulsions calibres, par exemple du 38 kHz pour de linfrarioge, on doit ajuster des retards la microseconde prs, en utilisant un nombre minime dinstructions. Le retard le plus court est celui de linstruction Nop, 1 us 4 MHz. Linstruction Jump APC+1 prend 2 us. Si la routine Rien : Ret existe dans un coin, linstruction Call Rien dure 4 us. Des boucles dattente sont ensuite utilises. 15.6 Watchdog et bits de configuration Le programme peut drailler suite un parasite, ou une condition exceptionelle non prvue Lide pour se protger est un compteur que le programme remets de temps en temps zro avant quil arrive la fin de son comptage et force le redmarrage du programme. Cette option ne doit pas tre active/dsactive par une instruction. Un bit dans le mot de configurations autorise ce fonctionnement. Le fichier www.didel.com/pic/Wdog.pdf explique en dtails et documente quelques bits du mot de configuration.

16 Programmes de test
La documentation dun microcontrleur pend des centaines de pages, et les diffrences dun microcontrleur lautre ne sont jamais documentes. Si lon veut programmer du PWM, des transferts synchrones, le mieux est de faire un programme de test qui permet de vrifier le bon fonctionnement avant dintgrer dans lapplication. Un oscilloscope est souvent ncessaire pour cette application.

Un certain nombre de programmes de test sont documents pour 6 Pics diffrents sous www.didel.com/pic/PicTests.pdf

17 Routines et programmes exemple


Routines non adaptes, Testes en 1998-2000 http://www.didel.com/picg/piclib/DopicSources.html

Ides de programme
Horloges Compteur de rflexe D lectronique affich sur lcran PacMan MasterMind Puissance 4 Nim (jeu des allumettes) Jeu de la vie

PIC 16F877 - CALM instructions


Code 14 bits 110000 kkkkkkkk 000000 1fffffff 001000 0fffffff 001000 1fffffff 000000 01100010 000000 01100101 000000 01100110 000000 01100111 111110 kkkkkkkk 000111 0fffffff 000111 1fffffff 111100 kkkkkkkk 000010 0fffffff 000010 1fffffff 111001 kkkkkkkk 000101 0fffffff 000101 1fffffff 111000 kkkkkkkk 000100 0fffffff 000100 1fffffff 111010 kkkkkkkk 000110 0fffffff 000110 1fffffff 001110 0fffffff 001110 1fffffff 000001 1fffffff 000001 00000000 000000 01100100 000000 01100011 001001 1fffffff 001001 0fffffff 001010 1fffffff 001010 0fffffff 000011 1fffffff 000011 0fffffff 001101 1fffffff 001101 0fffffff 001100 1fffffff 001100 0fffffff 0100bb bfffffff 0101bb bfffffff 001111 1fffffff 001111 0fffffff 001011 1fffffff 001011 0fffffff 0110bb bfffffff 0111bb bfffffff 1010kk kkkkkkkk 1000kk kkkkkkkk 110100 kkkkkkkk 000000 00001000 000000 00001001 000000 00000000 Microchip movlw val movwf reg movf reg,0 movf reg,1 option tris porta tris portb tris portc addlw val addwf reg,0 addwf reg,1 sublw val subwf reg,0 subwf reg,1 andlw val andwf reg,0 andwf reg,1 iorlw val iorwf reg,0 iorwf reg,1 xorlw val xorwf reg,0 xorwf reg,1 swapf reg,0 swapf reg,1 clrf reg clrw clrwdt sleep comf reg,1 comf reg,0 incf reg,1 incf reg,0 decf reg,1 decf reg,0 rlf reg,1 rlf reg,0 rrf reg,1 rrf reg,0 bcf reg,b bsf reg,b incfsz reg,1 incfsz reg,0 decfsz reg,1 decfsz reg,0 btfsc reg,b btfss reg,d goto addr call addr retlw val return retfie nop CALM Move Move Move Test Move Move Move Move Add Add Add Sub Sub Sub And And And Or Or Or Xor Xor Xor Swap Swap Clr Clr ClrWDT Sleep Not Not Inc Inc Dec Dec RLC RLC RRC RRC Clr Set IncSkip,EQ IncSkip,EQ DecSkip,EQ DecSkip,EQ TestSkip,BC TestSkip,BS Jump Call RetMove Ret RetI Nop #Val,W W,Reg Reg,W Reg W,Option W,TrisA 1 1 W,TrisB 1 W,TrisC #Val,W Reg,W W,Reg W,#Val,W W,Reg,W W,Reg #Val,W Reg,W W,Reg #Val,W Reg,W W,Reg #Val,W Reg,W W,Reg Reg,W Reg Reg W

www.didel.com/pic/CalmInstr877.pdf
Flags [none] [none] [Z] [Z] [none] [none] [none] [none] [C,D,Z] [C,D,Z] [C,D,Z] [C2,D,Z] [C2,D,Z] [C2,D,Z] [Z] [Z] [Z] [Z] [Z] [Z] [Z] [Z] [Z] [none] [none] [Z=1] [none] [none] [none] [Z] [Z] [Z] [Z] [Z] [Z] [C] [C] [C] [C] [none] [none] [none] [none] [none] [none] [none] [none] [none] [none] [none] [none] [int] [none] Operation #Val W W Reg Reg W Reg Reg

#Val+W Reg+W #Val+(-W) Reg+(-W) Reg+(-W)

W W W W Reg

Reg Reg swapped Reg Reg swapped Reg 0 Reg 0 W

Reg Reg,W Reg Reg,W Reg Reg,W Reg Reg,W Reg Reg,W Reg:#b Reg:#b Reg Reg,W Reg Reg,W Reg:#b Reg:#b Addr Addr #Val,W

Reg Reg Reg+1 Reg Reg-1 Reg Reg Reg Reg Reg

.not.Reg Reg .not.Reg W Reg Reg Reg+1 W Reg Reg Reg-1 W .rlc.Reg Reg .rlc.Reg W .rrc.Reg Reg .rrc.Reg W

Reg+1 Reg Reg Reg Reg+1 W Reg-1 Reg Reg Reg Reg-1 W

bcf status,0 CLRC Clr F:#0 bsf status,0 SETC Set F:#0 btfss status,0 Skip,CS TestSkip,BS Status:#C btfsc status,0 Skip,CC TestSkip,BC Status:#C btfss status,2 Skip,EQ TestSkip,BS Status:#Z btfsc status,2 Skip,NE TestSkip,BC Status:#Z F same name as Status Note 1: Move W,TrisD, Move W,TrisE does not exist. Use Move W,PortD, Move W.PortE in Bank1 Note 2: Processor add the 2-s complement; Carry value is inverted compared to most other P All instructions execute in 4 clock cycles (1 S at 4 MHz) except the Skip, Jump, Call and Ret that takes the double Compare for equality: Xor W,Reg or Xor Reg,W Compare for Inequality: Sub instruction, but be careful Except I/O, 16F87x, and other 14-bit instruction PICs have the same instruction set. jdn090823

You might also like