15
 Introduction au 68HC11(F1) Jean-Michel FRIEDT , Mai 1999 (March 6, 2000) 1 Introduction Le choix du 68HC11F1 a ´ et´ e fait selon le crit` ere d’avoir une microcontroleur ne n´ ecessitant pas de programmeur, pouvant ˆ etre pro- gramm´ e au vol ` a partir d’un port s´ erie  1 et comportant des convertisseurs ana logique-num ´ erique (A/D) t out en per mettant l ’inter fac ¸age avec une RAM externe. L ’assembleur utilis ´ e ici est disponib le gratuitement par ano nymous ftp ` a ftp.cmf.nrl.navy.mil dans /pub/kenh/ (il s’agit de  asxxxx-v1.51.tar.gz  en Novembre 1999, bien que la version puisse changer ult´ erieurement). Cet assembleur a l’avantage d’ˆ etre facilement adaptable ` a n’importe quel microcontroleur CISC (et inclut notamment des versions pour le 6809 et le Z80). La m´ ethode de compilation utilis´ ee, que ce soit sous DOS ou Linux, est la suivante : ´ ecrire le programme en assembleur dans un ´ editeur de texte (le chier sera ici nomm´ e  prg.asm). Par rap port aux ex emple donn´ es dans le texte, il ne faut taper que la partie droite (par exemple pour une ligne du type 0000 8E 01 FF lds #0h01FF ; setup : st ack il ne faut entrer que  lds #0h01FF suivi ´ eventuellement des commentaires (le texte apr` es le ’;’) . Le ebut de la ligne est l’adresse o` u se situe la ligne de code (ici d´ ebut du programme donc adresse  0000), puis les opcode correspondant ` a cette ligne apr` es assemblage (ici  8E 01 FF). C’est la suite de ces opcodes que nous enverrons via la liaison s´ erie au 68HC11. l’assembler par  as6811 -o prg.asm sous DOS ou  as6811 -o prg.rel prg.asm  sous Linux pour g´ en´ erer le chier prg.rel qui contient le code en hexad´ ecimal et d’autres informations. retirer les lign es ne comme nc ¸ant p as par un ’ T’ (grep ˆT) et les 8 premiers caract` eres des lignes restantes (qui sont le ’ T’ suivi de l’adresse de d´ ebut de ligne :  cut -c9-60) et mettre le r´ esultat dans  prg.out :  grep T %1.rel | cut -c9-60 > %1.out sous DOS ou  grep T $1.rel | cut -c9-60 > $1. ou t  sous Linux. enn, progra mmer le 68HC11F1en ex´ ecu tan t le progra mme DOS hc11.exe prg.out , r´ esu lta t de la compil ati on de hc11.pas fourni en annexe A de ce document.  ` A noter que le num´ ero du port s´ erie est en hard dans le programme sous le nom de variable PortId. Les programmes pr´ esent´ es dans ce document ont ´ et´ e g ´ en´ er´ es par as6811 -l prg.asm sous Linux (apr` es ´ edition des lignes inutiles). La mˆ eme fonction est disponible sous DOS par as6811 -l prg.asm qui g ´ en` ere automatiquement le chier  .lst. 2 G´ en ´ eralit ´ es Les instructions de base. 2 registres 16 bits utilis´ es pour les acc` es m´ emoires : X, Y 2 registres g´ en´ eraux 8 bits : A, B qui peuvent se concat´ ener en D=AB. Programme + data RAM Pile Registres ROM EEPROM vecteurs d’int. 0000 lds 03FF 1000 105F BF00 BFFF FE00 FFFF Les fonctio ns logiques habitu elles : AND( A/B), LSL(A/ B) (shift left), LSR(A/B) (shift right), ORA(A/B) Les op´ erations sur la pile : PSH(A/B/X/Y), PUL(A/B/X/Y) Les fonctions sur des bits : BCLR (bit clear), BSET (bit set) Les fonctions de saut relatif (court) : BRA (toujours), BNE (  0), BSR (branch to subrou- tine), RTS Les fonctions de saut long : JMP , JSR, Les foncti ons de charg emen t de vale ur : LDA(A/B), LDD, LDS, LD(X/Y), ST(X/ Y), STA(A/B), STD Les sauts avec tes t : BRCLR (branche si apr` es masquage avec les bits ` a 0, le r´ esultat est nul), BRSET (r´ ealise un ET logique avec le masque fourni, et branche si le esultat est 0) Interruptions : CLI (autorise les interruptions), RTI, SEI (arrˆ ete les interruptions) Comparaison : CP(X/Y), CMP(A/B) Arithm´ etique : DEC(A/B), DE(X/Y), INC(A/B), IN(X/Y), SUB(A/B), SUBD, ADD(A/B), ADDD. 1 La restriction sur le port RS232 vient de l’utilisation d’un palmtop HP200LX comme programmeur. Cet ordinateur ne poss` ede qu’un port s´ erie comme extension (absence de port parall` ele). 1

68hc11 ffff1

Embed Size (px)

Citation preview

Introduction au 68HC11(F1)Jean-Michel FRIEDT, Mai 1999 (March 6, 2000)

1 IntroductionLe choix du 68HC11F1 a et fait selon le crit` re davoir une microcontroleur ne n cessitant pas de programmeur, pouvant etre proe e e gramm au vol a partir dun port s rie 1 et comportant des convertisseurs analogique-num erique (A/D) tout en permettant linterfacage e ` e avec une RAM externe. Lassembleur utilis ici est disponible gratuitement par anonymous ftp a ftp.cmf.nrl.navy.mil dans /pub/kenh/ (il sagit e ` de asxxxx-v1.51.tar.gz en Novembre 1999, bien que la version puisse changer ult rieurement). Cet assembleur a lavantage e d tre facilement adaptable a nimporte quel microcontroleur CISC (et inclut notamment des versions pour le 6809 et le Z80). e ` La m thode de compilation utilis e, que ce soit sous DOS ou Linux, est la suivante : e e ecrire le programme en assembleur dans un editeur de texte (le chier sera ici nomm prg.asm). Par rapport aux exemple e donn s dans le texte, il ne faut taper que la partie droite (par exemple pour une ligne du type e 0000 8E 01 FF lds #0h01FF ; setup : stack il ne faut entrer que lds #0h01FF suivi eventuellement des commentaires (le texte apr` s le ;). Le d but de la ligne est e e ladresse o` se situe la ligne de code (ici d but du programme donc adresse 0000), puis les opcode correspondant a cette ligne u e ` apr` s assemblage (ici 8E 01 FF). Cest la suite de ces opcodes que nous enverrons via la liaison s rie au 68HC11. e e

lassembler par as6811 -o prg.asm sous DOS ou as6811 -o prg.rel prg.asm sous Linux pour g n rer le chier e e prg.rel qui contient le code en hexad cimal et dautres informations. e retirer les lignes ne commencant pas par un T (grep T) et les 8 premiers caract` res des lignes restantes (qui sont le T suivi e de ladresse de d but de ligne : cut -c9-60) et mettre le r sultat dans prg.out : grep T %1.rel | cut -c9-60 > e e %1.out sous DOS ou grep T $1.rel | cut -c9-60 > $1.out sous Linux. enn, programmer le 68HC11F1 en ex cutant le programme DOS hc11.exe prg.out, r sultat de la compilation de hc11.pas e e ` fourni en annexe A de ce document. A noter que le num ro du port s rie est en hard dans le programme sous le nom de variable e e PortId.

Les programmes pr sent s dans ce document ont et g n r s par as6811 -l prg.asm sous Linux (apr` s edition des lignes inutiles). e e e e ee e La m me fonction est disponible sous DOS par as6811 -l prg.asm qui g n` re automatiquement le chier .lst. e e e

2 G n ralit s e e eLes instructions de base. 2 registres 16 bits utilis s pour les acc` s m moires : X, Y e e e 2 registres g n raux 8 bits : A, B qui peuvent se concat ner en D=AB. e e e0000

Programme RAM + data lds Pile

Les fonctions logiques habituelles : AND(A/B), LSL(A/B) (shift left), LSR(A/B) (shift right), ORA(A/B) Les op rations sur la pile : PSH(A/B/X/Y), PUL(A/B/X/Y) e Les fonctions sur des bits : BCLR (bit clear), BSET (bit set)

03FF 1000 105F

Les fonctions de saut relatif (court) : BRA (toujours), BNE ( tine), RTS Les fonctions de saut long : JMP, JSR,

BF00

Les fonctions de chargement de valeur : LDA(A/B), LDD, LDS, LD(X/Y), ST(X/Y), STA(A/B), STD Les sauts avec test : BRCLR (branche si apr` s masquage avec les bits a 0, le r sultat est nul), e ` e BRSET (r alise un ET logique avec le masque fourni, et branche si le r sultat est 0) e e Interruptions : CLI (autorise les interruptions), RTI, SEI (arr te les interruptions) e Comparaison : CP(X/Y), CMP(A/B) Arithm tique : DEC(A/B), DE(X/Y), INC(A/B), IN(X/Y), SUB(A/B), SUBD, ADD(A/B), e ADDD.

ROM

BFFF

FE00

EEPROM vecteurs dint.

FFFF

1 La restriction sur le port RS232 vient de lutilisation dun palmtop HP200LX comme programmeur. Cet ordinateur ne poss` de quun port s rie comme extension e e (absence de port parall` le). e

1

Registres

0), BSR (branch to subrou-

Organisation de la m moire : e 1024 premiers octets (0000-03FF) : RAM. Lex cution commence a ladresse 0000 par un opcode fetch. Dans cette m moire, e ` e nous trouvons : la pile (stack), positionn e par lutilisateur au moyen de linstruction lds, les pseudo-vecteurs dinterruptions (si les e interruptions mat rielles sont utilis es) de 00C4 a 00FF par paquets de 3 octets (JMP @). e e ` Les registres de congurations de 1000 a 105F (96 registres). ` La ROM contenant le code a ex cuter au boot, de BF00 a BFFF ` e ` LEEPROM de FE00 a FFC0 (256 octets) ` Il est a noter que lorganisation de la m moire peut etre optimis e en fonction des besoins par la possibilit de d placer les registres ` e e e e de conguration, la RAM et lEEPROM a nimporte quel emplacement de la forme x000 (x=0..F). Dans tous les cas nous d marrons en ` e bootstrap mode, mais il est possible ensuite de passer en mode etendu et ainsi acc der a une m moire ext rieure. e ` e e

3 Mise en RAM locale dun programme et ex cution eLobjectif dans un premier temps est de tester le montage de base comprenant uniquement le microcontroleur 68HC11 et la logique de communication par port RS232 2 ainsi que les logiciel associ s (programme de communication du c t du PC pour envoyer le e oe programme a ex cuter par le microcontroleur, et programme a ex cuter lui m me). ` e ` e e Le montage propos est le suivant : e

Le circuit est compos s de 3 el ments principaux : le 68HC11F1, le MAX232, le 4066. Quelques composants discrets suppl mentaires e e e d nissent les niveaux de quelques broches du HC11. e Le MAX232 a pour r le de convertir les signaux TTL provenant des deux broches de communication s rie (TxD et RxD) a des o e ` niveaux 12 V requis par le port RS232 du PC. Le 4066 a pour r le de passer du mode chargement du programme du port s rie au mode ex cution du programme stock en o e e e EEPROM. En effet, le HC11 emet au boot (cf Annexe B, p.25) le caract` re 0h00 sur la broche TxD, puis se met en ecoute de ce e qui se passe sur la broche RxD. Si le caract` re 0h00 est recu, lex cution passe tout de suite au d but de lEEPROM. Si le caract` re e e e e nest pas 0h00 mais pas non plus 0hFF, alors le HC11 tente de changer de baud rate (fr quence de r ception des donn es). Enn, la e e e r ception dun caract` re 0hFF signie quil faut recevoir les octets et les placer en RAM (adresse commencant en 0h0000), jusqu` la e e a n de la communication. Ainsi, nous constatons que court-circuiter RxD et TxD au boot permet de passer tout de suite a lEEPROM. ` Cependant, court-circuiter d nitivement RxD et TxD fait perdre la possibilit dutiliser le port s rie ult rieurement. Le r le des switchs e e e e o analogiques du 4066 est de commander le court circuit pendant seulement les 10 premi` res ms apr` s le RESET en commandant les e e interrupteurs par un circuit RC (sous le 4066 : la capacit de 330 nF et la r sistance de 100 k. La r sistance de 10 k au-dessus du e e e 4066 sert de r sistance de pull-up). Ce court circuit est de plus permis par un strap : si ce strap est ouvert, il ny a pas court circuit et le e programme est charg par le port s rie. Si ce strap est ferm , il y a court circuit et donc saut en d but dEEPROM. e e e e Enn, pour le 68HC11, seulement quelques composants discrets externes sont n cessaires : le quartz et ses deux capacit s de e e quelques pF pour le faire osciller (avec un r sistance optionnelle de 10 M), des r sistances de pull up (en bas du HC11) sur les ls e e reli s a TxD, RxD et RESET. Il sera de plus n cessaire, en cas dutilisation des interruptions, dajouter deux r sistances de pull up entre e ` e e les broches IRQ et Vdd et XIRQ et Vdd (sinon le HC11 est continuellement interrompu et le programme se bloque apr` s ex cution de e e linstruction cli). Les straps disponibles sont donc : sous le HC11 (horizontal) pour le RESET (il sagit en fait plut t de court-circuiter ces deux o broches avec un objet conducteur pour effectuer le RESET), le strap (horizontal) a gauche du 4066 qui d termine sil faut charger le ` e programme sur le port s rie (ouvert) ou ex cut celui stock en EEPROM (ferm ), et enn les deux straps (verticaux) en haut du HC11 e e e e e et qui doivent normalement etre ferm s pour lancer le HC11 en bootstrap mode. e2 La m moire utilis e pour stocker le programme est incluse dans le microcontroleur (contrairement a plus loin o` nous nous efforcerons dinterfacer une RAM externe e e ` u avec le 68HC11).

2

Nous prendrons soin, lors de la r alisation, a placer deux supports de jumpers de facon verticale en haut du circuit (s lection du e ` e mode de fonctionnement : les deux jumpers doivent etre mis en place pour booter en bootstrap mode) ainsi quun support de jumper en bas du circuit pour le Reset (r alis en court-circuitant temporairement ce support de jumper avec un objet conducteur electriquement). e e 0000 0003 0006 0008 8E CE 86 A7 00 FF 10 00 FF 01 lds #0h00FF ldx #0h1000 ldaa #0hFF staa 0h01,x 000A 000C 000E 0012 86 A7 18 18 00 00 CE FF FF 09 ldaa #0h00 boucle: staa 0h00,x ldy #0hFFFF wait: dey 0014 26 FC 0016 4C 0017 20 F3 bne wait inca bra boucle

Ce petit programme de test fait d ler sur le port A (horizontal, en bas du circuit) la repr sentation binaire des nombres de 0 a 255. e e ` Le r sultat est visualisable en connectant un afcheur 7 segments ou une barrette de LEDs sur le port A. e

4 Lecture des valeurs du convertisseur analogique-num rique eIl faut : 1. mettre en route les convertisseurs A/D en ecrivant dans le registre 0x1039. 3 . 2. pour chaque nouvelle conversion, ecrire le num ro du convertisseur (entre 0 et 7) qui doit effectuer la conversion dans le registre e 0x1030 (dans lexemple ci-dessous, nous utilisons le convertisseur num ro 3) e 3. attendre le signal de n de conversion (par polling du registre 0x1030). 4. lire la valeur obtenue dans le registre 0x1034.0000 0003 0005 0008 000A 000D 8E 86 B7 86 B7 00 FF FF 10 01 90 10 39 lds #0h00ff ldaa #0hff staa 0h1001 ldaa #0h90 staa 0h1039 start: 000D 000F 0012 0014 0017 86 B7 8D B7 20 23 10 30 05 10 00 F4 ldaa #0h23 staa 0h1030 bsr ad_read staa 0h1000 bra start 0019 001C 001E 0021 B6 10 30 2A FB B6 10 34 39 ad_read:ldaa 0h1030 bpl ad_read ldaa 0h1034 rts

Cet exemple lit la valeur analogique sur une des voies du port E (au dessus du 68HC11) - le canal 3 - et renvoie la valeur sur le port A (auquel on aura reli un afcheur 7 segments par exemple). Une variation de la tension appliqu e sur la broche du port E (entre 0 et 5 e e V) doit se traduire par un variation de la valeur afch e. e

5 La communication s rie eIl faut : 1. mettre le port D en mode communication 2. d terminer la vitesse et le protocole de transmission e 3. une fois ces initialisation effectu es, attendre la transmission dun caract` re et le lire lorsquil a et recu (par polling). e e e Dans les programmes qui suivent, le 68HC11 doit etre reli par un c ble direct (non-crois ) a un PC sur lequel tourne un logiciel e a e ` d mulation de terminal (type Terminal sous Windows 3.11 ou Procom sous DOS). Dans le premier exemple, le 68HC11 afche sur le e port A (auquel on aura reli un afcheur 7 segments par exemple) la valeur ASCII du caract` re envoy par le PC (par appui dune touche e e e du clavier du PC par exemple). Dans le second exemple, le 68HC11 envoie en continu les caract` res ASCII afchable : le terminal e doit continuellement afcher les signes de ponctuation, les chiffres et lalphabet en minuscules et majuscules. Enn, le dernier exemple combine ces deux applications par attendre lenvoi dun caract` re du PC et le lui renvoyer. e Exemple de lecture des donn es venant sur le port s rie du 68HC11 : e e3 Nous utiliserons indiff remment la notation 0xyyyy (notation C), 0hyyyy (notation assembleur non-Motorola 68HC11) ou $yyyy (notation Pascal) pour noter le nombre e hexad cimal yyyy e

3

0000 0003 0006 0008 000A

8E CE 86 A7 1C

00 FF 10 00 FF 01 28 20

lds #0h00FF ldx #0h1000 ldaa #0hFF staa 0h01,x bset 0h28,x,#0h20

000D 000F 0012 0014 0016

6F CC A7 E7 1F

2C 33 0C 2B 2D 2E 20 FC

clr 0h2c,x ldd #0h330C staa 0h2B,x stab 0h2D,x rc: brclr 0h2E,x,#0h20,rc

001A E6 2F 001C E7 00 001E 20 F6

ldab 0h2F,x stab 0h00,x bra rc

Exemple d mission de donn es sur le port s rie du 68HC11 : e e e0000 8E 00 FF 0003 CE 10 00 0006 86 FF 0008 A7 01 000A 1C 28 20 ; port D OR mode lds #0h00FF ; stack ldx #0h1000 ; config registers ldaa #0hFF ; port A for output staa 0h01,x ; | bset 0h28,x,#0h20 000D 000F 0012 0014 0016 0018 6F CC A7 E7 86 1F 2C 33 0C 2B 2D 20 2E 80 FC clr 0h2C,x ; set 2400 N81 ldd #0h330C ; | staa 0h2B,x ; | stab 0h2D,x ; | ldaa #0h20 ; init value at boucle: brclr 0h2E,x,#0h80,boucle 001C 001E 001F 0021 0023 0025 A7 4C 81 26 86 20 2F 7B F5 20 F1 staa 0h2F,x ; send char inca ; next char cmpa #0h7B ; > z ? bne boucle ldaa #0h20 ; restart at bra boucle

Combinaison des deux programmes pr c dents pour lire une valeur sur le port s rie et la renvoyer au PC : e e e0000 0003 0006 0008 000A 8E CE 86 A7 1C 00 FF 10 00 FF 01 28 20 lds #0h00FF ldx #0h1000 ldaa #0hFF staa 0h01,x bset 0h28,x,#0h20 000D 000F 0012 0014 0016 6F CC A7 E7 1F 2C 33 0C 2B 2D 2E 20 FC clr 0h2C,x ldd #0h330C staa 0h2B,x stab 0h2D,x xm: brclr 0h2E,x,#0h20,xm 001A 001C 001E 0022 0024 E6 E7 1F E7 20 2F 00 2E 80 FC 2F F0 ldab 0h2F,x stab 0h00,x rc: brclr 0h2E,x,#0h80,rc stab 0h2F,x bra xm

6 Mise en EEPROM locale et ex cution dun programme e6.1 Aspect logicielLEEPROM commence en 0xFE00. Il nous faut donc, en bootloader mode, charger un programme en RAM dont la fonction est dattendre le programme a stocker en EEPROM et ex cuter la proc dure de stockage. Nous avons choisi de r aliser la conversion ` e e e hexad cimal-ASCII vers une valeur num rique au niveau du PC (contrairement a lAN1010 de Motorola qui r alise cette fonction au e e ` e niveau du microcontroleur) et de nenvoyer que les octets correspondant au programme (pas de checksum, pas dadresse de d but ...). e0000 0003 0006 000A 000C 000E 0011 0013 0016 0018 001A 001C 001E 0020 0022 0022 0026 0028 002A 002C 002E 8E CE 18 86 A7 1C 6F CC A7 E7 86 A7 86 A7 1F E6 E7 86 8D 86 00 10 CE 00 35 28 2C 33 2B 2D FF 01 22 00 FF 00 FE 00 lds #0h00FF ; stack ldx #0h1000 ; config registers offset ldy #0hFE00 ; start of EEPROM (cf 4.12 tech man) ldaa #0h00 ; bprot - block protection disabled staa 0h35,x ; | bset 0h28,x,#0h20 ; port D wired OR mode : set port D clr 0h2C,x ; set 2400 N81 ldd #0h330C ; | staa 0h2B,x ; | stab 0h2D,x ; | ldaa #0hFF ; port A as output staa 0h01,x ; | ldaa #0h22 ; show 22 on display staa 0h00,x ; | boucle: brclr 0h2E,x,#0h20,boucle ; wait for datum ldab 0h2F,x ; store it in B stab 0h00,x ; echo on port A ldaa #0h16 ; reset 1 byte bsr program ; write to location in EEPROM ldaa #0h02 ; store 1 byte 0030 0032 0034 0038 003A 003C 003E 0040 0040 0042 0045 0047 0048 004B 004C 004E 004F 0051 0053 8D 18 18 26 86 A7 20 0E 08 8C FF BF E8 08 00 FE bsr program ; write to location in EEPROM iny ; goto next location in EEPROM cpy #0hFFBF ; until we get to 0hFFBF bne boucle ; get next datum if not finished ldaa #0h08 ; show 8 on display staa 0h00,x fin: bra fin program: ; cf procedure p.4.16 of tech manual staa 0h3B,x stab 0,y ; erase/program byte inc 0h3B,x pshx ldx #0h1A0A ; 2x0h0D05 (16 MHz Q) => 2xdelay_AN1010 wait: dex bne wait pulx ; put X=0h1000 back dec 0h3B,x clr 0h3B,x rts

20 0C

2E 20 FC 2F 00 16 12 02

A7 18 6C 3C CE 09 26 38 6A 6F 39

3B E7 00 3B 1A 0A FD 3B 3B

Le programme ee.asm dont le r le est de recevoir des donn es sur le port s rie (2400, N81) et de les stocker en EEPROM. o e e

6.2 Aspect mat riel eNous avons vu plus haut quune s rie dinterrupteurs analogiques avaient et inclus sur la carte. Leur fonction est d ventuellement e e e permettre de court-circuiter pendant un temps bref les lignes RxD et TxD de communication de microcontroleur. En effet, si a lallumage ` le 68HC11 est en bootstrap mode, il attend de recevoir un signal sur la broche RxD et agit en cons quence. Si ce signal est 0xFF, le e baudrate est correct et lacquisition du programme a stocker commence. Si ce signal est 0x00, lex cution saute en d but dEEPROM : ` e e le programme qui avait et stock l` ant rieurement est ex cut . Dans les autres cas, le microcontroleur change le baud rate. e e a e e e Or a lallumage, la premi` re op ration du programme du bootloader est denvoyer 0x00 sur la broche TxD. Ainsi, en court-circuitant ` e e temporairement RxD et TxD, nous lancons le programme en EEPROM plut t quattendre lacquisition dun programme a ex cuter par o ` e le port s rie. e Le court-circuit se fait simplement en connectant un circuit RC sur la commande dun des interrupteurs analogiques elle m me e connectant la commande dun autre interrupteur analogique a la masse. La commande de cette seconde porte logique est cependant ` maintenue a l tat haut par une r sistance de pull-up de 10 k. Au reset, le niveau de la broche RESET est bas. Cette broche est reli e a ` e e e ` la commande du premier interrupteur analogique qui est donc ouvert, et la r sistance de pull-up maintient le second interrupteur ferm , e e connectant TxD et RxD. Le circuit RC se charge, fermant le premier interrupteur qui relie la commande du second interrupteur a la ` masse et ouvre donc le contact entre TxD et RxD.

6.3 Aspect pratiqueLe programme hc11.pas a et pr vu pour eventuellement accepter deux arguments. Nous avons jusque l` fourni un seul argument, le e e a programme en hexad cimal a charger dans la RAM du 68HC11. Si nous donnons deux argument, qui sont dans lordre le programme e `

4

ee.out vu plus haut, suivi du nom du programme a charger en EEPROM (nomm ici prg.out, hc11.exe ee.out prg.out chargera ` e dans un premier temps ee.asm dans la RAM du HC11 ee dont le r le est dattendre la r ception de prg.out sur le port s rie et o e e de le stocker en EEPROM. Ceci se fait par un d lai dune seconde entre la n de l mission de ee.out et le d but de l mission de e e e e prg.out (d lai sufsant pour d marrer ee). Il faudra de plus penser a relocaliser, a la compilation, prg.asm a ladresse de d but e e ` ` ` e de lEEPROM (0hFE00, puisque lEEPROM va de 0hFE00 a 0hFFBF) par lajout des deux lignes suivantes en d but de programme : ` e .area code (ABS) et .org 0hFE00.

7 Branchement dune RAM externeDans le cas de la connexion dun composant externe, il faut faire passer le 68HC11 en mode etendu de facon a ce que les ports F, B et ` C soient utilis s comme bus dadresse (octets de poids faible et fort) et bus de donn es (sur 8 bits), et pour faire fonctionner le signal e e d criture R/W#. Cette op ration se fait de facon logicielle : en effet, il nous faut tout dabord etre en bootstrap mode pour charger le e e programme en RAM interne du 68HC11 avant de pouvoir acc der a la RAM externe. e ` Le branchement de la RAM se fait facilement en reliant les bus dadresse et de donn es et, pour eviter les risques de conit avec les e m moires internes, nous avons reli les signaux dadresse 13 et 14 aux signaux dactivation de la RAM pour faire commencer lespace e e adressable de celle-ci a 0x2000. `0000 8E 00 FF 0003 CE 10 00 ters offset 0006 18 CE 20 00 000A 86 FF 000C A7 01 000E 1C 28 20 ; set SPI clock rate 0011 6F 2C lds #0h00FF ldx #0h1000 ; config regis0013 CC 33 0C 0016 A7 2B 0018 E7 2D ldy #0h2000 ; RAM offset 001A 86 E5 ldaa #0hFF ; set A port for output 001C A7 3C staa 0h01,x ; | 001E 1F 2E 20 FC bset 0h28,x,#0h20 ; read char 0022 E6 2F clr 0h2C,x ; 2400 bauds, N81 0024 E7 00 ldd #0h330C ; | staa 0h2B,x ; | stab 0h2D,x ; | ldaa #0hE5 ; set extended mode staa 0h3C,x ; | xmi: brclr 0h2E,x,#0h20,xmi ldab 0h2F,x ; | stab 0h00,x ; store on port A 0026 18 E7 00 stab 0h00,y ; store in RAM 0029 18 E6 00 ldab 0h00,y ; read from RAM 002C 18 08 iny ; goto next RAM address 002E 1F 2E 80 FC rec: brclr 0h2E,x,#0h80,rec ; echo char to serial port 0032 E7 2F stab 0h2F,x ; | 0034 7E 00 1E jmp xmi

Ce circuit peut facilement etre modi pour y adapter une RAM de 32K 62256 : relever les broches 1, 20 et 22 de la RAM et relier e 1 a la broche dadresse 14 du 68HC11 tandis que les broches 20 et 22 sont reli es a la masse pour toujours activer la RAM. ` e `

8 R sultat nal : acquisition de donn es, stockage en RAM puis envoie par port s rie e e eLobjectif du travail pr sent jusquici etait de r aliser un syst` me capable de faire seul un grand nombre ( 1000) dacquisitions pendant e e e e une dur e d termin e a lavance (de lordre de quelques heures), et une fois les donn es obtenues dattendre un signal ext rieur (sur le e e e ` e e port s rie) pour envoyer ces donn es a un PC qui soccupera du traitement des donn es. e e ` e Le programme suivant : initialise le port de communication et les convertisseurs A/D puis passe en mode etendu pour pouvoir acc der a la RAM externe. e `

lit p riodiquement la valeur analogique sur le convertisseur 3 et stocke la valeur observ e en RAM externe tout en afchant la e e valeur lue sur le port A.

une fois la RAM externe pleine, attend un caract` re (quelconque) sur le port s rie, et afche 00 sur le port A pour indiquer e e lattente.

envoie les donn es sur le port s rie lorsque la requ te a et faite et afche la valeur du caract` re recu sur le port A pour indiquer e e e e e que la transmission est en cours. transmission.

Il faudra se rapporter a lannexe C pour le programme en Turbo Pascal de r ception des donn es de la RAM li e au HC11 vers ` e e e lIBM PC une fois lacquisition nie.0000 0003 ters 0006 000A 000C 8E 01 50 CE 10 00 offset 18 CE 20 00 86 FF A7 01 lds #0h0150 ; stack ldx #0h1000 ; config regisldy #0h2000 ; RAM offset ldaa #0hFF ; port A: output staa 0h01,x ; | 000E 1C 28 20 ; port D OR mode 0011 6F 2C 0013 CC 33 0C 0016 A7 2B 0018 E7 2D bset 0h28,x,#0h20 clr 0h2C,x ; 2400 bauds, N81 ldd #0h330C ; | staa 0h2B,x ; | stab 0h2D,x ; | 001A 001C 001E able 0020 TION 86 E5 A7 3C 86 90 A/D converters A7 39 register ldaa #0hE5 ; set extended mode staa 0h3C,x ; | ldaa #0h90 ; enstaa 0h39,x ; store OP-

5

0022 0025 fore 0026 0028 002B sion 002D 002F 0031 0034 0036 0038

CE 3F FF 09 next conversion 26 FD CE 10 00 86 23 on AD3 A7 30 8D 30 18 A7 00 A7 00 18 08 18 8C 24 00

ad: ldx #0h3FFF loop: dex ; wait bebne loop ldx #0h1000 ldaa #0h23 ; start converstaa 0h30,x ; | bsr ad_read staa 0h00,y ; store in RAM staa 0h00,x ; echo on port A iny ; goto next RAM address cpy #0h2400 ; 256 values

003C 26 E4 tum if not finished 003E 86 00 sult of convert on A 0040 A7 00 0042 1F 2E 20 FC ; wait for 1 char 0046 A6 2F play it on portA 0048 A7 00 004A 18 CE 20 00 004E 18 A6 00

bne ad ; get next daldaa #0h00 ; displ. restaa 0h00,x ; | rcv: brclr 0h2E,x,#0h20,rcv ldaa 0h2F,x ; disstaa 0h00,x ldy #0h2000 ; RAM offset read_ra:ldaa 0h00,y

; read from RAM 0051 1F 2E 80 FC snd: brclr 0h2E,x,#0h80,snd ; echo char to serial port 0055 A7 2F staa 0h2F,x ; | 0057 18 08 iny ; inc RAM @ 0059 18 8C 24 00 cpy #0h2400 ; end of filled RAM ? 005D 26 EF bne read_ra ; get next datum 005F 20 FE fin: bra fin 0061 0063 0065 0067 A6 30 2A FC A6 34 39 ad_read:ldaa 0h30,x bpl ad_read ; wait convert end ldaa 0h34,x ; return res in A rts

300 "out.dat"

180 "out.dat" 160

250 140

200

120

100 150 80

100

60

40 50 20

0 0 100 200 300 400 500 600

0 0 200 400 600 800 1000 1200

Exemple dacquisition avec un l du bus dadresse de la RAM d connect (@5) e e

Exemple dacquisition correcte

9 La communication SPIIBM PCRS232 MOSI MISO CK

68HC11 MasterSS# +5 V

68HC11 SlaveSS# GND

GND MISO SCK MOSI

Connexions a ajouter aux circuits pour faire connecter deux 68HC11 en mode SPI `

La s lection de lesclave a qui le message est envoy se fait par lactivation de SS# qui, au lieu d tre connect e a la masse, est e ` e e e ` reli e a une broche du port B. Dans notre exemple o` nous avons simplement un matre envoyant un message a un seul esclave, nous e ` u `

6

avons directement reli SS# de lesclave a la masse. Les autres connexions consistent a relier directement MOSI, MISO et SCK (signal e ` ` dhorloge) ainsi que les masses des HC11 communiquant entre eux. Les programmes qui suivent ont pour but de tester la communication SPI : le matre emet dans un premier temps les nombres de 0 a ` 255 sur le port SPI (et sur son port A pour v rication) et lesclave afche sur son port A les valeurs lues. Les deux afcheurs connect s e e aux ports A de sortie du matre et de lesclave doivent montrer les m mes valeurs. Dans un deuxi` me temps, le matre lit des valeurs sur e e le port s rie et les afche sur son port A tout en les transmettant a lesclave. Ce second programme permet de v rier quil est possible e ` e dutiliser simultan ment la communication RS232 et SPI qui sont toutes deux connect es au port D du matre. e e 0000 0003 0006 0008 000A 000C 000E 0010 0012 8E CE 86 A7 96 A7 86 A7 86 00 FF 10 00 FF 01 2F 08 38 09 57 lds #0h00FF ldx #0h1000 ldaa #0hFF ; set port A for output staa 0h01,x ldaa 0h2F ; SS# hi, SCk lo, mosi hi staa 0h08,x ; store port D ldaa #0h38 ; - - 1 1 1 0 0 0 staa 0h09,x ldaa #0h57 ; 7=0111 : polarity, phase, rate1, rate0 ; 5=0101 : int, enable, open drain, master staa 0h28,x ; set SPCR ldaa #0h00 ; start : counter=0 0018 001A 001C 001E 0020 0023 0024 0026 002A 002C 002E A7 A7 E6 2A BD 4C 20 2A 00 29 FC 00 26 F2 snd: staa 0h2A,x ; send datum staa 0h00,x wait: ldab 0h29,x bpl wait ; wait until xfer finished jsr delay inca bra snd delay: ldy #0hFFFF wait_d: dey bne wait_d rts

0014 A7 28 0016 86 00

18 CE FF FF 18 09 26 FC 39

Master : emission des nombres de 0 a 255 sur le port SPI (D) et A. `0000 0003 0006 0008 000A 000C 000E 8E CE 96 A7 86 A7 86 00 FF 10 00 2F 08 38 09 47 lds #0h00FF ldx #0h1000 ldaa 0h2F ; SS# hi, SCk lo, mosi hi staa 0h08,x ; store port D ldaa #0h38 ; - - 1 1 1 0 0 0 staa 0h09,x ; store DDRD ldaa #0h47 ; 7=0111 : polarity, phase, rate1, rate0 ; 5=0101 : int, enable, open drain, master staa 0h28,x ; set SPCR ldaa #0hFF 0014 0016 0018 001A 001A 001C 001E 0020 0022 A7 01 86 88 A7 00 E6 2A A6 A7 20 29 FC 2A 00 F6 staa 0h01,x ; port A for output ldaa #0h88 staa 0h00,x ; show 88 on port A while waiting rcv: wait: ldab 0h29,x bpl wait ; wait until xfer finished ldaa 0h2A,x ; send datum staa 0h00,x bra rcv

0010 A7 28 0012 86 FF

Slave : r ception des signaux sur le port SPI et afchage sur le port A e0000 0003 0006 0008 000A 000C 000E 0010 0012 8E CE 86 A7 96 A7 86 A7 86 00 FF 10 00 FF 01 2F 08 38 09 57 lds #0h00FF ldx #0h1000 ldaa #0hFF ; set port A for output staa 0h01,x ; SPI SETUP ldaa 0h2F ; SS# hi, SCk lo, mosi hi staa 0h08,x ; store port D ldaa #0h38 ; - - 1 1 1 0 0 0 staa 0h09,x ldaa #0h57 ; 7=0111 : polarity, phase, rate1, rate0 ; 5=0101 : int, enable, open drain, master staa 0h28,x ; set SPCR ; SERIAL PORT SETUP 0016 0018 001B 001D 001F 0023 0025 0027 0029 002B 002D 6F CC A7 E7 1F E6 E7 E7 E6 2A 20 2C 33 0C 2B 2D 2E 20 FC 2F 2A 00 29 FC F0 ; bset 0h28,X,#0h20 ; ne fontionne pas si D port en open-drain clr 0h2c,x ldd #0h330C ; set baudrate of serial port to 2400 baud, N81 staa 0h2B,x stab 0h2D,x rs_rc: brclr 0h2E,x,#0h20,rs_rc; receive from RS232 ldab 0h2F,x snd: stab 0h2A,x ; send datum to SPI stab 0h00,x wait: ldab 0h29,x bpl wait ; wait until xfer finished bra rs_rc

0014 A7 28

Master : r ception des valeurs ASCII sur le port s rie puis echo sur le port SPI et A. e e

10 Contr le d cran LCD : o ee Nous nous int resserons aux ecrans bas s sur le controleur Hitachi HD44780. Dans notre cas il sagit dun ecran de 4 16 caract` res. e e Ce type d cran poss` de un connecteur a 14 broches, qui sont dans lordre (en partant du bord de l cran) : masse (GND), alimentation e e ` e (+5V), contraste (dans notre cas -5V), 3 bits de controle et 8 bits de donn es. Il existe un mode de communication sur seulement 4 e bits de donn es, permettant ainsi de totalement controler lafcheur avec un seul bus de 8 bits. e Les 3 bits de controle sont, de la broche de polarisation (vers le bord de lafcheur) vers les broches du bus de donn es : RS qui e d termine si la valeur sur le bus de donn es est une instruction (0) ou une donn e (1), R/W qui d termine le sens de la transaction (0 pour e e e e une ecriture, 1 pour une lecture), et E (enable) qui doit etre a 1 pour rendre lafcheur actif. Suivent ensuite les lignes de donn es en ` e commencant de la ligne 0 (poids le plus faible) jusqu` la ligne 7 (poids le plus fort, au bord du connecteur). En mode de communication a 4 bits, seuls les ligne D4-D7 sont utilis es. e Le mode le plus simple dutilisation est sur 8 bits de donn es. Nous connectons le bus de donn es au port B du 68HC11 et le bus de e e controle au port A. Les tableaux ci-dessous r sument le brochage, les commandes a envoyer sur les bus de donn es et de controle, ainsi e ` e que les valeurs possibles des variables de conguration de l cran et leur assignation (entre parenth` ses) dans nos exemples. e e 1 Vss 2 Vcc=+5V 3 Vee 0V

Brochage de lafcheur LCD (la broche 1 est la plus proche du bord de lafcheur)

4 RS

5 R/W

6 E

7 D0

-

14 D7

7

RS R/W Clear Display 0 0 Entry Mode Set 0 0 Display ON/OFF 0 0 Function Set 0 0 Set DD RAM address 0 0 Return Home 0 0 Cursor and Display Shift 0 0 Set CG RAM address 0 0 Read busy ag and address 0 1 Write data to CG or DD RAM 1 0 Read data from CG or DD RAM 1 1 D (0) : display on(1)/off(0) C (0) : curseur on(1)/off(0) B (0) : curseur clignotant on(1)/off(0) DL (1) : N (1) : F (0) : I/D (1) : S (0) : interface sur 8 bits (4 bits si DL=0) 2 lignes font 5 x7

DB7 0 0 0 0 1 0 0 0 BF D D

DB6 0 0 0 0 A 0 0 1 A D D

DB5 0 0 0 1 A 0 0 A A D D

DB4 0 0 0 DL A 0 1 A A D D

DB3 0 0 1 N A 0 S/C A A D D

DB2 0 1 D F A 0 R/L A A D D

DB1 0 I/D C * A 1 * A A D D

DB0 1 S B * A * * A A D D

8

LCD Display 22k 3

4

LCD Display 22k 3 -5V +5V GND

Port A Port B -5V +5V GND HC11

Port A HC11

incr menter la position du curseur apr` s afchage e e S=0 lors des utilisations habituelles (?!)

Nous nutiliserons que les fonctions pr sent es dans la partie sup rieure du tableau. Les fonctions de la partie inf rieure servent a e e e e ` modier les caract` res disponibles sur lafcheur et a lire l tat du controleur de lafcheur. e ` e Il est prudent de toujours attendre au moins 40 s apr` s chaque instruction. eConnexion du 68HC11 a lafcheur LCD pour un bus de donn es sur 8 bits (gauche) et un bus de donn es sur 4 bits (droite). ` e e

MAX232

4066

MAX232

C

E

C

E

68HC11F1

4066

F RS232 connector BD0 Data bus

68HC11F1

F B

RS232 connector

D8

A A0-A2A0 : RS A1 : R/W A2 : E

A A7-A4 A0-A2A4 : D4 A0 : RS A1 : R/W A7 : D7 A2 : E

Vue de dessus du circuit de base du 68HC11 avec position des bus reliant l cran LCD aux ports du HC11, dans le cas dune communication en 8 bits e (gauche) et 4 bits (droite).

0000 0003 0006 0008 000A 000C 000E 0010 0012 0014

8E CE 86 A7 86 8D 86 8D 86 8D

01 FF 10 00 FF 01 01 21 F2 4E 38 19

0016 0018 001A 001C

86 8D 86 8D

0C 15 06 11

lds #0h01FF ; setup : stack & port A for output ldx #0h1000 ldaa #0hFF staa 0h01,x ; DISPLAY SETUP : START on: ldaa #0h01 ; clear display bsr funct ldaa #0hF2 ; R/W#=1 + display F bsr delai set: ldaa #0h38 ; set : 0h38 (8 bit, 4 lines) bsr funct ;off: ldaa #0h08 ; display off : 0h08 ; bsr funct ; blank: ldaa #0h0C ; displ2 : 0h0C bsr funct entry: ldaa #0h06 ; entry mode : 0h06 bsr funct ; END OF SETUP

001E 0020 0022 0024 0026 0026 0027 0029 002B 002D 002D

8D 86 C6 8D

50 15 33 1C

5C 8D 24 C1 38 26 F9 20 FE

bsr messg ; AFFICHE HELLO WORLD ldaa #0h15 ; position ldab #0h33 ; char bsr gotoxy set_dd: incb bsr char ; display cmpb #0h38 bne set_dd start: bra start ; data bus (port A) a ete set to action | RS = 0 (set function) ; input : function in register A funct: staa 0h04,x ldaa #0hF0 ; bit 1 : R/W#=0 bsr delai ldaa #0hF4 ; bit 2 : E=1 bsr delai ldaa #0hF0 ; E=0

002F 0031 0033 0035 0037 0039

A7 86 8D 86 8D 86

04 F0 2B F4 27 F0

8

003B 003D 003F 0041

8D 23 86 F2 8D 1F 39

bsr delai ldaa #0hF2 ; R/W#=1 bsr delai rts ; goto a wanted position and display a char (automat-

0068 006A 006C 006D 006F

18 09 26 FC 4A 26 F5 39

dedans2:dey ; bne dedans2 ; deca bne dedans rts

----1 -- --- ------- => 115 ms ----1 -- --- #0h2FFF => 21.5 ms

icly shifts right after) 0042 0044 0046 0048 004A 004C 8A A7 8D E7 8D 39 80 04 E7 04 01 ; input : char value in register B and position in register A gotoxy: oraa #0h80 ; reg A -> set @ to reg A staa 0h04,x bsr funct stab 0h04,x bsr char rts ; data bus (port A) a ete set to char | RS = 1 (draw char) ; input : char value in register B char: stab 0h04,x ldaa #0h11 ; RS=1, R/W#=0, E=0 bsr delai ldaa #0h15 ; RS=1, R/W#=0, E=1 bsr delai ldaa #0h11 ; E=0 bsr delai ldaa #0h12 ; RS=0, R/W#=1, E=0 bsr delai rts ; attente delai: staa 0h00,x ; met le registre A sur le port A ldaa #0h01 dedans: ldy #0h2FFF ; ldab #0h06 et ldy #0hFFFF => 693 ms 0070 0072 0074 0076 0078 007A 007C 007E 0080 0082 0084 0086 0088 008A 008C 008E 0090 0092 0094 0096 0098 009A 009C 009E 86 C6 8D C6 8D C6 8D C6 8D C6 8D C6 8D C6 8D C6 8D C6 8D C6 8D C6 8D 39 02 48 CC 65 D3 6C CF 6C CB 6F C7 20 C3 57 BF 6F BB 72 B7 6C B3 64 AF

004D 004F 0051 0053 0055 0057 0059 005B 005D 005F

E7 86 8D 86 8D 86 8D 86 8D 39

04 11 0D 15 09 11 05 12 01

0060 A7 00 0062 86 01 0064 18 CE 2F FF

; DEBUT DE LAFFICHAGE CST : messg: ldaa #0h02 ; position (starts at 0) ldab #0h48 ; H bsr gotoxy ldab #0h65 ; e bsr char ; display ldab #0h6C ; l bsr char ldab #0h6C ; l bsr char ldab #0h6F ; o bsr char ldab #0h20 ; bsr char ldab #0h57 ; W bsr char ldab #0h6F ; o bsr char ldab #0h72 ; r bsr char ldab #0h6C ; l bsr char ldab #0h64 ; d bsr char rts

Exemple de programme pour une interface 8 bits0000 0003 0006 0008 8E CE 86 A7 01 FF 10 00 FF 01 lds #0h01FF ; setup : stack & port A for output ldx #0h1000 ldaa #0hFF staa 0h01,x ; DISPLAY SETUP : START bsr delai set: ldaa #0h28 bsr funct on: ldaa #0h01 ; clear display bsr funct ldaa #0hF2 ; R/W#=1 + display F bsr delai blank: ldaa #0h0C ; displ2 : 0h0C bsr funct entry: ldaa #0h06 ; entry mode : 0h06 bsr funct ; END OF SETUP jsr messg ; AFFICHE HELLO WORLD ldaa #0h15 ; position ldab #0h35 ; char bsr gotoxy set_dd: incb bsr char ; display cmpb #0h3B bne set_dd start: bra start ; attente delai: staa 0h00,x ; met le registre A sur le port A ldy #0h3FFF dedans2:dey bne dedans2 rts ; data bus (port A) a ete set to action | RS = 0 (set function) ; input : function in register A funct: psha pshb psha anda #0hF0 ; hi = char ; lo = 0000 staa 0h00,x ; FIRST NIBBLE bsr delai bset 0h00,x,#0h04 ;ldaa #0hF4 : bit 2 : E=1 bsr delai bclr 0h00,x,#0h04 ; E=0 bsr delai pula lsla lsla lsla lsla staa 0h00,x ; SECOND NIBBLE bsr delai bset 0h00,x,#0h04 ;ldaa #0hF4 : bit 2 : E=1 bsr delai bclr 0h00,x,#0h04 ; E=0 bsr delai bset 0h00,x,#0h02 ; R/W#=1 bsr delai pulb pula rts

; goto a wanted position and display a char (automaticly shifts right after) 006B 006D 006F 0071 0073 0075 8A A7 8D E7 8D 39 80 04 CC 04 01 ; input : char value in register B and position in register A gotoxy: oraa #0h80 ; reg A -> set @ to reg A staa 0h04,x bsr funct stab 0h04,x bsr char rts ; data bus (port A) a ete set to char | RS = 1 (draw char) ; input : char value in register B char: psha pshb andb #0hF0 stab 0h00,x ; FIRST NIBBLE, RS=1, R/W#=0, E=0 bset 0h00,x,#0h01 ; RS=1 bsr delai bset 0h00,x,#0h04 ; RS=1, R/W#=0, E=1 bsr delai bclr 0h00,x,#0h04 ; E=0 bsr delai lslb lslb lslb lslb andb #0hF0 stab 0h00,x ; SECOND NIBBLE, RS=1, R/W#=0, E=0 bset 0h00,x,#0h01 ; RS=1 bsr delai bset 0h00,x,#0h04 ; RS=1, R/W#=0, E=1 jsr delai bclr 0h00,x,#0h04 ; E=0 jsr delai bset 0h00,x,#0h02 ; RS=0, R/W#=1, E=0 bclr 0h00,x,#0h01 ; RS=0, R/W#=1, E=0 jsr delai pulb pula rts ; DEBUT DE LAFFICHAGE CST : messg: ldaa #0h02 ; position (starts at 0) ldab #0h48 ; H bsr gotoxy ldab #0h65 ; e bsr char ; display ldab #0h6C ; l bsr char ldab #0h6C ; l bsr char ldab #0h6F ; o bsr char ldab #0h20 ; bsr char ldab #0h57 ; W bsr char ldab #0h6F ; o bsr char ldab #0h72 ; r bsr char ldab #0h6C ; l bsr char ldab #0h64 ; d bsr char rts

000A 8D 26 000C 000E 0010 0012 0014 0016 0018 001A 001C 001E 86 8D 86 8D 86 8D 86 8D 86 8D 28 2D 01 29 F2 1A 0C 21 06 1D

0020 0023 0025 0027 0029 0029 002A 002C 002E 0030 0030

BD 86 C6 8D

00 B0 15 35 42

5C 8D 4A C1 3B 26 F9 20 FE

0032 0034 0038 003A 003C

A7 18 18 26 39

00 CE 3F FF 09 FC

0076 0077 0078 007A 007C 007F 0081 0084 0086 0089 008B 008C 008D 008E 008F 0091 0093 0096 0098 009B 009E 00A1 00A4 00A7 00AA 00AD 00AE 00AF

36 37 C4 E7 1C 8D 1C 8D 1D 8D 58 58 58 58 C4 E7 1C 8D 1C BD 1D BD 1C 1D BD 33 32 39

F0 00 00 01 B1 00 04 AC 00 04 A7

F0 00 00 9A 00 00 00 00 00 00 00

01 04 32 04 32 02 01 32

003D 003E 003F 0040 0042 0044 0046 0049 004B 004E 0050 0051 0052 0053 0054 0055 0057 0059 005C 005E 0061 0063 0066 0068 0069 006A

36 37 36 84 A7 8D 1C 8D 1D 8D 32 48 48 48 48 A7 8D 1C 8D 1D 8D 1C 8D 33 32 39

F0 00 EC 00 04 E7 00 04 E2

00 D9 00 04 D4 00 04 CF 00 02 CA

00B0 00B2 00B4 00B6 00B8 00BA 00BC 00BE 00C0 00C2 00C4 00C6 00C8 00CA 00CC 00CE 00D0 00D2 00D4 00D6 00D8 00DA 00DC 00DE

86 C6 8D C6 8D C6 8D C6 8D C6 8D C6 8D C6 8D C6 8D C6 8D C6 8D C6 8D 39

02 48 B5 65 BC 6C B8 6C B4 6F B0 20 AC 57 A8 6F A4 72 A0 6C 9C 64 98

` Exemple de programme pour une interface 4 bits. A noter que pour des raisons de probl` mes de d lais dans les initialisations, il faut relancer plusieurs e e fois ce programme avant quun message ne safche sur l cran LCD (effectuer un reset du 68HC11 mais ne pas eteindre le g n rateur de tension e e e entre deux reprogrammations an de ne pas r -initialiser a chaque fois l cran LCD). e ` e

9

11 Les interruptions11.1 Les interruptions mat rielles IRQ# e11.1.1 Aspect mat riel e Modications au circuit initial : mettre le bit I du registre de controle par cli va rendre les interruptions mat rielles actives. Par e d faut, toutes les sources internes au 68HC11 dinterruptions mat rielles (principalement les timers) sont inactives. Il nous faut de e e plus d sactiver les broches dinterruptions mat rielles XIRQ et IRQ (actives par un signal au niveau bas) en ajoutant deux r sistances e e e de pull-up entre lalimentation (Vdd=+5V) et ces broches. Lactivation de linterruption mat rielle IRQ se fait alors en mettant cette e broche au niveau bas (par exemple en fermant un interrupteur dans notre exemple). 11.1.2 Aspect logiciel Principe des pseudo-vecteurs : les vecteurs dinterruptions sont situ s en ROM et ne sont donc pas modiables pour pointer vers la e fonction de lutilisateur. Ces vecteurs pointent vers des pseudo-vecteurs pr -d nis qui sont eux situ s en RAM. Il sagit en fait de trois e e e octets r serv s a laction a effectuer lorsque linterruption est d clench e : une instruction JMP (0x7E) suivi des 2 octets de ladresse de e e ` ` e e la fonction de lutilisateur. La liste des adresses des pseudo-vecteurs est disponible p. 3-18 du 68HC11 Reference Manual de Motorola. Le premier exemple que nous proposons ici sert a bien identier la syntaxe permettant de r cup rer ladresse o` se situe une ` e e u proc dure, et de voir comment manipuler cette adresse. Dans le programme ci-dessous, la proc dure nomm e irq commence a e e e ` ladresse 0x0026. Nous allons chercher cette adresse, la stocker dans le registre 16 bits X, puis transf rer X dans D (qui est en fait e la concat nation de A et B) de facon a pouvoir successivement afcher sur le port A les valeurs des registres A et B et ainsi pouvoir e ` visualiser (par exemple sur un afcheur 7 segments connect au port A) ladresse de la proc dure (cette etape interm diaire - le passage e e e de X a D - est obligatoire pour pouvoir visualiser la valeur stock e dans X. Il nest pas possible denvoyer directement X, qui est sur ` e 16 bits, sur un des ports dentr e-sortie 8 bits). Il faut prendre soin, lors de la recherche de ladresse de la proc dure irq, dutiliser la e e syntaxe ldx #irq qui renvoie ladresse o` se trouve irq (0h0023 dans notre cas), et non pas ldx irq qui renvoie le contenu de u loctet se trouvant a ladresse irq (0x86 dans notre cas, qui est lopcode de linstruction ldaa). `

0000 0003 0005 0008 000A 000C 000F 0011 0014 0017 0019 001B 001D 001F 0021

8E 86 B7 86 97 CE DF CE 18 18 A7 8D E7 8D 20

00 FF 10 7E EE 00 EF 10

FF 01

23 00

DE EF 8F 00 09 00 05 F1

lds #0h00FF ldaa #0hFF ; DDRA : output staa 0h1001 ldaa #0h7E ; opcode de JMP staa 0h00EE ; interrupt vector-1=JMP opcode ldx #irq ; ISR de IRQ# : ldx irq=00 86 (opcode de jmp)->ldx #irq stx 0h00EF ; interrupt vector ldx #0h1000 ; cli ; enable interrupts ici: ldy 0h00EF ; BFF2=00 ; BFF3=EE ; 00EE=7E ; 00EF=86 ; F0=00; F1=24 xgdy ; echange X et D staa 0h00,x ; afficher alternativement bsr delai ; ... A et B pour montrer stab 0h00,x ; ... ce qui etait dans X bsr delai bra ici irq: ldaa rti #0h00 ; reset port A

XIRQ IRQ

0023 86 00 0025 3B 0026 002A 002C 002E 18 CE FF FF 18 09 26 FC 39

delai: ldy #0hFFFF wait: dey bne wait rts

Programme de lecture de la valeur stock e dans un pseudo-vecteur du 68HC11 et afchage sur le port A (v rication de la programmation de e e ladresse de la fonction de gestion des interruptions)

Linstruction cli met le bit I du registre de controle a 0 et met ainsi en marche les interruptions mat rielles. ` e Application au cas de la r -initialisation dune variable par une interruption mat rielle. Il est n cessaire de passer par une zone e e e m moire en RAM car lappel a une fonction provoque un empilement des registres qui seront ensuite r -initialis s a leurs valeurs e ` e e ` initiales lors de linstruction rti. Ce programme fait d ler les nombres binaires sur le port A, et remet le compteur a 0 chaque fois e ` quune interruption mat rielle est provoqu e par la fermeture de linterrupteur. e e0000 0003 0005 0008 000A 000C >ldx 000F 0011 0014 0015 0017 0019 001B 8E 00 86 FF B7 10 86 7E 97 EE CE 00 #irq DF EF CE 10 0E 86 00 97 E0 96 E0 4C FF 01 lds #0h00FF ldaa #0hFF ; DDRA : output staa 0h1001 ldaa #0h7E ; opcode de JMP staa 0h00EE ; interrupt vector-1=JMP opcode ldx #irq ; ISR de IRQ# : ldx irq=00 86 (opcode de jmp)stx 0h00EF ; interrupt vector ldx #0h1000 cli ; enable interrupts ldaa #0h00 staa 0h00E0 ici: ldaa 0h00E0 inca 001C 001E 0020 0022 97 A7 8D 20 E0 00 07 F5 staa staa bsr bra 0h00E0 0h00,x delai ici

24

0024 86 00 0026 97 E0 0028 3B 0029 002D 002F 0031 18 CE FF FF 18 09 26 FC 39

irq: ldaa #0h00 ; PAS ldaa #0h00 directmt car rti pop regs staa 0h00E0 rti delai: ldy #0hFFFF wait: dey bne wait rts

00

10

Exemple de remise a 0 par interruption mat rielle dun compteur : le port A afche les valeurs croissantes dun constante dun compteur qui est remis ` e a 0 par la fermeture de linterrupteur reliant la broche IRQ a la masse. ` `

Il faut penser, pour toute utilisation des interruptions mat rielles li es aux timers internes du HC11, a effectuer la modication sur les e e ` broches IRQ et XIRQ (en les reliant via une r sistance denviron 5 k a lalimentation Vdd). e ` Lutilisation du compteur pr sent e ici permet de r aliser un scheduler lorsque plusieurs t ches doivent etre ex cut es s quentiellement e e e a e e e avec une p riodicit donn e, ou une modulation en largeur de pulse (PWM). Dans le but davoir le temps de voir le compteur e e e ` osciller, nous avons d cid dabaisser la fr quence du timer au 16eme de sa valeur par d faut en mettant PR1 et PR0 du registre e e e e TMSK2 (0h1024) a 1. Le compteur va de 0 a 65536 en 524.3/2 ms (i.e. 4 s par tic dhorloge). On le fait compter de 1 a ` ` ` 0hDFFF=53248+3840+240+15=57343 soit 229.4 ms entre deux incr ments du compteur. e La valeur du compteur, incr ment a chaque interruption, est afch e sur les ports A et B. La broche 6 du port A oscille de plus a la e e` e ` fr quence des interruptions (sortie PWM). e0000 0003 0005 0008 000A 000C 000F 8E 86 B7 86 97 CE DF 00 FF FF 10 01 7E DC 00 2E DD lds ldaa staa ldaa staa ldx stx #0h00FF ; stack #0hFF ; set port A for output 0h1001 ; | on affiche cpt val sur A et B, et A6=PWM #0h7E ; opcode de JMP 0h00DC ; interrupt vector of OC2 #int ; ISR de int 0h00DD ; interrupt vector+1 de OC2 = int @ 0021 0023 0025 0026 0028 002A 002C 002E 0030 0031 0033 0036 0038 003A 003C 003E 86 97 0E 96 A7 A7 20 96 4C 97 CC E3 ED 86 A7 3B 00 E0 E0 04 00 F8 E0 E0 DF FF 12 12 40 23 ldaa #0h00 ; initialisation du compteur staa 0h00E0 ; octet en RAM stockant la valeur a afficher cli ; enable interrupts : check pull ups on IRQ & XIRQ ici: ldaa 0h00E0 staa 0h04,x ; display counter value on port B staa 0h00,x ; display counter value on port A bra ici int: ldaa 0h00E0 ; PAS inca directmt car rti pop regs inca ; incremente le compteur staa 0h00E0 ; stocke le result ldd #0hDFFF ; 1/2 delay PWM time of next interrupt ldaa #0h40 staa 0h23,x ; clear flag by setting 0100 0000 (OC2) rti

0011 CE 10 00 0014 1C 24 03 0017 0019 001B 001D 001F 86 A7 A7 86 A7 40 23 22 40 20

11.3

Programmation multi-t ches au moyen des interruptions - linstruction WAI a

Jusquici, nos programmes n taient capables que deffectuer une op ration a la fois : soit faire lacquisitions de donn es provenant e e ` e des convertisseurs analogiques-num eriques, soit transmettre des donn es sur le port s rie, soit attendre la r ception de donn es sur le e e e e port RS232. Lutilisation des interruptions dans lexemple qui suit va donner limpression que le 68HC11 est capable de simultan ment e incr menter un compteur de facon p riodique tout en etant a l coute du port s rie. De plus, mettre toutes les fonctions a ex cuter par e e ` e e ` e le microcontroleur sous interruption permet une economie d nergie par l x cution de linstruction WAI lorsque quaucune t che nest e e e a a ex cuter. Cette instruction met le 68HC11 en mode veille qui consomme moins de courant. Le microcontroleur est r activ lorsquun ` e e e interruption qui a et autoris e (dans notre cas le timer, la r ception dun message sur le port s rie ou lactivation de linterruption e e e e mat rielle sur la broche IRQ) est d clench e. e e e0000 0003 0006 0008 000A 000C 000E code de 0011 0013 0016 0017 001A 001C 001F 8E CE 86 A7 01 20 10 00 00 01 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 lds #0h0120 ; set stack ldx #0h1000 ldaa #0h00 ; port A setup for input staa 0h01,x ; | ldaa #0h7E ; opcode de JMP staa 0h00C4 ; interrupt vector-1=JMP opcode ldx #irq ; ISR de IRQ# : ldx irq=00 86 (opstx 0h00C5 ; interrupt vector ldx #0h1000 cli ; enable interrupts bset 0h28,x,#0h20 ; serial port setup clr 0h2c,x ldd #0h332C ; set baudrate, enable recv & tx staa 0h2B,x ; 2400 N81 with 16 MHz xtal 0021 E7 2D 0023 0023 3E 0024 20 FD 0026 002A 002C 002E 002F 0033 0035 0038 003A 18 CE FF FF 18 09 26 FC 39 1F A6 B7 A7 3B 2E 20 FC 2F 01 00 05 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 stab 0h2D,x ; 2 de 2C : enable receive interrupt

86 7E 97 C4 CE 00 2F jmp)->ldx #irq DF C5 CE 10 00 0E 1C 6F CC A7 28 20 2C 33 2C 2B

Exemple dinterruption d clench e a la r ception dun caract` re sur le port s rie : le compteur est remplac par la valeur ASCII du caract` re recu. e e ` e e e e e 0000 0003 0006 0008 8E CE 86 A7 01 20 10 00 00 01 1 lds #0h0120 ; set stack 2 ldx #0h1000 3 ldaa #0h00 ; port A setup for input 4 staa 0h01,x ; | 5 6 ; setup serial port interrupt routine 7 ldaa #0h7E ; opcode de JMP 8 staa 0h00C4 ; interrupt vector-1=JMP opcode toggle output of port A6 on int

main: ; ldaa 0h0100 ; read stored value ; staa 0h05,x ; and display on port F wai ; low power sleep mode bra main delai: ldy wait: dey bne wait rts #0hFFFF

irq: brclr 0h2E,x,#0h20,irq ; reset serial port ldaa 0h2F,x ; load received character staa 0h0100 ; store in memory staa 0h05,x ; display on port F rti ; end of interrupt service routine

002A 1D 25 7F 002D 1C 24 83 0030 86 00 0032 B7 01 01 0035 0035 3E 0036 20 FD 0038 003C 003E 0040 0041 0043 0045 0048 0049 004B 004E 18 CE FF FF 18 09 26 FC 39 86 A7 B6 4C A7 B7 3B 80 25 01 01 05 01 01

; staa 0h00EE ; interrupt vector-1=JMP opcode 0) then begin writeln; writeln(TERMINAL Version 1.00 Written 1995 by Stephan A. Maciej); writeln(Internet: [email protected] http://www.muc.de/stephanm); writeln; { Check for some correct parameters on the command line. } GetCommandLine(PortNr, Speed); PortBase := GetPortBase(PortNr); if (PortBase = 0) then begin writeln(COM, PortNr, : no such port !); halt; end; UsedIRQ := 4 - ((PortNr - 1) and 1); UARTType := GetUARTType(PortBase); { Reset both the incoming as well as the outgoing Queue. } ResetQueue(InQueue); ResetQueue(OutQueue); { Write some information about the selected port. } WritePortInfo; { Setup the port, run the terminal and reset the port when ready. } SetupPort(PortBase, Speed, UsedIRQ); if (paramcount>1) then RunTerminal(PortBase,paramstr(1),paramstr(2)) else RunTerminal(PortBase,paramstr(1), ); ResetPort(PortBase,UsedIRQ); end else writeln(progname filename); end.

{ Check if a 16550A UART is present... } if (UARTType = UART_16550A) then begin { Clear the FIFO queues } Port[PortBase + FifoCtrl] := $07; { Enable the FIFO queues } Port[PortBase + FifoCtrl] := $C1; { Print a message so the user recognizes the FIFO queues are on } writeln(Enabling 16550A FIFO queues...); end; end; procedure RunTerminal(PortBase: word;s:string;s2:string); { Run the Terminal } var fc:file of char; {0..255} b1,b2,bl:char; cnt,i:integer; begin { sendchar(H);sendchar(e);sendchar(l);sendchar(l);sen dchar(o); sendchar( );sendchar(W);sendchar(o);sendchar(r);sendchar(l) ; sendchar(d);sendchar( ); } {sendchar(chr(0)); repeat until keypressed;} i:=0; assign(fc,s);reset(fc);b1:= ; sendchar(chr($FF)); { set baud rate } while not EOF(fc) do begin while ( ((b1= ) or (b1=chr(10)) or (b1=chr(13)) ) and not eof(fc)) do if not eof(fc) then read(fc,b1); if (ord(b1)>47) then begin cnt:=0; read(fc,b2); if (ord(b1)>96) then b1:=chr(ord(b1)-32); {min -> maj} if (ord(b2)>96) then b2:=chr(ord(b2)-32); if (ord(b1)96) then b1:=chr(ord(b1)-32); {min -> maj} if (ord(b2)>96) then b2:=chr(ord(b2)-32); if (ord(b1)