XII- INTRODUCTION AU MICROCONTRÔLEUR M68HC12 12.1- La notion de Microcontrôleur L’objectif d’un microcontrôleur est de : ¢ Diminuer les interconnexions de circuits, sources de plus-values et de pannes. ¢ Intégrer sur la même puce de silicium le microprocesseur et un certain nombre de périphériques. Parmi les périphériques que l’on va intégrer on trouve : - La mémoire RAM - La mémoire ROM. - La mémoire EEPROM - Des ports de liaisons parallèles - Des ports de liaison série - Des compteurs temporisateurs - Des convertisseurs numériques analogiques et analog/ numériques - Des contrôleurs de DMA et d’interruption Etc... Remarque : Le microcontrôleur universel n’existe pas 12.2 Introduction au 68HC12 • • • • • • circuit intégré HCMOS CPU avec registres et ALU Mémoires (RAM, EEPROM, Flash) Timer Divers organes d’entrée/sortie Convertisseur A/D 12.3 Deux versions du M68HC12 Comparaison E/S Série MC68HC812A4 2 ports série asynchrone (SCI) Un port série synchrone (SPI) MC68HC912B32 Un port série asynchrone (SCI) Un port série synchrone (SPI) Un contrôleur supplémentaire de transmission série Modulation de la largeur d’impulsion Non 4 canaux 8-bit Extension de mémoire Jusqu’à 5 Mbytes non Application Applications nécessitant de l’extension mémoire Application demandant de multiples ports d’E/S Mémoire 1 Kbyte RAM 4 Kbytes EEPROM 1 Kbyte RAM 768 bytes EEPROM 32 Kbytes FLASH EEPROM 12.4 Les registres Accum. A 15 7 Accum. B 0 Double Accumulateur D 0 Registre Index X Registre Index Y Registre Conditions Pointeur de PILE Compteur Ordinal SXHINZVC Retenue Dépassement Zéro Négatif Masque inter. Retenue Aux. Masque inter. Stop 12.5 Le plan mémoire Le 68HC12 est un microcontrôleur 16-bits, 16 bits données, 16 bits adresses possibilité d'adresser 216 positions en mémoire =64 Kbytes de 0000h à FFFFh Il peut utiliser des mémoires 8-bits Gamme des adresses $0000 - $01FF $0800 - $09FF $0A00 - $0BFF $0D00 - $0FFF $8000 - $F67F $F680 - $F6BF $F6C0 - $F6FF $F700 - $F77F $F780 - $F7FF $F800 - $FBFF $FC00 - $FFBF $FFC0 - $FFFF Usage Registres de la CPU Code/donnée utilisateur Réservé pour D-bug12 Code/donnée utilisateur Code D-Bug12 Fonctions accessibles à l'utilisateur Données D-Bug12 Code départ D-Bug12 Table des sauts d'interruption Réservé pour le boot (extension) Boot EEPROM Reset vecteur interruption Description On chip 1 Kbyte RAM On chip 768 byte on-chip EEPROM 32 Kbytes on-chip EEPROM FLASH 12.6 Les modes d'adressage il y a plusieurs manières d'accéder à des données ou à des codes stockés dans une cellule mémoire: "modes d'adressage" Modes d'adressage du 68HC12 1. Immédiat 2. Direct 3. Etendu 4. Indexé (pré et post incrément et décrément) 5. Indexé indirect 6. Inhérent 7. Relatif ¢ Adressage immédiat La donnée suit immédiatement l'instruction. # signifie adressage immédiat Exemple ldda #!64 ; décimal 64 dans A ldda #$64 ; hex 64 dans A ldx #$1234 ; hex 1234 dans X ¢ Adressage direct Adressage page zéro 256 emplacement mémoire 00h à FFh (adresse 8-bits) LSByte La CPU met le MSByte à 00h On peut adresser donc de 0000h à 00FFh (256 emplacements) Exemple: ldaa $64 ; ($0064) dans A Stab !255 ; B dans ($00FF) ldx !10 ; ($000A:000B) dans X ¢ Adressage étendu On utilise l'adresse sur 16-bit pour adresser 216 emplacements mémoire C'est une instruction 3-bytes, l'adresse est sur les deux bytes juste après l'opcode. Exemple: ldaa $1234 ; ($1234) dans A ldd $1234 ; ($1234:1235) dans D stx $c000 ; X dans ($C000:C001) ¢ Adressage indexé Il fait intervenir les registres index X et Y et des fois SP et PC . Format : Operation Offset, registre_index Registre_index : X, Y, SP ou PC offset 5, 9, ou 16 bits valeur ajoutée au contenu du registre_index 1er cas: offset=constante: Exemple: ldaa ,x ldaa 0,x ldaa -!64,Y ; (x + 0) 5 bit offset dans A ; (x + 0) 5 bit offset dans A ; (Y-64) 9 bit offset dans A Staa -1, SP ldaa !5000,PC ; A dans (SP – 1) 5 bit offset ; (PC + 5000) 16 bit offset dans A 2ème cas Index avec incrément et décrément (pré et post): Le format est le suivant : Opération valeur, - registre_index Opération valeur, registre_indexOpération valeur, +registre_index Opération valeur, registre_index+ pré décrémentation post décrémentation pré incrémentation post incrémentation La valeur est ajoutée ou soustraite du registre index avant (pré) ou après (post) que la donnée soit transférée. Valeur : entier 1 to 8 Registre_index: X, Y ou SP Exemple: ldaa !7, -X ; X-7 dans X, (X) dans A pré décrémentation ldaa !2, X+ ; (X) dans A, X+2 dans X post incrémentation 3ème cas : Accumulateur offset Format de l'instruction: Opération Registre, registre_index register: A, B, ou D register_index : X, Y, SP, PC L'instruction calcule l'adresse effective en ajoutant 8 ou 16 bits au registre index. Ceci ne change pas la valeur actuelle du registre. Exemple: ldaa B,X ; (X+B) dans A ldab A,Y ; (Y+A) dans B ldy D,X ; (X+D:X+D+1) dans Y 4ème cas : Indexé indirect Ce mode est indirect car on va chercher de l'adresse de la donnée qui elle sera utilisée pour aller chercher la donnée. Exemple ldx #$5000 ; $5000 dans X (on initialise X) ldaa [$64,X] ; ((5064)) dans A ou bien staa [-1,X] ; A dans (($4FFF)) ¢ Adressage inhérent L'instruction elle-même contient l'adresse où se trouve la donnée. Exemple: Aba Inx ; A+B dans A ; X+1 dans X ¢ Adressage relatif Si on dispose d'une mémoire organisée en pages, il suffit d'indiquer l'adresse à l'intérieur de la page et de garder l'adresse de la page dans un registre (registre des pages). Adresse effective AE = base B + dépassement D (D est assez grand) 12.7 Programmation en assembleur du M68HC12 12.7.1 Exemple LDX $F682 JSR 0,X PSHA LDAA #$3D 0806 0800 FE F6 82 0803 15 00 0805 36 86 3D 12.7.2 Syntaxe de l'assembleur Un programme est spécifique d'un microprocesseur Une instruction Label (étiquette) Exemple: Opcode LDX 4 champs Champs du code source Opérande $F682 a- champ label ou étiquette ( 16 caractères : ) b- champ opération (code d'instruction) c- champ opérande (soit l'opérande ou son adresse) d- champ commentaires (commence par ; ) Remarque Labels interdits 612FG : Début LDAB : 12.7.3 Le jeu d'instruction du M68HC12 (voir document PDF, notes de cours) Exemple: Retard: $MACRO Loop: $MACROEND equ delay_100 PSHA LDAA DECA BNE loop PULA !100 ; sauvegarder le contenu de A #retard ; récupérer le contenu de A Commentaire ; Faire appel à getchar 12.7.4 Le format des instructions et des données Donnée : 8 ou 16 bits Instruction: 1 octet 2 octets 3 octets << code opération >> << code op. + donnée ou adresse (8 bits) >> << code op.+ donnée ou adresse (16 bits) >> 12.7.5 Les directives et les pseudo-instructions ce sont des instructions qui serviront à l'assembleur mais ne seront pas assemblées - Nom du programme - Origine de départ - Fin de programme, etc... Exemples de pseudo-opérations ORG : (origine) adresse du départ du programme, celle qu'utilisera le compteur ordinal. ORG $0800 EQU: (equate), c'est un ordre d'équivalence PROG: EQU $4000 ORG PROG DB: (define byte) définir qu'on travaille par octet BUF1: DB $45,$45,$33,$37,$31,$20,$69,$73,$20,$66,$75,$6E,$21,$7F DW : (define word) on travaille sur 16 bits DS: (define storage) réserver des emplacements mémoires BUF4: DS !14 Directives (elles sont invoquées par /, # ou $) BASE : change la base de numérotation 2, 8, 10, 16 $BASE n INCLUDE: Inclure un fichier pour être assemblé avec le programme $INCLUDE "Spécifications fichier" IF, ENDIF: code conditionnel "SI" et "fin de condition" MACRO et MACROEND: début et fin de macro-instruction HEADER: une entête 12.7.6 Erreurs détectées par l'assembleur a- Erreur d'adresse LDAA $FFC68 b- Erreur d'équilibrage DB "D' c- Erreur d'expression PUSHA d- Erreur de format LDX $fe04,$fe05 e- Erreur de caractère LDAB %01112110 PSHA f- Définitions multiples LABELxx.....xx1 :........... LABELxx.....xx2 :...... (sur 16 caractères ça donne le même label) g- Erreur d'emboîtement pour les macros et les branchements conditionnels h- Erreur de phase ORG debut i- Autres erreurs debut EQU !5 Erreurs de syntaxe (omission d'un code, débordement pile,...) 12.7.7 Les ruptures de séquences et les macro-instructions Les diverses ruptures de séquences : - Lors du déroulement d'un programme on passe d'une instruction à la suivante selon un mode séquentiel. - Le compteur ordinal est incrémenté à chaque pas - On dit qu'il y a rupture de séquence lorsque cette règle n'est plus appliquée Les principales ruptures de séquences sont: - Les branchements inconditionnels ou conditionnels BNE (branch if not equal Z=0) Les appels de sous-programmes, conditionnels ou inconditionnels CALL , JSR (jump to subroutine) - Les retours de sous-programmes, conditionnels ou inconditionnels RTS (return from subroutine) Les échanges (entrées/sorties) lorsqu'ils font appel à des sous-programmes spécialisés (routines de services) Macro-instructions (groupe d'instructions): On retrouve dans un programme des séquences identiques d'instructions qui se répètent Deux solutions: Écrire une macro-instruction (nombre d'instruction petit) Écrire un sous-programme (quand le nbre d'inst. devient important) 12.7.8 Fichiers de sortie de l'assembleur L'assembleur produit deux fichiers importants : ¢ Le fichier listing (qui inclut une table des symboles) ¢ Et le fichier S-record (qui sera chargé sur la mémoire du microcontrôleur pour être exécuté) Format du fichier listing place en mémoire . . Table des symboles . . Exemple : [cycles] code objet Numéro de ligne code source ESSAI2.ASM Assembled with IASM 09/28/2000 15:45 PAGE 1 0000 0000 0000 0000 0000 0800 0800 [02] CF0A00 0803 [02] CC080B 0806 [03] FEF686 0809 [04] 1500 080B 68656C6C 6F20776F 726C6400 17 18 Symbol Table DATA EOS HELLO PRINTF PROG STACK SWI 1 ;exemple page 47 2 ;essai 3 ;programme sur iasm12 4 eos: equ 0 ; fin de chaine de caracteres 5 ; definitions pour Debug-12 6 printf: equ $f686 ;Debug ver 2.xx 7 prog: equ $0800 8 data: equ $0900 9 stack: equ $0a00 10 /org prog 11 /lds #stack 12 /ldd #hello 13 /ldx printf 14 /jsr 0,x 15 swi 16 hello: db 'hello world',eos 0900 0000 080B F686 0800 0A00 080B Essai2.hex :10080000CF0A00CC080BFEF686150068656C6C6F8D :0708100020776F726C640099 :00000001FF Essai2.S19 S1130800CF0A00CC080BFEF686150068656C6C6F89 S10A081020776F726C640095 S9030000FC Remarque: L'assembleur IASM12.EXE nécessite une installation avec IASMINST.EXE qui permet de définir, entre autres, les fichiers de sorties et le format. Exemple sur l'utilisation du Dbug12: D-Bug12 v2.0.2 Copyright 1996 - 1997 Motorola Semiconductor For Commands type "Help" >asm 900 0900 C624 0902 FEF684 0905 1500 0907 FEF682 090A 1500 090C 8605 090E 36 090F FEF684 0912 1500 0914 32 0915 43 0916 26F6 0918 3F 0919 0500 LDAB #$24 LDX $F684 JSR 0,X LDX $F682 JSR 0,X LDAA #$05 PSHA LDX $F684 JSR 0,X PULA DECA BNE $090E SWI JMP 0,X >g 900 $yyyyy User Breakpoint Encountered PC SP X Y D = A:B CCR = SXHI NZVC 0918 09FF DE3E 00C0 00:79 1001 0100 0918 3F SWI Les routines utilitaires du DBug12 „ Le D-Bug12 fournit des sous-programmes nécessaires pour les tâches d'entrées/sorties. „ On accède à ces sous-programmes par l'instruction JSR „ Remarque : Les sous-programmes sont écrits en langage C Exemple: LDX $F682 JSR PSHB LDAB LDX $F684 JSR PULB LDX $F698 JSR LDAB LDX $F684 JSR LDAB JSR SWI ; Lire un caractère avec getchar 0,X #$3D ; Garder le caractère dans la pile ; Charger le code ASCII pour = ; L’afficher avec putchar 0,X ; Récupérer le caractère de la pile ; Afficher son code hexadécimal avec out2hex 0,X #$0D 0,X #$0A 0,X ; Charger le code ASCII pour la touche « retour chariot CR» ; Et l’afficher ; Charger le code ASCII pour « line feed LF » ; Et l’afficher Exercices Exercice 1 Si on utilise la commande D-Bug12, MD 0900 090F, on obtient : 25 E6 5D 85 F5 02 C1 10 4A 61 42 FC DE AB 55 77 (en hexadécimal) Donner les résultats après l'exécution des instructions suivantes: a) SP = $0910 PSHA PSHB SP = .................. b) SP = $090C PULA PSHB A = .................... SP = ...................... c) LDX #$0900 LDAA 0,X A = .................... NZVC = ...................... d) LDX #$0900 LDAA 4,X A = .................... NZVC = ...................... e) LDAA $0900 CMPA $0905 A = .................... NZVC = .................(après exéc. de CMPA) Exercice 2 Écrire pour les pseudo-codes suivants, une partie du programme correspondant pour le M68HC12. On montrera le branchement conditionnel vers " LABELX " au cas où la condition serait vérifiée. On supposera que P et Q sont des nombres binaires 8-bit sans signes et qu'ils se trouvent dans les emplacements mémoires P et Q. a) IF P ≤ Q b) IF P + Q > $40 Exercice 3 Donner le mode d'adressage et calculer l'adresse effective dans les cas suivants: Instruction ldx #$4000 Staa Ldy $10,x #$400D Ldaa -!20,y Ldx #$4000 Ldaa [$64,x] Staa $04FA Mode d'adressage Adresse effective Exercice 4 Écrire un programme sur le M68HC12 qui réalise les opérations décrites ci-dessous. Placer le code programme dans l'espace vide qui suit le commentaire. ORG $4000 ; Initialiser le pointeur de pile à $0A00 ; Initialiser le registre X pour qu'il pointe à l'adresse $5000 ; Transférer les contenus en bytes des emplacements mémoire $5000 - $5014 vers $6000 - $6014 ; Retourner au programme moniteur D-Bug12. Exercice 5 Écrire un programme pour le microcontrôleur M68HC12, qui calcule la somme des nombres positifs d'un tableau de 10 nombres, chaque nombre étant sur 8 bits. Le tableau est stocké à partir de l'adresse $D000 jusqu'à $D009. Exercice 6 Calculer la moyenne de ces 10 nombres (programme 1) et écrire le résultat à l'adresse $0000. Exercice 7 Écrire un programme structuré qui obéit au pseudo-code (algorithme) suivant : SI A1 = B1 ALORS QUAND C1 < D1 FAIRE Décrémenter D1 A1=2 ∗ A1 FIN DE "FAIRE" FIN DE "QUAND C1 < D1" SINON A1 = 2 ∗ B1 FIN DE "SI A1 = B1" On suppose que A1, B1, C1 et D1 sont des nombres binaires positifs sur 16 bits et que l'allocation mémoire, dans le programme, est la suivante: A1: DS 2 B1: DS 2 C1: DS 2 D1: DS 2 On suppose aussi que les valeurs de A1, B1, C1 et D1 sont connues et déjà entrées ailleurs dans le programme. Solutions des exercices Exercice 1 a) SP = $0910 PSHA PSHB b) SP = $090C PULA PSHB c) LDX #$0900 LDAA 0,X d) LDX #$0900 LDAA 4,X e) LDAA $0900 CMP $0905 SP = ....090E.............. A = .......DE............. SP = ......$090C................ A = ......25.............. NZVC = .......000x.............. A = ......F5.............. NZVC = .......100x............... A = . 23 NZVC = ....0000.............. Exercice 2 a) IF P ≤ Q ldaa P cmpa Q BLE labelx b) IF P + Q > $40 ldaa P adda Q cmpa #$40 BHI labelx Exercice 3 Donner le mode d'adressage et calculer l'adresse effective dans les cas suivants: Instruction Mode d'adressage Adresse effective ldx #$4000 immédiat Staa $10,x indexé $4010 Ldy #$400D immédiat Ldaa -!20,y indexé $3FF9 Ldx #$4000 immédiat Ldaa [$64,x] indexé indirect (($4064)) dans A Staa $04FA étendu $04FA Exercice 4 ORG $4000 ; Initialiser le pointeur de pile à $0A00 LDS #$0A00 ; Initialiser le registre X pour qu'il pointe à l'adresse $5000 LDX $5000 ; Transférer les contenus en bytes des emplacements mémoire 5000 - 5014 vers 6000 - 6014 (on suppose qu'on travaille en décimal, sinon en hexa il faudrait incrémenter le contenu de l'accu. 20 fois ($5014-$5000=$14=20 décimal)) Une des solutions peut être: ldaa #!0 ldx #$5000 ldy #$6000 movb !0,x+,!0,y+ inca cmpa #!15 blo loop ; Retourner au programme moniteur D-Bug12. SWI loop Exercice 5 Une des solutions ; programme array equ $d000 prog equ $800 ; on peut supposer des valeurs test tab: DB $10,$20,$30,$1F,$3D,$CC,$21,$00,$C5,$F1 org prog LDX #$0000 LDAA #!10 LDY #array loop ldab 1,y+ ABX deca bne loop swi ; initialisation du registre X utilisé pour la somme ; initialisation d'un compteur ; adresse de la 1ère donnée ; mettre valeur dans B puis incrémenter y ; addition X<=X+B ; décrémenter compteur ; la somme est dans X Exercice 6 Une des solutions ; Programme array prog resultat equ $d000 equ $800 equ $0000 ; on peut supposer des valeurs test tab: DB $10,$20,$30,$1F,$3D,$CC,$21,$00,$C5,$F1 org prog LDX #$0000 LDAA #!10 LDY #array loop ldab 1,y+ ABX deca bne loop tfr D,X ldx #!10 IDIV XGDX ; initialisation du registre X utilisé pour la somme ; initialisation d'un compteur ; adresse de la 1ère donnée ; mettre valeur ds B puis incrémenter y ; addition X<=X+B ; décrémenter compteur ; ; ; ; mettre somme dans D diviseur dans X division entier D/X résultat dans X placer résultat dans D staa swi resultat ; placer le résultat à l'adresse $0000 ; fin Exercice 7 0000 FC002D 0003 BC002F 0006 261C 4 0008 FC0031 000B BC0033 000E 2412 10 0010 FE0033 0013 09 0014 7E0033 0017 FC002D 001A F3002D 001D 7C002D 0020 20E6 22 0022 2009 24 0024 FC002F 0027 F3002F 002A 7C002D 002D 002F 0031 0033 33 34 35 36 1 ; IF A1 = B1 2 ldd A1 3 cpd B1 bne else_part 5 ; THEN 6 ; WHILE C1 < D1 7 while_start: 8 ldd C1 9 cpd D1 bhs end_while 11 ; DO 12 ; Decrement D1 13 ldx D1 14 dex 15 stx D1 16 ; A1 = 2 * A1 17 ldd A1 18 addd A1 ; Double it 19 std A1 20 ; ENDO 21 ; ENDWHILE C1 < D1 bra while_start 23 end_while: bra end_if 25 ; ELSE 26 else_part: 27 ; A1 = 2 * B1 28 ldd B1 29 addd B1 30 std A1 31 ; ENDIF A1 = B1 32 end_if: A1: B1: C1: D1: DS DS DS DS 2 2 2 2