LE 68HC11

 

                     

Exemples d’applications de programmes en assembleur à partir du  microcontrôleur de Motorola –

le 68HC11F1 - mettant en œuvre un LCD - 4 lignes * 16 caractères -.

A.    HC11F1. 4

1.1       Montage. 4

1.2       Organisation interne du 68HC11F1 : 4

1.3       Montage. 5

1.4       Test des ports du HC11. 6

1.4.1        Les programmes. 6

1.4.2        LES INSTRUCTIONS. 6

1.4.2.1     Chargements, Sauvegardes et Transferts. 6

1.4.2.2     Opérations arithmétiques. 7

1.4.2.3     Décalages et rotations. 7

1.4.2.4     Opérations logiques. 7

1.4.2.5     Branchements et sauts. 7

B.     LCD.. 7

1.5       Niveau des différentes broches. 8

1.5.1        Description des différentes broches. 9

1.6       Apparition des caractères sur l'afficheur 9

1.7       Principe de fonctionnement 10

1.8       Tableau des différentes commandes de l'afficheur 10

1.8.1        Description des différentes commandes. 13

1.9       Table des caractères. 13

1.10     Application pratique. 14

1.10.1      Schéma de montage : 15

1.10.1.1       Utilisation des ports du 68HC11. 15

1.10.2      Instructions et caractères : 15

1.10.2.1       Envoi d’instructions. 15

1.10.2.2       Envoi de caractères. 17

1.10.3      Le programme : 18

1.10.3.1       Affichage du message « Hello World » sur le LCD.. 18

1.10.3.2       Idem précedent avec message passé en adresse : 19

1.10.3.3       Idem précédent avec plusieurs lignes : 19

1.10.3.4       Affichage d’un chronomètre hh :mm :ss. 19

1.10.3.5       Convertisseur Hexa >> Décimal : 19

1.10.3.6       Convertisseur Hexa >> ASCII : 20

1.10.3.7       Convertisseur PhMetre : 20

1.10.3.8       Voltmetre : 20

C.    Convertisseur Analogique / numérique. 20

1.11     Initialisation. 20

1.12     Les registres : 20

1.12.1.1       Registre OPTION ($1039) 20

1.12.1.2       Registre ADCTL ($1030) 21

1.12.2      Initialisation du CAN : 21

1.13     Exemples. 22

1.13.1      Les programmes : 22

1.13.1.1       Resultat CAN sur PORTB.. 22

1.13.1.2       Voltmetre. 23

D.    La communication série : ASCI. 23

1.14     Initialisation. 23

1.15     Les registres. 23

1.15.1.1       Registre HPRIO ($103C) 23

1.15.1.2       Registre BAUD ($102B) 24

1.15.1.3       Registre SCCR1($102C) 25

1.15.1.4       Registre SCCR2 ($102D) 25

1.15.1.5       Registre SCSR ($102E) 25

1.15.1.6       Registre SCDR ($102F) 25

1.16     Principe de communication : 26

1.17     Les programmes. 26

1.17.1.1       Exemple de lecture des données venant sur le port série du 68HC11 : 26

1.17.1.2       Exemple d’émission de données sur le port série du 68HC11 : 26

1.17.1.3       Combinaison des deux programmes précédents pour lire une valeur sur le port série et la renvoyer au PC : 27

E.     Branchement d’une RAM externe. 27

1.18     Les registres. 27

1.18.1.1       Registre HPRIO ($103C) 27

1.19     Montage. 27

1.20     Exemple de programme. 29

1.20.1      Acquisition du convertisseur numérique, stockage en RAM et envoi des résultats par SCI 29

1.20.1.1       Le programme. 29

1.20.1.2       Principe. 29

1.20.1.3       Résultat 29

F.     La communication SPI 30

1.20.1.4       Master : émission des nombres de 0 à 255 sur le port SPI (D) et écho sur le portA. 31

1.20.1.5       Slave : réception des signaux sur le port SPI et affichage sur le port A.. 32

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

G.    Contrôle d'afficheur BCD.. 34

H.    Timer / compteur. 35

1.21     Compteur 35

1.21.1      Les registres. 35

1.21.1.1       Registre PACNT  $1027. 35

1.21.1.2       Registre TMSK2  $1024. 36

1.21.1.3       Registre TFLG2  $1025. 36

1.21.2      Les Interruptions : 36

1.21.2.1       Compteur d’evenement 37

1.22     Timer 39

1.22.1.1       Timer quand PA est mis à 0. 39

I.      Les interruptions. 39

1.23     Les interruptions matérielles IRQ#. 40

1.23.1      Aspect matériel 40

1.23.2      Aspect logiciel 41

1.23.3      Montage. 41

1.23.4      Déclenchement d’une interruption :  IRQ.. 42

1.24     Les interruptions matérielles liées aux timers : RTI. 44

1.24.1      Déclenchement d’une interruption : SCI 46

1.24.1.1       Interruption déclenchée à la réception d’un caractère sur le port série. 46

1.24.2      Déclenchement d’une interruption :  TIMER.. 46

1.24.2.1       Exemple de combinaison des interruptions timer 46

1.24.3      Aplications : 46

1.24.3.1       Registre PACTL bits RTR0, RTR1 :déterminent la période d'interruption. 47

1.24.3.2       Registre TMSK2 bit 6 RTII autorise l'interruption RTI 47

1.24.3.3       Registre TFLG2 bit 6 RTIF indique l'état de l'interruption. 48

1.24.3.4       Registre TMSK2. 51

1.24.3.5       Registre TFLG2 bit 7 TOF indique l'état de l'interruption. 51

1.24.3.6       Timer Interrupt Mask Register 2 (TMSK2 $1024) 59

1.24.3.7       Timer Interrupt Flag Register 2 (TFLG2 — $1025) 60

1.24.3.8       Timer Interrupt Mask Register 2 (TMSK2 $1024) 66

1.24.3.9       Timer Interrupt Mask Register 1 (TMSK1 $1022) 64

1.24.3.10     Timer FLAG Register 1 (TFLG1 $1023) 67

J.      Moteur pas à pas. 72

1.25     Principe. 72

1.26     Montage. 73

K.    Les liens. 74

 

 

 

1.1    Montage

Le montage proposé est le suivant :

   

 

1.2    Organisation interne du 68HC11F1 :

 

1.3    Montage

1.4    Test des ports du HC11

1.4.1   Les programmes

 

Défillement des LED sur le PORTB de gauche a droite avec pointeur par FCB : K2000.ASC

 

 

1.4.2   LES INSTRUCTIONS 

1.4.2.1   Chargements, Sauvegardes et Transferts 

Mise à zéro d'un registre mémoire : CLR ou d'un accumulateur CLRA, CLRB.
Chargement : LDAA, LDAB, LDD, LDX, LDY, LDS.
Sauvegarde : STAA, STAB, STD, STX, STY, STS.
Mise d'octet(s) dans la pile : PSHA, PSHB, PSHX, PSHY.
Sortie d'octet(s) de la pile : PULA, PULB, PULX, PULY.
Transfert : TAB, TBA, TAP, TPA, TSX, TSY, TXS, TYS.
Echange : XGDX, XGDY.

1.4.2.2   Opérations arithmétiques 

Addition : ABA, ABX, ABY, ADDA, ADDB, ADDD, ADCA, ADCB.
Comparaison : CBA, CMPA, CMPB, CPD, CPX, CPY, TST, TSTA, TSTB.
Incrémentation : INC, INCA, INCB, INX, INY, INS.
Décrémentation : DEC, DECA, DECB, DEX, DEY, DES.
Soustraction : SUBA, SUBB, SUBD, SBCA, SBCB.
Complément à deux : NEG, NEGA, NEGB.
Multiplication : MUL.
Division : FDIV, IDIV.
Ajustement décimal : DAA.

1.4.2.3   Décalages et rotations 

Décalage vers la gauche : ASL, ASLA, ASLB, ASLD, LSL, LSLA, LSLB, LSLD.
Décalage vers la droite : ASR, ASRA, ASRB, LSR, LSRA, LSRB, LSRD.
Rotation vers la gauche : ROL, ROLA, ROLB.
Rotation vers la droite : ROR, RORA, RORB.

1.4.2.4   Opérations logiques 

Et logique : ANDA, ANDB, BITA, BITB.
Ou logique : ORAA, ORAB, Ou exclusif : EORA, EORB.
Complémentation : COM, COMA, COMB.
Mise à un (ou à zéro) d'un bit : BSET, BCLR, SEC, CLC, SEI, CLI, SEV, CLV.

1.4.2.5   Branchements et sauts 

Suivant l'état du bit : BRSET, BRCLR, BCS, BCC, BVS, BVC, BEQ, BNE, BMI, BPL.
Signés : BGE, BGT, BLE, BLT.
Non signés : BHI, BHS, BLO, BLS.

Inconditionnels : BRA, BRN, JMP, BSR, JSR, RTS, RTI.

Divers :SWI, WAI, NOP, STOP, TEST.

 

 

 

 

 

 

 

 

 

 

 



 

 

 

 

 

 

Nous nous intéresserons aux écrans basés sur le contrôleur Hitachi HD44780. Dans notre cas il s’agit d’un écran de 4*16 caractères.

Réglage du contraste par un potentiometre.

Alimentation 5V  et -5V pour le contraste du LCD.

 

 

 

 

1.5     Niveau des différentes broches

N° DE BROCHE

SIGNAL

NIVEAU

14

VSS

Masse

13

VDD

+ 5 V

12

VLC

-2,5 V

11

RS

0 = Instruction 1 = caractère.

10

   R/

0 = écriture 1 = lecture

9

E

Front descendant

8

D0

Logique positive

7

D1

Logique positive

6

D2

Logique positive

5

D3

Logique positive

4

D4

Logique positive

3

D5

Logique positive

2

D6

Logique positive

1

D7

Logique positive

 

1.5.1   Description des différentes broches

1 à 8 : D7 à D0 : Bus de donnés bidirectionnel 3 états

9 : E : Entrée de validation (ENABLE) ;elle est active sur front descendant. Il est important ici de tenir compte des 2 seuils durées de commutation importantes en pratique: lorsque RS et R/ ont atteint un niveau stable, il doit se passer un intervalle de 140 ns minimum avant que la ligne "E" ne passe au niveau haut. Cette ligne doit ensuite, être maintenue à ce niveau pendant 450 ns au moins et les données doivent rester tables sur le bus de données jusqu'au début du flanc descendant de ce signal. Lorsque E=0 les entrées du bus de l'afficheur sont à l'état haute impédance.

10 : R/: Lecture ou écriture.(READ/WRITE). Lorsque R/ est au niveau bas, l'afficheur est en mode "écriture", et lorsque R/ est au niveau haut, l'afficheur est en mode "lecture".

11 : RS: Sélection du registre.(REGISTER SELECT) : Grâce à cette broche, l'afficheur est capable de faire la différence entre une commande et une donnée. Un niveau bas indique une commande et un niveau haut indique une donnée.

12 : VLC : Cette tension permet le réglage du contraste de l'afficheur. C'est une tension négative et tournant autour de -1,5 V.(selon l'angle de visualisation)

13 : VDD : + 5 V

14 : VSS : Masse.

 

1.6    Apparition des caractères sur l'afficheur

Apres avoir défini le sens de déplacement, les caractères apparaissent au dessus du curseur (qu'il soit visualisé ou non).

Remarque : la ligne 3  et la suite de la ligne 1 et la ligne 4 la suite de la ligne 2 au  niveau adressage.

Adresse

gauche droite

invisible

haut : ligne 1

$00 ............... $0F

 

bas : ligne 2

$40 ................$4F

 

haut : ligne 3

$10 ............... $1F

$20 .......... ....$3F

bas : ligne 4

$50 ................$5F

$60 .......... ....$67

 

        

00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F

40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F

10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F

50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F

 

 
 

 

 

 

 

 


L'adresse 00 correspond à la ligne du haut à gauche, 0F à droite.

L'adresse 40 correspond à la ligne du bas à gauche, 4F à droite.

La zone invisible correspond à la mémoire de l'afficheur.(48 caractères)

Lorsqu'un caractère est inscrit à l'adresse $27, le caractère suivant apparaît à la ligne suivante

 

1.7    Principe de fonctionnement

  Le principe de fonctionnement est simple, pour visualiser un caractère, il suffit de le positionner sur le bus de donnée (codé en ASCII), de mettre RS au niveau haut (caractère), R/ au niveau bas (écriture), et de provoquer un front descendant sur l'entrée de validation de l'afficheur (E).

ATTENTION: Après chaque action sur l'afficheur, il faut vérifier que celui-ci est en mesure de traiter l'information suivante. Pour cela il faut aller lire l'adresse de la position du curseur (RS=0, R/=1) et tester l'indicateur flag "Busy" (BF) (voir tableau ci-dessous). Lorsque BF=1 l'affichage est en cours et lorsque BF=0, l'affichage est terminé, on peut passer au caractère suivant

.

1.8    Tableau des différentes commandes de l'afficheur

Valeur usuelle

TYPE DE COMMANDE

RS

R/W

D7

D6

D5

D4

D3

D2

D1

D0

DESCRIPTIF

 

#$01

EFFACER

L'AFFICHAGE

0

0

0

0

0

0

0

0

0

1

Efface l'ensemble de la mémoire de données sans toucher au générateur de caractère. Met le curseur en position Home, à l'adresse 00.

 

         #$02

CURSEUR EN

POSITION HOME

0

0

0

0

0

0

0

0

1

*

Met le curseur en position Home. Si l'affichage à été décalé, il est remis à sa position d'origine: l'adresse 00 se trouve à nouveau en haut à gauche.

 

       #$06

MANIERE DE

VISUALISER LES

CARACTERES

0

0

0

0

0

0

0

1

ID

S

Détermine le sens de déplacement du curseur après apparition d'un caractère (ID) et le déplacement collectif d'une position de l'ensemble de l'affichage (S).

 

       #$0E

MARCHE/ARRET

DE L'AFFICHAGE

DU CURSEUR

0

0

0

0

0

0

1

D

C

B

Met l'affichage en ou hors fonction (D). Met le curseur en ou hors fonction (C). Fait clignoter le caractère situé au-dessus du curseur (B), clignotement se traduisant par une alternance du caractère et du caractère FF (rectangle noir)

 

DECALAGE

0

0

0

0

0

1

S/C

R/L

*

*

Déplace le curseur ou l'ensemble de l'affichage sans modifier le contenu de la mémoire.

      #$

FONCTION

0

0

0

0

1

DL

N

F

*

*

Indique la largeur du bus de données. Indique s'il ne faut utiliser que la ligne du haut ou que celle du bas. (F) : matrice

 

ADRESSE DU

GENERATEUR DE

CARACTERES

0

0

0

1

Caractère

Rangée

Définit l'adresse de la mémoire du générateur de caractères. Les données suivantes correspondent à la matrice du caractère concerné.

 

ADRESSE DE LA MEMOIRE DE DONNEES

0

0

1

Adresse

Définit l'adresse de la mémoire de données. Les données suivantes correspondent au caractère ASCII à visualiser.

 

INDICATEUR BUSY

LECTURE

D'ADRESSE

0

1

BF

Adresse

Lit l'indicateur Busy (BF) pour vérifier que l'afficheur et en mesure de traiter la commande suivante. Lit l'adresse de la position du curseur.

 

ECRITURE DE DONNEES

1

0

Données

Ecrit des données respectivement dans la mémoire de données ou le générateur de caractères.

 

LECTURE DE

DONNEES

1

1

Données

Lit les données respectivement de la mémoire de données ou le générateur de caractères.

1.8.1   Description des différentes commandes.

 

 

0

1

ID

Déplacement vers la gauche

Déplacement vers la droite

S

L'affichage ne bouge pas

L'affichage est décalé

C

Absence du curseur

Visualisation du curseur

B

Absence de clignotement du caractère

Clignotement du caractère

S/C

Déplacement du curseur

Déplacement de l'affichage

R/L

Décalage vers la gauche

Décalage vers la droite

DL

4 bits

8 bits

N

Ligne du haut

2 lignes validées

Le bit noté F permet de définir la matrice des caractères suivant le tableau ci dessous.

N

F

Nombre DE LIGNE

MATRICE

0

0

1

5 * 7

0

1

1

5 * 10

1

*

2

5 * 7

1.9    Table des caractères

 

1.10                   Application pratique

1.10.1                    Schéma de montage :

Fig1 : Schéma de montage en mode 8 bits (gauche) et 4 bits (droite). Pour la suite le mode 8 bits sera retenus.

Fig2 : Schéma de montage en mode 8 bits et 4 bits sur le 68HC11. Pour la suite le mode 8 bits sera retenus.

1.10.1.1               Utilisation des ports du 68HC11.

Pour la réalisation du programme de l'afficheur le PORT B et le PORT A sont nécessaires.

PORT A : Pour les commandes de l'afficheur qui se compose du RS, E, R/W,

            A0 : RS

            A1 : R/W

            A2 : E

PORT B : Pour les données de l'afficheur, qui correspondent aux déplacements de l'affichage, positionnement du curseur, sélection de la ligne, déplacement de l'affichage.

1.10.2                    Instructions et caractères :

1.10.2.1               Envoi d’instructions

Après la mise sous tension de l'afficheur, la ligne supérieur devrait être totalement sombre, celle du bas complètement claire. Si tel n'était pas le cas, il faudra augmenter (négativement) la valeur de la tension VLC à l’aide du potentiomètre. Il est temps maintenant d'envoyer les premières commandes d'initialisation.

La première commande à envoyer est la commande permettant de définir le mode de dialogue avec l'afficheur (DL), et le nombre de lignes sélectionnées (N). Pour cela, on met RS et R/ au niveau bas et on positionne sur le bus de données le code correspondant au choix de l'utilisateur (cette commande efface la ligne supérieure). Après un front descendant de l'entrée E, l'information sera prise en compte. A partir de maintenant, l'ordre des commandes n'a plus d'importance. La routine suivante permet de valider une commande envoyée sur le portb :

Fonc    staa PORTB,x

ldaa #$F0                   * E=0 RW=0 RS=0 * RS en mode instruction

bsr delay                     *attente avant instruction suivante

ldaa #$F4                   * E=1 RW=0 RS=0 * en front montant >> validation

bsr delay                     *attente avant instruction suivante

ldaa #$F0                   * E=0 RW=0 RS=0 * RS en mode instruction

bsr delay                     *attente avant instruction suivante

rts

 
 

 

 

 

 


Envoyons par exemple la commande $01 (effacement de l'afficheur) :

Puis la commande $0E : l’afficheur est allumé (D=1), sans curseur (C=0), sans faire clignoter le caractère (B=0).                   

LDAA $0E

BSR Fonc

 

 

 

 
 

 


Ensuite, il faut définir le sens de déplacement du curseur, pour cela, envoyons la commande $06, soit ID=1 et S=0 pour décaler le curseur a droite après la réception d’un caractère.

 

LDAA $06

BSR Fonc

 

 

 
 


Il faut définir le type de bus sélectionné : 8 bits 

 

LDAA $38

BSR Fonc

 

 

 
 

 


1.10.2.2               Envoi de caractères.

Ceci étant fait, on peut maintenant commencer à envoyer les premiers caractères à afficher. Il faut faire passer la ligne RS au niveau haut et envoyer sur le bus de données les codes des caractères à afficher. Après chaque front descendant de l'entrée E, le caractère sera affiché au dessus de la position du curseur.

Char    staa PORTB,x

ldaa #$11                    * E=0 RW=0 RS=1 * RS en mode caractere

bsr delay                     *attente avant instruction suivante

ldaa #$15                    * E=1 RW=0 RS=1 * en front montant >> validation

bsr delay                     *attente avant instruction suivante

ldaa #$11                    * E=0 RW=0 RS=1 * RS en mode caractere

bsr delay                     *attente avant instruction suivante

rts

 
 

 

 

 

 

 


Exple envoi du caractere « H » sur l’afficheur :

 

LDAA $48

BSR Char

 

 

 
 


De nombreuses animations peuvent être effectuées sur l'afficheur. On peut déplacer le curseur en positionnant sur le bus de données l'adresse souhaitée. Un défilement des caractères est même possible, il suffit pour cela d'envoyer la commande $07 (ID=1, S=1) sans oublier de positionner RS à 0. Mais il faut faire attention car un décalage de l'affichage décale également les adresses de l'afficheur de sorte à ce que l'extrême gauche de la ligne supérieur ne soit plus adressable à l'adresse 00. La commande retour Home permet de repositionner les adresses de l'affichage.

Le BUSY est l'indicateur nécessaire pour permettre de savoir si l'afficheur à exécuté la commande que l'on a donnée, d'une c'est une vérification, mais surtout si il est prêt à exécuter une autre commandes pour la poursuite du programme.

ATTENTION: Avant toute procédure d'écriture, il est impératif de tester l'indicateur Busy. Pour cela il faut aller lire l'adresse de la position du curseur en mettant RS au niveau bas, R/ au niveau haut, et effectuer un ET logique avec la valeur $80 afin de permettre le test du bit BF de l'indicateur Busy. Lorsque BF=0, il est possible d'envoyer le caractère suivant à afficher. (Cette lecture doit avoir lieu lorsque la ligne E se trouve au niveau haut)

Gotoxy            oraa #$80        * evalue busy avant d'envoyer valeur portB     

                        bsr fonc

                        bsr char

                        rts

 
 

 


Car si l'on tente d'écrire d'envoyer des commandes à l'affichage pendant que ce dernier est en cours de traitement de donnée ou d'une commande précédente, le système peut se planter, l'affichage s'affole et les 2 circuits intégrés voient leur température augmenter.

1.10.3                    Le programme :

 

1.10.3.1               Affichage du message « Hello World » sur le LCD

 

*******************************************************

****                       affiche message sur LCD                             ***

*******************************************************

*DONNES SUR PORT B sur $04

*INSTRUCTION SUR PORT A sur $00

                               org $FE00                                                              * positionnement EEPROM

PORTB   equ    $04                                                                               *donnes

PORTA   equ    $00                                                                               *instructions

DDRA     equ     $01

 

**Initialisation constante***

*******************************************************

                               lds #$0150                                              *pile

                               ldx #$1000                                             *offset

                               ldaa #$FF

                               staa DDRA,x                                          *port A en sortie

***initialisation LCD***      

*******************************************************

Init                          ldaa #$F2                                                * E=0 , RW=1 , RS=0 sur PORTA                                                          bsr delay

home                       ldaa  #%00000001                                  *0000 0001 : place curseur position HOME

                               bsr fonc                                                  *(#$01)

enter                       ldaa  #%00000110                                  *0000  0110 : deplacement afficheur droite

                               bsr fonc                                                  *(#$06)

Curse                       ldaa  #%00001100                                  *0000 1100 : D=1 afficheur alumé

                               bsr fonc                                                  *C=0 *sans curseur  *B=0 sans clignotement (#$0C)

Bus                          ldaa #%00111000                                   *0011 1000 : BUS 8 bits (#$38)

                               bsr fonc

***Affiche message***

*******************************************************

                               bsr messg

                                stop                       

*** routine du pgm :***

*******************************************************

***Délai avant instruction suivante***

delay                       staa PORTA,x

                               ldaa #$01

dedans                     ldy #$2FFF

dedans2                   dey                                                         *tempo wait instruction 115ms

                        bne dedans2                                            *21.5ms

                               deca                                                        *

                               bne dedans

                               rts

* **Test busy avant  instruction suivante***

gotoxy                    oraa #$80                                              * evalue busy avant d'envoyer valeur portB           

                               bsr fonc

                               bsr char

                               rts

***envoi instruction port B : RS au niveau bas***

fonc                        staa PORTB,x                                        *instruction sur PORTB

                               ldaa #$F0                                               *E=0 RW=0 RS=0 * RS en mode instruction

                               bsr delay

                               ldaa #$F4                                                * E=1 RW=0 RS=0 * en front montant >> validation

                               bsr delay

                               ldaa #$F0                                                * E=0 RW=0 RS=0

                               bsr delay

                               rts

* **envoi caractere sur port B :RS au niveau haut***

char                         stab PORTB,x

                               ldaa #$11                                                *E=0,R/W=0,RS=1  * RS en mode données

                               bsr delay

                               ldaa #$15                                                *E=1,RW=0,RS=1 *E en front montant >> validation

                               bsr delay

                               ldaa #$11                                               *E=0,RW=0,RS=1 * Reinit E

                               bsr delay

                               rts

***Message***

*******************************************************

messg       ldaa #$02                *E=0,R/W=1,RS=0 pour evaluation busy

                ldab #$48                *H

                bsr gotoxy

                ldab #$65                *E

                bsr char

                ldab #$6c                 *L

                bsr char

                ldab #$6C                *L

                bsr char

                ldab #$6F                *O

                bsr char

                ldab #$20                *' '

                bsr char

                ldab #$57                *W

            bsr char

                ldab #$6F                *O

                bsr char

                ldab #$72                *R

                bsr char

                ldab #$6C                *L

                bsr char

                ldab #$64                *D

                bsr char

                rts              

                end

 
 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


A partir de là on peut utiliser ce pgm de base pour afficher n’importe quelle données

En remplacement de : bsr messg

 

Message en Hexa : LCDHELLO.ASC

 

 

1.10.3.2               Idem précedent avec message passé en adresse :

Utilisation de FCB : LCDHELL1.ASC

 

Utilisation de FCC : LCDHELL3.ASC

 

1.10.3.3               Idem précédent avec plusieurs lignes :

Utilisation de FCC et position curseur adréssé (FCB) : LCDHELL2.ASC

 

1.10.3.4               Affichage d’un chronomètre hh :mm :ss

Adressage par FCb : LCDHRONO.ASC

 

1.10.3.5               Convertisseur Hexa >> Décimal :

Affichage en Décimal de la valeur Hexadecimal recu sur le PORT B : LCDHXDEC.ASC

Exple : la valeur hexadécimal « C5 » s’affichera sous la forme « 197 » a l’cran.

 

1.10.3.6               Convertisseur Hexa >> ASCII :

Affichage de la valeur hexadécimal recu sur le PORT B : LCDHXASCII.ASC

 Exple : la valeur hexadécimal « C5 » s’affichera sous la forme « C5 » a l’cran.

 

1.10.3.7               Convertisseur PhMetre :

Simulation d’un affichage pour PhMetre. Codification de la valeur Hexadécimal recue sur l’échelle

Ph = 0 (valeur « $00 » ) à Ph = 14 (valeur « $256 » : LCDPH.ASC

 Exple : la reception de la valeur valeur hexadécimal « $51 » affichera un Ph= 2.55 a l’écran.

$51 * 14 / 255 = 2.8

 

1.10.3.8               Voltmetre :  

Utilisation du Convertisseur Analogique Numerique pour afficher la tension 0/5V à l’ecran.

Variation de la tension par un potentiometre : LCDVOLT.ASC

 

 

 

 

 

1.11                   Initialisation

Lecture des valeurs du convertisseur analogique-numérique.

Il faut :

  1. Mettre en route les convertisseurs A/D en écrivant dans le registre $1039 (OPTION).
  2. Pour chaque nouvelle conversion, écrire le numéro du convertisseur (entre 0 et 7) qui doit effectuer la conversion dans le registre 0x1030 (ADCTL) (dans l’exemple ci-dessous, nous utilisons le convertisseur numéro 3).
  3. Attendre le signal de fin de conversion (par polling du registre $1030 ADCTL ).
  4. Lire la valeur obtenue dans le registre $1031 ADR1.

1.12                   Les registres :

1.12.1.1               Registre OPTION ($1039)

 

Bit 7

6

5

4

3

2

1

Bit 0

ADPU

CSEL

IRQE

DLY

CME

FCME

CR1

CR0

 

·  Bit7 – ADPU :  0 = CAN désactivé    1 = CAN activé

·  Bit6 – CSEL :   0 = CAN et EEPROM utilisent l’horlage du quartz    1 = CAN et EEPROM utilisent l’horloge du systeme RC

·  Bit5 – 

 

1.12.1.2               Registre ADCTL ($1030)

 

Bit 7

6

5

4

3

2

1

Bit 0

CCF

0

SCAN

MULT

0

CC

CB

CA

 

·  Bit7 - CCF: Ce bit est un indicateur, quand il est mis à 1 cela signifie que le CAN vient de terminer une conversion.

·  Bit5 - SCAN : Quand ce bit est mis à 1 :  la conversion est faite continuellement.

                            Quand ce bit est mis a 0 : une seule conversion est effectuée.

·  Bit4 - MULT : Quand ce bit est mis a 1 : quatre entrées d’un même groupe défini par CC sont converties. Si CC = 0 il s’agit du 1er groupe : PE0  PE1  PE2  et PE3  si CC=1 alors le 2eme groupe est converti : PE4  PE5  PE6  et  PE7

                            Quand ce bit est mis à 0 : une seule entrée est convertie ; Les bits CC, CB et CA définissent cette entrée.

·  Bit2 1 0  - CC...CA

 

 

CC

CB

CA

Entrée

Résultat

 

0

0

0

PE0

ADR1

 $1031

0

0

1

PE1

ADR2

 $1032

0

1

0

PE2

ADR3

 $1033

0

1

1

PE3

ADR4

 $1034

1

0

0

PE4

ADR1

 $1031

1

0

1

PE5

ADR2

 $1032

1

1

0

PE6

ADR3

 $1033

1

1

1

PE7

ADR4

 $1034

 

1.12.2                    Initialisation du CAN :

L’exemple suivant permet d’allumer le CAN : $90 dans OPTION ( ADCTL = 1 et BIT4 = 1 )

Et $00 dans ADCTL ( SCAn = 0 une seule conversion, MULT = 0 une seule entrée convertie , Cb= CA = CC = 0 : selection du BIT  E0  en recuperant adresse $1031

ldaa     #$98                *%10011000                                                
staa     OPTION                                                                              
ldaa     #$00                *%00000000                                                
staa     ADCTL                                                                                            

 
 

 



 

1.13                   Exemples 

 

1.13.1                    Les programmes :

Convertion de E0 :

 

****************************************

***                                                                     **

***                              CAN                              **

***                                                                     **                        

****************************************

**        read A/D from port E : bit 7

**        write PORT B

 

ADCTL                       equ                              $30

PORTB                       equ                              $04     

OPTION                     equ                              $39

PORTE                       equ                              $0A

ADR1                         equ                              $31

 

 

                                   org     $FE00               * start of EEPROM

 

                                   ldx       #$1000            * needed for the brclr command

                                   ldaa      #%10011000  * Power up A/D with clock delay

                                   staa    OPTION,x        * OPTION

 

Main

                                   ldaa      #%00000000 * single scan, multi-mode, pins e0-3

            staa    ADCTL,x          * write starts conversion   ADCTL

Conversion                  brclr ADCTL,x,#$80 Conversion  *wait end conversion  ADCTL      

            ldaa    ADR1,x            * get value from pin E0, E1, E2, or E3  ADR1                       

                                   staa    PORTB,x          * store it to PORTB

                                   bra     Main                  * boucle

                                              

                                   end

 

 

 

 

 

 

                                              

                       

 
 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


1.13.1.1               Resultat CAN sur PORTB

Lecture du CAN bit E0   et affichage sur le PORT B : CAN.ASC

 

1.13.1.2               Voltmetre

Fonction voltmètre avec affichage de la tension 0-5V sur le LCD : LCDVOLT .ASC

 

 

 

1.14                   Initialisation

http://www.stielec.ac-aix-marseille.fr/cours/abati/mic68711.htm

Il faut :

  1. mettre le port D en mode communication.
  2. déterminer la vitesse et le protocole de transmission.
  3. une fois ces initialisations effectuées, attendre la transmission d’un caractère et le lire lorsqu’il a été reçu (par polling).

Dans les programmes qui suivent, le 68HC11 doit être relié par un cable direct (non-croisé) à un PC sur lequel tourne un logiciel d’´ emulation de terminal (type Terminal sous Windows 3.11 ou Procom sous DOS). Dans le premier exemple, le 68HC11 affiche sur le port A (auquel on aura reli´ e un afficheur 7 segments par exemple) la valeur ASCII du caractère envoyé par le PC (par appui d’une touche du clavier du PC par exemple). Dans le second exemple, le 68HC11 envoie en continu les caractères ASCII affichable : le terminal doit continuellement afficher les signes de ponctuation, les chiffres et l’alphabet en minuscules et majuscules. Enfin, le dernier exemple combine ces deux applications par attendre l’envoi d’un caractère du PC et le lui renvoyer.

 

1.15                   Les registres

1.15.1.1               Registre HPRIO ($103C)

Définit le mode des ports B et F : en adressage ou en ports normaux (sortie)

 

7

Bit 6

5

4

3

2

1

 0

RBOOT

SMOD

MDA

IRV

PSEL3

PSEL2

PSEL1

PSEL0

 

 

 

 

 

Cavalier J1 et J2 du HC11

Mode description

HPRIO

MODB

MODA

RBOOT

SMOD

MDA

1

0

Single chip

0

0

0

1

1

Etendu

0

0

1

0

0

Bootstrap

1

1

0

0

1

Test

0

1

1

Rq : en mode étendu les ports B et F deviennent des bus d’adresse

 

1.15.1.2               Registre BAUD ($102B)

Définit la vitesse de transmission :

 

 7

Bit 6

5

4

3

2

1

 0

TCLA

SCP2

SCP1

SCP0

RCFB

SCR2

SCR1

SCR0

·        bit 6 5 t 4 :  prédivision 

SCP[2 :0]

Divise horloge interne par

Sortie ( Quartz = 16Mh)

X00

1

250000 bauds

001

3

83333 bauds

X10

4

62500 bauds

X11

13

19200 Bauds

101

9

---

·        bit 2 1 0 : selection du baud rate

SCR[2 :0]

Division par

Divise horloge 4800

Divise horloge 9600

Divise horloge 19200

Divise horloge 76800

000

1

4800

9600

19200

38400

001

2

2400

4800

9600

19200

010

4

1200

2400

4800

9600

011

8

600

1200

2400

4800

100

16

300

600

1200

2400

101

32

150

300

600

1200

110

64

75

150

300

600

111

128

---

75

150

300

Exple 19200 Bauds : $30 : 0011 0000

            2400 Bauds : $33 : 0011 0011

 

1.15.1.3               Registre SCCR1($102C)

Format du mot en reception/emission :

 

 7

Bit 6

5

4

3

2

1

 0

R8

T8

 

M

WAKE

 

 

 

·        Bit 7 : 0 = reception en mode 8 bits

·        Bit 6 : 0 = transmission en mode 8 bits

·        Bit 4 : 0 = 1 bits de départ, 8 bits de data, 1 bit de stop

·                  1 = 1 bits de départ, 9 bits de data, 1 bit de stop

·         

Exple 8 bits : $00

 

1.15.1.4               Registre SCCR2 ($102D)

Contrôle : interruption, autorisation…

 

 7

Bit 6

5

4

3

2

1

 0

TIE

TCIE

RIE

ILIE

TE

RE

RWU

SBK

·        Bit 7 : TIE : 0 = interruption désactivées

·        Bit 6 : TCIE : 1 = interruption SCI requise quand le TC est positionné

·                             0 = interruption désctivée

·         

 

Exple 

 

1.15.1.5               Registre SCSR ($102E)

Etat registre de transmission vide.

 

 7

Bit 6

5

4

3

2

1

 0

TDRE

TC

RDRF

IDLE

OA

NF

FE

 

Exple 

 

1.15.1.6               Registre SCDR ($102F)

Données en Emission et transmission

 

 7

Bit 6

5

4

3

2

1

 0

 

 

 

 

 

 

 

 

Exple 8 bits : $00

 

1.16                   Principe de communication :

Lorsqu'un mot est reçu, l'indicateur RDRF (registre de réception plein) du registre d'état SCSR passe à 1. Une lecture du registre SCSR, suivie d'une lecture du SCDR permet de "récupérer" le mot, tout en mettant l'indicateur RDRF à zéro.

Lorqu'un mot à été transmis, l'indicateur TDRE (registre de transmission vide) du SCSR passe à 1. Une lecture du SCSR, suivie d'une écriture dans le SCDR (pour une nouvelle transmission) repositionne l'indicateur TDRE à zéro.

Le test d'un indicateur peut se faire de la façon suivante:
BRCLR SCSR TDRE Label
ce qui signifie : brancher à Label si le bit TDRE du registre SCSR est à zéro.

L'écriture ou la lecture du registre SCDR se fait de façon classique:
LDAA #Donnée
STAA <SCDR
ce qui signifie : charger l'accumulateur A (en immédiat) avec la valeur Donnée, puis sauver son contenu (en direct) dans le registre de transmission SCDR.

Il y a 5 sources possibles d'interruptions. Les plus utilisées sont:
l'interruption de transmission (TIE),lorsque le registre de transmission est vide,
l'interruption de réception (RIE),( lorsque le registre de réception est plein,
Toutes les interruptions renvoient à un seul vecteur $FFD6-$FFD7, ce qui peut contraindre à devoir identifier la source de l'interruption par tests successifs des différents indicateurs du registre d'état.

 

1.17                   Les programmes

1.17.1.1               Exemple de lecture des données venant sur le port série du 68HC11 :

SCI_RCS.ASC 

1.17.1.2               Exemple d’émission de données sur le port série du 68HC11 :

 SCI_SND.ASC

1.17.1.3               Combinaison des deux programmes précédents pour lire une valeur sur le port série et la renvoyer au PC :

SCI_TXRX.ASC

 

 

 

Dans le cas de la connexion d’un composant externe, il faut faire passer le 68HC11 en mode étendu de façon à ce que les ports F, B et C soient utilisées comme bus d’adresse (octets de poids faible et fort) et bus de données (sur 8 bits), et pour faire fonctionner le signal d’écriture R/W#. Cette opération se fait de façon logicielle : en effet, il nous faut tout d’abord être en bootstrap mode pour charger le programme en RAM interne du 68HC11 avant de pouvoir accéder à la RAM externe.

Le branchement de la RAM se fait facilement en reliant les bus d’adresse et de données et, pour éviter les risques de conflit avec les mémoires internes, nous avons relié les signaux d’adresse 13 et 14 aux signaux d’activation de la RAM pour faire commencer l’espace adressable de celle-ci à 0x2000.

1.18                   Les registres

1.18.1.1               Registre HPRIO ($103C)

Définit le mode des ports B et F : en adressage ou en ports normaux (sortie)

 

 7

Bit 6

5

4

3

2

1

 0

RBOOT

SMOD

MDA

IRV

PSEL3

PSEL2

PSEL1

PSEL0

 

 

Switch 1 et 2
Etat
HPRIO
Switch 1
Switch 2
RBOOT
SMOD
MDA
1
0
Single ship
0
0
0
1
1
Etendu
1
0
1
0
0
Bootstrap
1
1
0
0
1
Test
1
1
1
 
 
 

1.19                   Montage

Adaptation pour relier une RAM de 32K (62256) :

1        relier les broches 1 et 26 de la RAM pour faire commencer l’espace areessable $2000

2        relier les broches 20 et 22 de la RAM a la masse pour l’activer.

 

 

1.20                   Exemple de programme

 

1.20.1                    Acquisition du convertisseur numérique, stockage en RAM et envoi des résultats par SCI

 

1.20.1.1               Le programme

 

RAMCAN.ASC

 

1.20.1.2               Principe

 

Branchement d’un potentiometre (0 a 5V) sur le CAN patte 7 du HC11

Lancement du programme RAMCAN.ASC : debut de l’enregistrement des variations de tensions appliquées à l’entrée du CAN

Récupération des données dans un fichier (1.txt)  par HyperTerminal (2400 , 8 , 1) lorsque la touche « SPACE » du clavier est pressée .

Conversion des données avec ASCII.EXE en numérique (0 a 255) et échelonnée [0 5]V (2.data).

Utilisation de GnuPlot  et fichier Gnu configuré pour le 68HC11  pour restituer la courbe de chargement.

 

1.20.1.3               Résultat

 

 

 

 

 

 

 La sélection de l’esclave à qui le message est envoyé se fait par l’activation de SS# qui, au lieu d’être connectée à la masse, est reliée à une broche du port B. Dans notre exemple où nous avons simplement un maître envoyant un message à un seul esclave, nous avons directement reliés SS# de l’esclave à la masse. Les autres connexions consistent à relier directement MOSI, MISO et SCK (signal d’horloge) ainsi que les masses des HC11 communiquant entre eux.

Les programmes qui suivent ont pour but de tester la communication SPI : le maître émet dans un premier temps les nombres de 0 à 255 sur le port SPI (et sur son port A pour vérification) et l’esclave affiche sur son port A les valeurs lues. Les deux afficheurs connectées aux ports A de sortie du maîitre et de l’esclave doivent montrer les mêmes valeurs. Dans un deuxième temps, le maître lit des valeurs sur le port série et les affiche sur son port A tout en les transmettant à l’esclave. Ce second programme permet de vérifier qu’il est possible d’utiliser simultanément la communication RS232 et SPI qui sont toutes deux connectés au port D du maître.

 

1.20.1.4               Master : émission des nombres de 0 à 255 sur le port SPI (D) et écho sur le portA.

(spi_master.asm)

0000 8E 00 lds #0h00FF

0003 CE 10 ldx #0h1000

0006 86 FF ldaa #0hFF ; set port A for output

0008 A7 01 staa 0h01,x

000A 96 2F ldaa 0h2F ; SS# hi, SCk lo, mosi hi

000C A7 08 staa 0h08,x ; store port D

000E 86 38 ldaa #0h38 ; - - 1 1 1 0 0 0

0010 A7 09 staa 0h09,x

0012 86 57 ldaa #0h57 ; 7=0111 : polarity, phase, rate1, rate0

; 5=0101 : int, enable, open drain, master

0014 A7 28 staa 0h28,x ; set SPCR

0016 86 00 ldaa #0h00 ; start : counter=0

0018 A7 2A snd: staa 0h2A,x ; send datum

001A A7 00 staa 0h00,x

001C E6 29 wait: ldab 0h29,x

001E 2A FC bpl wait ; wait until xfer finished

0020 BD 00 jsr delay

0023 4C   inca

0024 20 F2 bra snd

0026 18 CE delay: ldy #0hFFFF

002A 18 09 wait_d: dey

002C 26 FC bne wait_d

002E 39   rts

 

1.20.1.5               Slave : réception des signaux sur le port SPI et affichage sur le port A

(spi_slave.asm)

0000 8E 00 FF lds #0h00FF

0003 CE 10 00 ldx #0h1000

0006 96 2F ldaa 0h2F ; SS# hi, SCk lo, mosi hi

0008 A7 08 staa 0h08,x ; store port D

000A 86 38 ldaa #0h38 ; - - 1 1 1 0 0 0

000C A7 09 staa 0h09,x ; store DDRD

000E 86 47 ldaa #0h47 ; 7=0111 : polarity, phase, rate1, rate0

; 5=0101 : int, enable, open drain, master

0010 A7 28 staa 0h28,x ; set SPCR

0012 86 FF ldaa #0hFF

0014 A7 01 staa 0h01,x ; port A for output

0016 86 88 ldaa #0h88

0018 A7 00 staa 0h00,x ; show 88 on port A while waiting

001A rcv:

001A E6 29 wait: ldab 0h29,x

001C 2A FC bpl wait ; wait until xfer finished

001E A6 2A ldaa 0h2A,x ; send datum

0020 A7 00 staa 0h00,x

0022 20 F6 bra rcv

 

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

(spi_master2.asm)

0000 8E 00 FF lds #0h00FF

0003 CE 10 00 ldx #0h1000

0006 86 FF ldaa #0hFF ; set port A for output

0008 A7 01 staa 0h01,x ; SPI SETUP

000A 96 2F ldaa 0h2F ; SS# hi, SCk lo, mosi hi

000C A7 08 staa 0h08,x ; store port D

000E 86 38 ldaa #0h38 ; - - 1 1 1 0 0 0

0010 A7 09 staa 0h09,x

0012 86 57 ldaa #0h57 ; 7=0111 : polarity, phase, rate1, rate0

; 5=0101 : int, enable, open drain, master

0014 A7 28 staa 0h28,x ; set SPCR ; SERIAL PORT SETUP

; bset 0h28,X,#0h20 ; ne fontionne pas si D port en open-drain

0016 6F 2C clr 0h2c,x

0018 CC 33 0C ldd #0h330C ; set baudrate of serial port to 2400 baud, N81

001B A7 2B staa 0h2B,x

001D E7 2D stab 0h2D,x

001F 1F 2E 20 FC rs_rc: brclr 0h2E,x,#0h20,rs_rc; receive from RS232

0023 E6 2F ldab 0h2F,x

0025 E7 2A snd: stab 0h2A,x ; send datum to SPI

0027 E7 00 stab 0h00,x

0029 E6 29 wait: ldab 0h29,x

002B 2A FC bpl wait ; wait until xfer finished

002D 20 F0 bra rs_rc

 

 

 

La gestion d'afficheur BCD nécessite généralement des composants appropriés (4029 Cmos ou TTL...) qui gère la transformation binaire --> 7 segments.

Ici l'incrémentation s'effectue grâce à une table indexé par le registre Y

Le montage proposé est le suivant:

 

 

Dans l'exemple suivant on réalise une temporisation sur 3 afficheurs (2 pour les seconde et 1 pour les minutes) declenché lorsque la patte 7 du portA est à 0 et réinitialisé à 0 lorsqu'elle est mise à 1 ( avec un délai de 1 à 2 secondes ).

(Chaise0.asm=

 

 

 

1.21                   Compteur

1.21.1                    Les registres 

1.21.1.1               Registre PACNT  $1027

Compteur 8 bits de lecture et écriture

7

6

5

4

3

2

Bit 1

Bit 0

DDRA7

PAEN

PAMOD

PEDGE

DDRA3

I4/O5

RTR1

RTR0

Le PA (pulse accumulator ) peut servir de compteur d'évènement en mesurant selon le

mode programmé soit le nombre de transition de 0 à 1 soit de 1 à 0 .

Le choix s'effectue selon le mode suivant :

PMOD (patte 5 portA )

PEDGE (patte 4 portA )

PA (patte 7 portA )

0

0

PA change de 0 à 1

0

1

PA change de 1 à 0

L'entrée s'effectue sur la patte 7 du portA DDRA7 ( déclarée en entrée )

Pour utiliser la fonction de compteur, il faut mettre PAEN à 1.

On recupère le résultat sur le registre PACTN que l'on redirige vers un port de sortie afin de visualiser le résultat

 

1.21.1.2                Registre TMSK2  $1024

Maskage des interruptions

7

6

5

4

3

2

Bit 1

Bit 0

TDE

RTII

PA0VI

PAII

 

 

PR1

PR0

 

1.21.1.3                Registre TFLG2  $1025

Maskage des interruptions

7

6

5

4

3

2

Bit 1

Bit 0

TDF

RTIF

PAOVF

PAIF

 

 

 

 

 

1.21.2                    Les Interruptions :

 L'accumulateur d'impulsions peut générer 2 interruptions:
- front sur l'entrée PAI (vecteur $FFDA-$FFDB)
- dépassement de capacité (vecteur $FFDC-$FFDD)

Dans le cas d'une utilisation en décompteur (avoir une information au bout de n impulsions), la technique de programmation est la suivante:
- charger le PACNT avec $FF-n
- tester l'indicateur de dépassement de capacité PAOVF ou utiliser l'interruption de dépassement de capacité.

La borne PAI peut aussi être utilisée:
- en tant qu'entrée fonctionnant sur front montant ou descendant ( par test de l'indicateur PAIF mis à 1 sur le front actif),
- en tant qu'entrée d'interruption externe, de la même façon que la borne IRQ*, mais avec l'avantage de fonctionner au choix sur front montant ou descendant ( IRQ* ne peut être configurée que sur front descendant).

L'effacement des indicateurs PAOVF et PAIF se fait par écriture d'un 1 logique au niveau de leur emplacement dans le TFLG2.

 

1.21.2.1               Compteur d’evenement

Le compteur est incrémenter à chaque transition de 0 à 1 de PA7, resultat sur port B.

( Compteur .asm)

 

**********************************

** **

** COMPTEUR D'IMPULSION **

** **

**********************************

;Impulsion sur patte 7 PORTA

;Resultat du comptage sur portB

;incrementation par transition 0-->1 de la patte 7

 

PORTA         equ         $00

PORTB         equ         $04

DDRA           equ         $01

PACNT         equ         $27

PACTL         equ          $26

 

                      org $fe00

 

init:       lds    #$0250                           ;pile

            ldx    #$1000                           ;offset

 

            ldaa #$00

            staa PACNT,x                        ;init registre resultat

            staa DDRA,x                           ;port A en sortie

            ldaa #$50                               ; #% 0101 0000 : init PA (PAEN) et PA sur front ( 0 > 1)

            staa PACTL,x

 

;bset PACTL,x,#$60 ;PAEN=1 PMOD=0 PEDG=1

 

toto:     ldab PACNT,x                        ;resultat du compteur

            stab PORTB,x                         ; sur PORT B

            bra  wait

 

deb:     bra toto                                  ; boucle début pgm

 

wait:     ldy #$ff00                               ; tempo

            dey

            bne wait

            rts

 

 

 Avec Emulateur du MC68HC711D3 de MECALOGIC Concept.
***********************************************
* Essai du TIMER (pulse accumulator). A.P. octobre 1994.
* Fronts à comptabiliser sur borne PA7(22). L'afficheur s'incrémente toute les 10 impulsions
* sur PA7.
* Equivalences globales:
PACTL EQU $0026 Registre de contrôle du pulse accumulator
TFLG2 EQU $0025 Registre d'indicateur d'interruption
TMSK2 EQU $0024 Registre de masquage des interruptions
PACTN EQU $0027 Compteur du pulse accumulator
PORTC EQU $0003
DDRC EQU $0007
INDEX EQU $0040 Mémoire temporaire
ORG $F000
* Initialisation
Reset SEI Masquer les interruptions
LDAA #%01000000 Pulse accumulator autorisé PAEN=1
* PA7 en entrée DDRA7=0 (PAI). Incrémentation sur front descendant PADMOD=0 et PEDGE=0
STAA <PACTL
LDAA #%00100000 Interruption autorisées (PAOVI=1)
STAA <TMSK2
LDAA #10 Dix fronts descendants à détecter
NEGA Complément à 2
STAA <PACTN
LDAA #$FF
STAA <DDRC Port PC0 en sortie
* Programme principal
CLR PORTC
LDX #TABLE Valeur première donnée (chiffre"0").
STX <INDEX
CLI Lever le masque d'interruptions
BRA * Boucle sans fin
* Le compteur est donc chargé avec $F6 (complément à 2 de 10). Lorsqu'il reçoit la dixième
* impulsion, il passe de $FF à $0 et une interruption par overflow est générée.
* Programme d'interruption
Inter LDAA #$F0 Raz de l'indicateur PAOVF par mise
STAA <TFLG2 à 1 du bit correspondant
LDAA #10 Nouveau chargement du compteur
NEGA
STAA <PACTN
LDX <INDEX
LDAB <0,X
STAB <PORTC Donnée sur Port C.
INX Donnée suivante.
STX <INDEX
CPX #TABLE+10 Fin de table de données?
BNE Fin
LDX #TABLE Valeur première donnée (chiffre"0").
STX INDEX
Fin RTI
* Table de conversion Port C - Afficheur ("0"=$7E,"1"=$30...).
TABLE FCB $7E $30 $6D $79 $33 $5B $5F $70 $7F $7B
*Vecteurs ORG $FFDC Vecteur d'interruption
FDB Inter Pulse Accumulator Overflow
ORG $FFFE Vecteur de démarrage
FDB Reset
* Mode opératoire : [V],[D],^I,[O],[I],[C],[U],[O],[R],[H]
END Fin du listing.

REMARQUE :

·                    Si le compteur /Timer déborde ( parvient à $FF ) il met le bit POVF du registre TFLG2 à 1.

·                    Si le bit POVI du registre TMSK2 est écrit à 1, une interruption est déclenché lors du débordement (POVF = 1 ). L'addresse de l'interruption est $FFDC est doit être déclaré dans le programme.

·                    Si une transition du compteur arrive sur PA, le bit PAIF du registre TFLG2 est mis à 1

·                    Si le bit PAII du registre TMSK2 est écrit à 1, une interruption est déclenché lors d'une transition de PA. L'addresse de l'interruption est $FFDA et doit être déclaré dans le programme., la subroutine remet PAIF à 0 pour permettre une autre interruption )

 

 

1.22                   Timer

La fonction de timer enregistre les périodes ou le PA est soit à 0 soit à 1.

PMOD (patte 5 portA )

PEDGE (patte 4 portA )

PA (patte 7 portA )

1

0

PA mis à 1

0

1

PA mis à 0

L'initialisation (PAEN) et le résultat (PACTN) du timer sont identiques à celle du compteur.

1.22.1.1               Timer quand PA est mis à 0

(Timer.asm)

 

 

 

Adresse en mode normal

Adresse en mode bootstap

Vecteur

$FFD6,$FFD7

$00C4,$00C5,$00C6

SCI

$FFD8,$FFD9

$00C7,$00C8,$00C9

Fin transmission sur la SPI

$FFDA,$FFDB

$00CA,$00CB,$00CC

Front actif sur accu d'impulsion

$FFDC,$FFDD

$00CD,$00CE,$00CF

Débordement sur accu d'impulsion

$FFDE,$FFDF

$00D0,$00D1,$00D2

Débordement TIMER

$FFE0,$FFE1

$00D3,$00D4,$00D5

TOC5

$FFE2,$FFE3

$00D6,$00D7,$00D8

TOC4

$FFE4,$FFE5

$00D9,$00DA,$00DB

TOC3

$FFE6,$FFE7

$00DC,$00DD,$00DE

TOC2

$FFE8,$FFE9

$00DF,$00E0,$00E1

TOC1

$FFEA,$FFEB

$00E2,$00E3,$00E4

TIC3

$FFEC,$FFED

$00E5,$00E6,$00E7

TIC2

$FFEE,$FFEF

$00E8,$00E9,$00EA

TIC1

$FFF0,$FFF1

$00EB,$00EC,$00ED

Itéruption temps réel

$FFF2,$FFF3

$00EE,$00EF,$00F0

IRQ barre

$FFF4,$FFF5

$00F1,$00F2,$00F3

XIRQ barre

$FFF6,$FFF7

$00F4,$00F5,$00F6

SWI

$FFF8,$FFF9

$00F7,$00F8,$00F9

Code Op illégal

$FFFA,$FFFB

$00FA,$00FB,$00FC

COP chien de garde

$FFFC,$FFFD

$00FD,$00FE,$00FF

Surveillance de l'horloge

$FFFE,$FFFF

$BF40,$BF41,$BF42

Reset barre

 

traité par des exemples.

 

 

 

 

 

 

1.23                   Les interruptions matérielles IRQ#

1.23.1                    Aspect matériel

CLI : va rendre les interruptions matérielles actives. Par défaut, toutes les sources internes au 68HC11 d’interruptions matérielles (principalement les timers) sont inactives. L’activation de l’interruption matérielle IRQ se fait alors en mettant cette broche au niveau bas (par exemple en fermant un interrupteur dans notre exemple).

1.23.2                    Aspect logiciel

Principe des pseudo vecteurs : les vecteurs d’interruptions sont situés en ROM et ne sont donc pas modifiables pour pointer vers la fonction de l’utilisateur. Ces vecteurs pointent vers des pseudo vecteurs prédéfinis qui sont eux situées en RAM. Il s’agit en fait de trois octets réservés à l’action à effectuer lorsque l’interruption est déclenchée : une instruction JMP (0x7E) suivi des 2 octets de l’adresse de la fonction de l’utilisateur. 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 à bien identifier la syntaxe permettant de récupérer l’adresse ou se situe une procédure, et de voir comment manipuler cette adresse. Dans le programme ci-dessous, la procédure nommée IRQ commence à l’adresse 0x0026. Nous allons chercher cette adresse, la stocker dans le registre 16 bits X, puis transférer X dans D (qui est en fait la concaténation de A et B) de façon à pouvoir successivement afficher sur le port A les valeurs des registres A et B et ainsi pouvoir visualiser (par exemple sur un afficheur 7 segments connecté au port A) l’adresse de la procédure (cette étape intermédiaire - le passage de X à D - est obligatoire pour pouvoir visualiser la valeur stockée dans X. Il n’est pas possible d’envoyer directement X, qui est sur 16 bits, sur un des ports d’entrée-sortie 8 bits). Il faut prendre soin, lors de la recherche de l’adresse de la procédure irq, d’utiliser la syntaxe ldx #irq qui renvoie l’adresse où se trouve irq (0h0023 dans notre cas), et non pas ldx irq qui renvoie le contenu de l’octet se trouvant à l’adresse irq (0x86 dans notre cas, qui est l’opcode de l’instruction ldaa).

 

1.23.3                    Montage 

 

 

 

 

1.23.4                    Déclenchement d’une interruption :  IRQ

En mode normal  ( cavalier J2 enlevé) : IRQ2.ASC

************************************************************

* Ce programme permet de tester le mode Interruption Physique

* Compteur sur PORTB

* reinitalisation du compteur si appui sur IRQ

************************************************************    

PORTB                  equ          $1004

CNT                       rmb                         1

 

                               org $FE00              

start                        lds #$0150                                                                           

                               ldx #$1000                                                            

                               ldaa #$00                *init port b...

                                staa CNT                *...et variable compteur

                                                                             

                               cli                                                                          

                                                                             

ici                            ldaa CNT               

                               staa PORTB           *resultat sur port b                                                                                                             

                               inca                         *increment le compteur                        

                                staa CNT                                                                                                                              bsr delai                  *tempo compteur  

                               bra ici                      *boucle                  

                                                              

***boucle tempo***                                                                           

delai                        ldy #$C000

wait                        dey

                               bne wait

                               rts 

 

***sous pro d'interruption***                                                                           

reinit                       ldaa #$00                * reinit la variable compteur

                               staa CNT               

                               staa PORTB                                         

                               rti

 

***vecteur d'interruption IRW ***

                               org  $FFF2                             * vecteur de IRQ

irqvect     fdb          reinit

                                                                             

                               end

 
 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


En mode Bootstrap (cavalier J2 en place ) : IRQ.ASC

1.      Autorisé les interruptions par : CLI

2.      Initialiser le pointeur de pile sur un adresse ne RAM ou seront sauvegardé les registres durant l’interruption : LDS #$00FF

3.      Charger le code hexa des commandes dans les adresses des interruptions : les Pseudo-Vecteurs d'interuption sont sur 3 octets, le premier doit contenir le code hexadicimal de l'instruction à éffectuer (ex : $7E pour le JMP).
Les 2 autres doivent contenir l'adresse ou est implanté la routine d'interruption ecrite par l'utilisateur.

 

******************************************************************

* Ce programme permet de tester le mode Interruption Physique en mode bootstrap

* Compteur sur PORTB

* reinitalisation du compteur si appui sur IRQ

******************************************************************

PORTB                  equ                          $1004

IRQ1                      equ                          $00EE

IRQ2                      equ                          $00EF

 

                               org $FE00              

                               cli

 

                               lds #$0150

                                                              

                               ldaa #$7E                * opcode de JMP

                               staa IRQ1               * interrupt vector-1=JMP opcode

                                                              

                               ldaa #$00                *init

                               staa IRQ2               *interrupt vector=#$00

                               staa PORTB

                               ldx #irq                   * ISR de IRQ# : ldx irq (opcode de jmp)->                                                                                                                        

                               stx IRQ2                 * interrupt vector

                                                              

                               ldx #$1000                                                

                        ldaa $00E0

                               inca

                               staa $00E0                                                                           

                               staa PORTB                                                                        

                               bsr delai

                               bra ici

                                                                             

irq                           ldaa #$00                               

                               staa $00E0

                               rti

                                                                             

delai                        ldy #$F000

wait                        dey

                               bne wait

                               rts 

                                                          

                        end

 
 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


Exple IRQ : adresse $00EE $00EF $00F0

ldaa #$7E                                * opcode de JMP

staa $00EE                              * sur le 1ere adresse de IRQ

ldx #irq                                    * ISR de IRQ                                                                        

stx $00EF                               *sur la 2eme adresse de IRQ

             

1.24                   Les interruptions matérielles liées aux timers : RTI.

L’utilisation du compteur présentée ici permet de réaliser un scheduler lorsque plusieurs tâches doivent être exécutées séquentiellement avec une périodicitée donnée, ou une modulation en largeur de pulse (PWM). Dans le but d’avoir le temps de voir le compteur osciller, nous avons décidé d’abaisser la fréquence du timer au 16 ème de sa valeur par défaut en mettant PR1 et PR0 du registre TMSK2 (0h1024) à 1. Le compteur va de 0 à 65536 en 524.3/2 ms (i.e. 4 µs par tic d’horloge). On le fait compter de 1 à 0hDFFF=53248+3840+240+15=57343 soit 229.4 ms entre deux incréments du compteur. La valeur du compteur, incréementé à chaque interruption, est affichée sur les ports A et B. La broche 6 du port A oscille de plus à la fréquence des interruptions (sortie PWM).

0000 8E 00 FF lds #0h00FF ; stack

0003 86 FF ldaa #0hFF ; set port A for output

0005 B7 10 01 staa 0h1001 ; | on affiche cpt val sur A et B, et A6=PWM

0008 86 7E ldaa #0h7E ; opcode de JMP

000A 97 DC staa 0h00DC ; interrupt vector of OC2

000C CE 00 2E ldx #int ; ISR de int

000F DF DD stx 0h00DD ; interrupt vector+1 de OC2 = int @

0011 CE 10 00 ldx #0h1000

0014 1C 24 03 bset 0h24,x,#0h03 ; prescaler : ici, divise la vitesse par 16

0017 86 40 ldaa #0h40 ; only work on OC_2_

0019 A7 23 staa 0h23,x ; clear any pending flag

001B A7 22 staa 0h22,x ; enable OC2 interrupt

001D 86 40 ldaa #0h40 ; intOC2 : 0h00 -> do not affect port A pin

001F A7 20 staa 0h20,x ; 0h40 -> toggle output of port A6 on int

0021 86 00 ldaa #0h00 ; initialisation du compteur

0023 97 E0 staa 0h00E0 ; octet en RAM stockant la valeur a afficher

0025 0E cli ; enable interrupts : check pull ups on IRQ & XIRQ

0026 96 E0 ici: ldaa 0h00E0

0028 A7 04 staa 0h04,x ; display counter value on port B

002A A7 00 staa 0h00,x ; display counter value on port A

002C 20 F8 bra ici

002E 96 E0 int: ldaa 0h00E0 ; PAS inca directmt car rti pop regs

0030 4C inca ; incremente le compteur

0031 97 E0 staa 0h00E0 ; stocke le result

0033 CC DF FF ldd #0hDFFF ; 1/2 delay PWM <- duree entre 2 transitions

0036 E3 12 addd 18,x ; add value of counter 2 to delay

0038 ED 12 std 18,x ; store in counter -> time of next interrupt

003A 86 40 ldaa #0h40

003C A7 23 staa 0h23,x ; clear flag by setting 0100 0000 (OC2)

003E 3B rti

 

 

 

Jusqu’ici, nos programmes n’étaient capables que d’effectuer une opération à la fois : soit faire l’acquisitions de données provenant les convertisseurs analogiques-numériques, soit transmettre des données sur le port série, soit attendre la réception de données sur le port RS232. L’utilisation des interruptions dans l’exemple qui suit va donner l’impression que le 68HC11 est capable de simultanément incrémenter un compteur de fac¸on périodique tout en étant à l’écoute du port série. De plus, mettre toutes les fonctions à exécuter par le microcontroleur sous interruption permet une économie d’énergie par l’éxécution de l’instruction WAI lorsque qu’aucune tâche n’est à exécuter. Cette instruction met le 68HC11 en mode veille qui consomme moins de courant. Le microcontroleur est réactivé lorsqu’un interruption qui à été autorisée (dans notre cas le timer, la réception d’un message sur le port série ou l’activation de l’interruption matérielle sur la broche IRQ) est déclenchée.

1.24.1                     Déclenchement d’une interruption : SCI

1.24.1.1               Interruption déclenchée à la réception d’un caractère sur le port série

En mode bootstrap    :           IRQSCI.ASC

En mode normal        :           IRQSCI2.ASC

 

1.24.2                    Déclenchement d’une interruption :  TIMER

1.24.2.1               Exemple de combinaison des interruptions timer

 (incrément du compteur) et de réception sur le port série. Noter que la procédure principale est uniquement formée d’une boucle sur la fonction WAI dont l’intérêt est l’économie de courant.

IRQTIM.ASC

 

1.24.3                    Aplications :

 

On reprend le probleme n°9 gestion de 2 feux et on rajoute un feu clignotant orange pour tourner a droite lorsque le feu 1 est vert. Le clignotement du feu orange se fait par l'interruption temps reel (RTI). On autorise son clignotement que lorsque le feu 1 est vert.

 

Le problème se situe sur le clignotement du feu orange.
La RTI est une interruption qui arrive régulièrement dans le temps. Chaque fois qu'elle se présente on exécute le programme D'interruption associé.
Le vecteur d'interruption est à l'adresse : $FFF0 $FFF1

1.24.3.1               Registre PACTL bits RTR0, RTR1 :déterminent la période d'interruption

Pulse Accumulator Control Register (PACTL $1026)

7

6

5

4

3

2

Bit 1

Bit 0

DDRA7

PAEN

PAMOD

PEDGE

DDRA3

I4/O5

RTR1

RTR0

RTR[1:0] — RTI Interrupt Rate Select :

Ces deux bits determinent l'intervalle de temps entre deux interruptions RTI.
Ce temps est pilote par la division de l'horloge E/213. Cette horloge est independante de l'horloge TIMER 'voir exo suivant). La combinaison de ces deux bits permet la division selon le tableau ci-dessous. 1

 

RTR[1:0]

E = 3 MHz

E = 2 MHz

E = 1 MHz

E = X MHz

E = 16MHz

0 0
0 1
1 0
1 1

2.731 ms
5.461 ms
10.923 ms
21.845 ms

4.096 ms
8.192 ms
16.384 ms
32.768 ms

8.192 ms
16.384 ms
32.768 ms
65.536 ms

(E/2 13 )
(E/2 14 )
(E/2 15 )
(E/2 16 )

1.953 ms
0,9765 ms
 ms
 ms

 

>> Pour obtenir ne période de 32,768 ms, RTR0=1 et RTR1=1

        ldaa    #$03                     ; RTR0=1 ; RTR1=1
        staa    pactl                    ; Horloge 8Mhz t=32.77ms

1.24.3.2               Registre TMSK2 bit 6 RTII autorise l'interruption RTI

Timer Interrupt Mask Register 2 (TMSK2 $1024)

Ce registre contient le bit de validation de l'interruption temps reel.

Bit 7

Bit 6

5

4

3

2

1

 0

TOI

RTII

PAOVI

PAII

-

-

PR1

PR0

RTII — Validation de Real-Time Interrupt
0 = L'interruption est desactive
1 = L'interruption est active, elle sera demande lorsque RTIF (voir TFLG2) est a 1.

>> Autorisation de l'interruption RTI 
 
        bset       tmsk2,x,#$40
 

 

1.24.3.3               Registre TFLG2 bit 6 RTIF indique l'état de l'interruption

Timer Interrupt Flag Register 2 (TFLG2 — $1025)

Ce registre est liee au registre TMSK2, chaque bits de TFLG2 a sa correspondance bit a bit avec TMSK2.
Le bit RTIF passe a un et demande une interruption de type RTI. Il faut le remettre à 0 au depart et à chaque sortie du SP d'interruption.

 

 7

Bit 6

5

4

3

2

1

 0

TOF

RTIF

PAOVF

PAIF

-

-

-

-

 

RTIF — Real-Time Interrupt Flag Le drapeau RTIF est automatiquement mis a 1 a la fin de chaque periode de determine par RTR0 et RTR1.

 Pour le remettre a 0 on ecrit un 1 dans le registre.

        Etat de la RTI Forcage du bit rtif a 0 * 
 
bset    tflg2,x,#$40            * #% 0100 0000 
                                * Permet de remettre le bit RTIF a 0
                                * Chez motorola pour mettre un drapeau a 0
                                      * On le remet avec un 1


       

Resolution du probleme presente par RTI.

*                           feuclign.a11
* (32s) Rouge feu 1/vert feu 2 – 
* (4s) Rouge feu 1/Orange feu 2 – 
* (2s) Rouge feu 1/Rouge feu 2 
* (32s) Vert feu 1/Orange 2 clignotant/Rouge feu 2 – 
* (4s) Orange1 feu 1/Rouge feu 2 – 
* (2s) Rouge feu 1/Rouge feu 2 
* Gestion D'un seul feu
* Feu tricolore 1 sur portB Feu rouge bit 2, orange bit 1 et vert bit 0.
* Feu tricolore 2 sur portB Feu rouge bit 7, orange bit 6 et vert bit 5.
 
* R  O  V  OC    R  O  V
* 7  6  5  4  3  2  1  0  : PORT B
* 8  4  2  1  8  4  2  1
 
portb          equ            $04
pactl          equ            $1026
tmsk2          equ            $24
tflg2          equ            $25
 
 
* Constantes
 
dureev         equ            32
dureeo         equ            4
duree2r        equ            2
pile           equ            $ff
 
*Variables d’adressage :
 
               org            $2000
 
duree          rmb            1        * Parametre contenant la duree en seconde
compt          rmb            1        * Compteur contenant le nombre d'interruption RTI permettant
                                        * de connaitre la duree entre 2 interruptions RTI
 
 
 
*Début du programme implantation en EEPROM
 
               org            $FE00
 
********************
*   Configuration        
********************
* Pile
 
start          lds            #$00ff
 
* Initilisation de Y pour adressage indexé specifique aux instructions BSET BCLR BRSET BRCLR
 
 
               ldy            #$1000
 
*Initialisation de la RTI
**************************
 
* Horloge 8Mhz RTR0=RTR1=1 t=32.77ms
 
 
               ldaa           #$03
                staa           pactl         
 
* Etat de la RTI Forcage du bit rtif a 0 *
 
               
               bset            tflg2,y,#$40     * Ce bit indique l'etat de la RTI
 
* Chez Motorola pour remettre à zero les flag on met un 1 d'ou l'utilisation de BSET ci-dessus
 
 
* Autorisation des interruptions Générales masquable par I du CCR
 
 
               cli
 
 
********************
*Programme principal  
********************
* allumage du feu rouge feux 1 et vert feux 2.
 
debut          ldaa           #$81           ; 1000 0001 
               staa           portb,y
 
* tempo de 32 secondes
 
               bsr            tempo32
 
* allumage du feu rouge feux 1 et feu orange feux 2
 
               ldaa           #$82          ; 1000 0010
               staa           portb,y
 
* tempo de 4 secondes
 
               bsr            tempo4
 
* allumage du feu rouge feux 1 et feu rouge feux 2
 
               ldaa           #$84
               staa           portb,y
 
* tempo de 2 secondes 
 
               bsr            tempo2
 
* allumage du feu vert feux 1 et rouge feux 2.
 
               ldaa           #$24
               staa           portb,y
 
* Autorisation de l'interruption RTI *
 
               bset           tmsk2,y,#$40
 
* tempo de 32 secondes
 
               bsr            tempo32
 
* allumage du feu orange feux 1 et feu rouge feux 2
 
               ldaa           #$44
               staa           portb,y
 
* inibition de l'interruption RTI *
 
                bclr           tmsk2,y,#$40
 
* tempo de 4 secondes
 
               bsr            tempo4
 
* allumage du feu rouge feux 1 et feu rouge feux 2
 
               ldaa           #$84
               staa           portb,y
 
* tempo de 2 secondes 
 
               bsr            tempo2
               bra            debut
 
*****************
* Sous programmes  *
*****************
 
*Sous programmes tempo32
**********************
 
* duree de temporisation de 32 secondes
 
tempo32        ldaa           #dureev
               staa           duree
               bsr            tempo
               rts
 
*Sous programmes tempo4
*********************
* duree de temporisation de 4 secondes
 
tempo4         ldaa           #dureeo
               staa           duree
               bsr            tempo
               rts
 
*Sous programmes tempo2
**********************
* duree de temporisation de 2 secondes
 
tempo2         ldaa           #duree2r
               staa           duree
               bsr            tempo
               rts
 
 
*Sous programme tempo*
********************
 
* lecture du paramètre duree determinant la duree de la tempo en seconde
 
tempo          ldaa           duree
 
* on effectue 10 boucles de 100 ms
 
tduree         ldab           #10
 
* Duree de base de 100ms par decrementation de X qui dure 3µs*33333=99999µs
 
t1s            ldx            #33333
t100ms         dex
               bne            t100ms
 
* fin de la boucle 100ms
 
               decb
               bne            t1s
 
*fin de la boucle 1s
 
               deca
               bne            tduree
 
*fin de la duree fois 1s
 
               rts
 
********************************
* Sous programmes interruption*
********************************
 
* SP RTI *
**********
 
orange         inc            compt
 
* 23 (23*32,768 = 754ms) fois la RTI (1/2 periode de clignotement) ?
 
               ldaa           compt
               suba           #23
               bne            fin     *sortir de la rti duree inferieure a 754 ms depuis le dernier
                                      *changement du feu orange clignotant
              
* Test s'il faut eteindre ou allumer le feu orange clignotant               
 
               ldaa           portb,y
               bita           #$10          ; 0001 0000 : si ORANGE allumé
               beq            inv           ; ...alors
 
* On eteint le feu orange clignotant
 
               bclr           portb,y,#$10  ; ...eteint ORANGE
               bra            suite
 
* On allume le feu orange clignotant
 
inv             bset           portb,y,#$10      ; ...allume ORANGE
 
*RAZ compteur pour compter de nouveau un temps de 754ms
 
suite          clr           compt
 
* rtif=0 pour revenir en rti 32.77ms apres
 
fin            bset           tflg2,y,#$40     
 
               rti
 
***************************
* Vecteurs d'interruptions
***************************
*vecteur Real time interrupt 
 
 
               org            $fff0
rtivect        fdb            orange
 
 
 
*vecteur de reset 
 
               org     $fffe
rstvect        fdb     start

                               end

 

 

Même probleme avec l'elaboration des tempo des feux par debordement de timer

L'avantage de l'utilisation du timer est :

Sa precision pouvant atteindre 0,5µs (pas exploite ici mais dans le chapitre suivant).

L'utilisation en interruption permet d'effectuer d'autres taches au lieu d'attendre que le temps passe. Le TIMER est la partie la plus vaste du HC11.
Ici on utilise le débordement du Timer, on ne presentera que cette partie du timer.

 

 

·  Les bit PR0 et PR1 permettent de prediviser l'horloge par 1, 4, 8, ou 16, ainsi le compteur TCNT peut être cadence par E, ou E/4 E/8 ou E/16. Ce prediviseur doit etre programme durant les 64 premiers clock d'horloge pour etre pris en compte. La predivision donne la precision du compteur. Pour 8Mhz ce dernier est incremente toutes les 500 ns, 2µs, 4µs ou 8µs selon la combinaison de PR[0:1]

·  Le compteur TCNT est un compteur qui n'est jamais arrete. On peut le lire mais pas l'arreter, pas le forcer a zero ou autres valeurs.

·  Lors du debordement du compteur (Passage de $FFFF a $0000) le bit TOF est mis a 1. On peut remetre ce bit a zero.

1.24.3.4               Registre TMSK2

bit 7 TOI autorise l'interruption Debordement Timer
Bit 0 et 1 predivision de E

Timer Interrupt Mask Register 2 (TMSK2 $1024)

Bit 7

6

5

4

3

2

1

Bit 0

TOI

RTII

PAOVI

PAII

-

-

PR1

PR0

 

 

 

 

 

 

 

 

 

PR[1:0]

Predivision

0 0
0 1
1 0
1 1

1
4
8
16

TOI — Validation de Timer Overflow
0 = L'interruption est desactive
1 = L'interruption est active, elle sera demande lorsque TOF (voir TFLG2) est a 1.

1.24.3.5               Registre TFLG2 bit 7 TOF indique l'état de l'interruption

Timer Interrupt Flag Register 2 (TFLG2 — $1025)

Ce registre est liee au registre TMSK2, chaque bits de TFLG2 a sa correspondance bit a bit avec TMSK2.
Le bit TOF passe a un et demande une interruption de type TO. Il faut le remettre à 0 au depart et à chaque sortie du SP d'interruption.

 

Bit 7

6

5

4

3

2

1

Bit 0

TOF

RTIF

PAOVF

PAIF

-

-

-

-

 

TOF — Timer Overflow Flag Le drapeau TOF est automatiquement mis a un a la fin de chaque periode de determine par RTR0 et RTR1. Pour le remettre a zero on ecrit un 1 dans le registre.

Adresse du vecteur d'interruption

$FFDE et $FFDF

Organigrammes de fonctionnement

 

 

 

* fichier feutimer.asc

* Gestion des tempos par timer
* (32s) Rouge feu 1/vert feu 2 – 
* (4s) Rouge feu 1/Orange feu 2 – 
* (2s) Rouge feu 1/Rouge feu 2 
* (32s) Vert feu 1 Orange2 clignotant/Rouge feu 2 – 
* (4s) Orange1 feu 1/Rouge feu 2 – 
* (2s) Rouge feu 1/Rouge feu 2 
* Gestion D'un seul feu
* Feu tricolore 1 sur portB Feu rouge bit 2, orange bit 1 et vert bit 0.
* Feu tricolore 2 sur portB Feu rouge bit 7, orange bit 6 et vert bit 5.
 
* R  O  V  OC    R  O  V
* 7  6  5  4  3  2  1  0 
* 8  4  2  1  8  4  2  1
 
*Equivalences registres
 
portb            equ            $04
pactl            equ            $1026
tmsk2            equ            $24
tflg2            equ            $25
 
*Constantes 
 
dureev           equ            64             * Duree de 64/2 d'allumage du feu vert
dureeo           equ            8              * Duree de 8/2 d'allumage du feu orange
duree2r          equ            4              * Duree de 4/2 d'allumage du feu rouge
pile             equ            $ff
 
*Variables
 
         org            $0000
duree            rmb            1       * Parametre contenant la duree en seconde
compt            rmb            1       * Compteur contenant le nombre d'interruption RTI permettant
                                        * de conaitre la duree entre 2 interruptions RTI
drapeau          rmb            1       * Drapeau permettant de connaitre l'etat de la tempo
compt1           rmb            1       * Compteur pour la tempo
 
*Début du programme implantation en EEPROM
 
         org            $FE00
 
********************
*   Configuration        
********************
 
*initialisation de la pile
 
start            lds            #pile
 
* Initilisation de Y pour adressage indexé specifique aux instructions BSET BCLR BRSET BRCLR
 
         ldy            #$1000
 
* Init Timer
************
 
*Predivision du timer avant 64 clock d'horloge
*PR0=PR1=1 Predivision par 16 (16*500ns=8µs)
* Autorisation interruption debordement TCNT
 
         bset           tmsk2,y,#$83   *Interruption toutes les 524,28ms
 
*Initialisation de la RTI
**************************
 
* Horloge 8Mhz RTR0=RTR1=1 t=32.77ms
 
         ldaa           #$03
         staa           pactl         
 
* Etat de la RTI Forcage du bit rtif a 0 *
 
         bset            tflg2,y,#$40     * Ce bit indique l'etat de la RTI
 
* Chez Motorola pour remettre à zero les flag on met un 1 d'ou l'utilisation de BSET ci-dessus
 
 
* Autorisation des interruptions Générales masquable par I du CCR
 
         cli
 
*
********************
*Programme principal  
********************
 
* allumage du feu rouge feux 1 et vert feux 2.
 
debut    ldaa           #$81
         staa           portb,y
 
* tempo de 32 secondes
 
         bsr            tempo32
 
* allumage du feu rouge feux 1 et feu orange feux 2
 
         ldaa           #$82
         staa           portb,y
 
* tempo de 4 secondes
 
         bsr            tempo4
 
* allumage du feu rouge feux 1 et feu rouge feux 2
 
         ldaa           #$84
         staa           portb,y
 
* tempo de 2 secondes 
 
         bsr            tempo2
 
* allumage du feu vert feux 1 et rouge feux 2.
 
         ldaa           #$24
         staa           portb,y
 
* Autorisation de l'interruption RTI *
 
         bset           tmsk2,y,#$40
 
* tempo de 32 secondes
 
         bsr            tempo32
 
* allumage du feu orange feux 1 et feu rouge feux 2
 
         ldaa           #$44
         staa           portb,y
 
* inibition de l'interruption RTI *
 
        bclr             tmsk2,y,#$40
 
* tempo de 4 secondes
 
         bsr            tempo4
 
* allumage du feu rouge feux 1 et feu rouge feux 2
 
         ldaa           #$84
         staa           portb,y
 
* tempo de 2 secondes 
 
         bsr             tempo2
         bra            debut
 
*****************
* Sous programmes  *
*****************
 
*Sous programmes tempo32
**********************
 
* duree de temporisation de 32 secondes
 
tempo32  ldaa    #dureev
         staa           duree
         bsr            attente
         rts
 
*Sous programmes tempo4
*********************
* duree de temporisation de 4 secondes
 
tempo4   ldaa    #dureeo
         staa           duree
         bsr            attente
         rts
 
*Sous programmes tempo2
**********************
* duree de temporisation de 2 secondes
 
tempo2   ldaa    #duree2r
         staa           duree
         bsr            attente
         rts
 
*Sous programmes Attente
**********************
* Attente d'interruption
 
attente  ldaa           drapeau
         beq            attente
         clr            drapeau
         rts
 
 
********************************
* Sous programmes interruption*
********************************
 
* SP TIMER Depassement TCTNT *
******************************
 
tempo    inc            compt1         * Tempo de 0,52428 x duree
         ldaa           duree          * Donne le temps 
         suba           compt1         * comparaison de compt1
         bne            fin1           * a Duree
         ldaa           #$01           * Drapeau = 1 fin tempo
         staa           drapeau        * 
         clr            compt1         * Preparation pour tempo suivante
 
* TOF=0 pour revenir en interruption 524,28ms apres
 
fin1             bclr           tflg2,y,#$7F     
 
* On utilise ici bclear au lieu de bset pour ne pas toucher au bit RTIF 
utilise dans la RTI
 
         rti
 
 
* SP RTI *
**********
 
orange   inc            compt
 
* 23 (23*32,768 = 754ms) fois la RTI (1/2 periode de clignotement) ?
 
         ldaa           compt
         suba           #23
         bne            fin     *sortir de la rti duree inferieure a 754 ms depuis le dernier
                                *changement du feu orange clignotant
        
* Test s'il faut eteindre ou allumer le feu orange clignotant         
 
         ldaa           portb,y
         bita           #$10
         beq            inv
 
* On eteint le feu orange clignotant
 
         bclr           portb,y,#$10
         bra            suite
 
* On allume le feu orange clignotant
 
inv      bset           portb,y,#$10
 
*RAZ compteur pour compter de nouveau un temps de 754ms
 
suite    clr           compt
 
* rtif=0 pour revenir en rti 32.77ms apres
 
fin      bclr           tflg2,y,#$BF
 
* On utilise ici bclear au lieu de bset pour ne pas toucher au bit TOF 
utilise dans debordement TIMER interupt
 
         rti
 
 
***************************
* Vecteurs d'interruptions
***************************
*vecteur Timer Debordement TCTNT 
 
         org            $ffde
rstctnt  fdb            tempo
 
*vecteur Real time interrupt 
 
         org            $fff0
rstrti   fdb            orange
 
*vecteur de reset 
 
         org            $fffe
rstvect  fdb            start
 
         end

 

 

 

 

Même probleme avec l'elaboration des tempo des feux par debordement de timer

L'avantage de l'utilisation du timer est :

Sa precision pouvant atteindre 0,5µs (pas exploite ici mais dans le chapitre suivant).

L'utilisation en interruption permet d'effectuer d'autres taches au lieu d'attendre que le temps passe. Le TIMER est la partie la plus vaste du HC11.
Ici on utilise le débordement du Timer, on ne presentera que cette partie du timer.

 

 

·  Les bit PR0 et PR1 permettent de prediviser l'horloge par 1, 4, 8, ou 16, ainsi le compteur TCNT peut être cadence par E, ou E/4 E/8 ou E/16. Ce prediviseur doit etre programme durant les 64 premiers clock d'horloge pour etre pris en compte. La predivision donne la precision du compteur. Pour 8Mhz ce dernier est incremente toutes les 500 ns, 2µs, 4µs ou 8µs selon la combinaison de PR[0:1]

·  Le compteur TCNT est un compteur qui n'est jamais arrete. On peut le lire mais pas l'arreter, pas le forcer a zero ou autres valeurs.

·  Lors du debordement du compteur (Passage de $FFFF a $0000) le bit TOF est mis a 1. On peut remetre ce bit a zero.

Registre TMSK2

bit 7 TOI autorise l'interruption Debordement Timer
Bit 0 et 1 predivision de E

1.24.3.6               Timer Interrupt Mask Register 2 (TMSK2 $1024)

Bit 7

6

5

4

3

2

1

Bit 0

TOI

RTII

PAOVI

PAII

-

-

PR1

PR0

 

PR[1:0]

Predivision

0 0
0 1
1 0
1 1

1
4
8
16

TOI — Validation de Timer Overflow
0 = L'interruption est desactive
1 = L'interruption est active, elle sera demande lorsque TOF (voir TFLG2) est a 1.

Registre TFLG2 bit 7 TOF indique l'état de l'interruption

1.24.3.7               Timer Interrupt Flag Register 2 (TFLG2 — $1025)

Ce registre est liee au registre TMSK2, chaque bits de TFLG2 a sa correspondance bit a bit avec TMSK2.
Le bit TOF passe a un et demande une interruption de type TO. Il faut le remettre à 0 au depart et à chaque sortie du SP d'interruption.

Bit 7

6

5

4

3

2

1

Bit 0

TOF

RTIF

PAOVF

PAIF

-

-

-

-

TOF — Timer Overflow Flag Le drapeau TOF est automatiquement mis a un a la fin de chaque periode de determine par RTR0 et RTR1. Pour le remettre a zero on ecrit un 1 dans le registre.

Adresse du vecteur d'interruption

$FFDE et $FFDF

Organigrammes de fonctionnement

 

Feutimer.asc
 
* Gestion des tempos par timer
* (32s)Rouge feu 1/vert feu 2 – 
* (4s) Rouge feu 1/Orange feu 2 – 
* (2s) Rouge feu 1/Rouge feu 2 
* (32s)Vert feu 1 Orange2 clignotant/Rouge feu 2 – 
* (4s) Orange1 feu 1/Rouge feu 2 – 
* (2s) Rouge feu 1/Rouge feu 2 
* Gestion D'un seul feu
* Feu tricolore 1 sur portB Feu rouge bit 2, orange bit 1 et vert bit 0.
* Feu tricolore 2 sur portB Feu rouge bit 7, orange bit 6 et vert bit 5.
 
* R  O  V  OC    R  O  V
* 7  6  5  4  3  2  1  0 
* 8  4  2  1  8  4  2  1
 
*Equivalences registres
 
portb            equ            $04
pactl            equ            $1026
tmsk2            equ            $24
tflg2            equ            $25
 
*Constantes 
 
dureev           equ            64      * Duree de 64/2 d'allumage du feu vert
dureeo           equ            8       * Duree de 8/2 d'allumage du feu orange
duree2r          equ            4       * Duree de 4/2 d'allumage du feu rouge
pile             equ            $ff
 
*Variables
 
                org             $0000
duree            rmb            1       * Parametre contenant la duree en seconde
compt            rmb            1       * Compteur contenant le nombre d'interruption RTI permettant
                                        * de conaitre la duree entre 2 interruptions RTI
drapeau          rmb            1       * Drapeau permettant de connaitre l'etat de la tempo
compt1           rmb            1       * Compteur pour la tempo
 
*Début du programme implantation en EEPROM
 
                org             $FE00
 
********************
*   Configuration        
********************
 
*initialisation de la pile
 
start    lds            #pile
 
* Initilisation de Y pour adressage indexé specifique aux instructions BSET BCLR BRSET BRCLR
 
         ldy            #$1000
 
* Init Timer
************
 
*Predivision du timer avant 64 clock d'horloge
*PR0=PR1=1 Predivision par 16 (16*500ns=8µs)
* Autorisation interruption debordement TCNT
 
         bset           tmsk2,y,#$83   *Interruption toutes les 524,28ms
 
*Initialisation de la RTI
**************************
 
* Horloge 8Mhz RTR0=RTR1=1 t=32.77ms
 
         ldaa           #$03
         staa           pactl         
 
* Etat de la RTI Forcage du bit rtif a 0 *
 
         bset            tflg2,y,#$40     * Ce bit indique l'etat de la RTI
 
* Chez Motorola pour remettre à zero les flag on met un 1 d'ou l'utilisation de BSET ci-dessus
 
 
* Autorisation des interruptions Générales masquable par I du CCR
 
         cli
 
*
********************
*Programme principal  
********************
 
* allumage du feu rouge feux 1 et vert feux 2.
 
debut    ldaa           #$81
         staa           portb,y
 
* tempo de 32 secondes
 
         bsr            tempo32
 
* allumage du feu rouge feux 1 et feu orange feux 2
 
         ldaa           #$82
         staa           portb,y
 
* tempo de 4 secondes
 
         bsr            tempo4
 
* allumage du feu rouge feux 1 et feu rouge feux 2
 
         ldaa           #$84
         staa           portb,y
 
* tempo de 2 secondes 
 
         bsr            tempo2
 
* allumage du feu vert feux 1 et rouge feux 2.
 
         ldaa           #$24
         staa           portb,y
 
* Autorisation de l'interruption RTI *
 
         bset           tmsk2,y,#$40
 
* tempo de 32 secondes
 
         bsr            tempo32
 
* allumage du feu orange feux 1 et feu rouge feux 2
 
         ldaa           #$44
         staa           portb,y
 
* inibition de l'interruption RTI *
 
        bclr             tmsk2,y,#$40
 
* tempo de 4 secondes
 
         bsr            tempo4
 
* allumage du feu rouge feux 1 et feu rouge feux 2
 
         ldaa           #$84
         staa           portb,y
 
* tempo de 2 secondes 
 
         bsr            tempo2
         bra            debut
 
*****************
* Sous programmes  *
*****************
 
*Sous programmes tempo32
**********************
 
* duree de temporisation de 32 secondes
 
tempo32  ldaa    #dureev
         staa    duree
         bsr     attente
         rts
 
*Sous programmes tempo4
*********************
* duree de temporisation de 4 secondes
 
tempo4   ldaa    #dureeo
         staa    duree
         bsr     attente
          rts
 
*Sous programmes tempo2
**********************
* duree de temporisation de 2 secondes
 
tempo2   ldaa    #duree2r
         staa    duree
         bsr     attente
         rts
 
*Sous programmes Attente
**********************
* Attente d'interruption
 
attente  ldaa    drapeau
         beq     attente
         clr     drapeau
         rts
 
 
********************************
* Sous programmes interruption*
********************************
 
* SP TIMER Depassement TCTNT *
******************************
 
tempo    inc            compt1         * Tempo de 0,52428 x duree
         ldaa           duree          * Donne le temps 
         suba           compt1         * comparaison de compt1
         bne            fin1           * a Duree
         ldaa           #$01           * Drapeau = 1 fin tempo
         staa           drapeau        * 
         clr            compt1         * Preparation pour tempo suivante
 
* TOF=0 pour revenir en interruption 524,28ms apres
 
fin1     bclr           tflg2,y,#$7F     
 
* On utilise ici bclear au lieu de bset pour ne pas toucher au bit RTIF 
utilise dans la RTI
 
         rti
 
 
* SP RTI *
**********
 
orange   inc            compt
 
* 23 (23*32,768 = 754ms) fois la RTI (1/2 periode de clignotement) ?
 
         ldaa           compt
         suba            #23
         bne            fin     *sortir de la rti duree inferieure a 754 ms depuis le dernier
                                *changement du feu orange clignotant
        
* Test s'il faut eteindre ou allumer le feu orange clignotant         
 
         ldaa           portb,y
         bita           #$10
         beq            inv
 
* On eteint le feu orange clignotant
 
         bclr           portb,y,#$10
         bra            suite
 
* On allume le feu orange clignotant
 
inv              bset           portb,y,#$10
 
*RAZ compteur pour compter de nouveau un temps de 754ms
 
suite            clr           compt
 
* rtif=0 pour revenir en rti 32.77ms apres
 
fin              bclr           tflg2,y,#$BF
 
* On utilise ici bclear au lieu de bset pour ne pas toucher au bit TOF 
utilise dans debordement TIMER interupt
 
         rti
 
 
***************************
* Vecteurs d'interruptions
***************************
*vecteur Timer Debordement TCTNT 
 
         org            $ffde
rstctnt          fdb            tempo
 
*vecteur Real time interrupt 
 
         org            $fff0
rstrti           fdb            orange
 
*vecteur de reset 
 
         org            $fffe
rstvect          fdb            start
 
         end
 
 

 

 

 

 

Meme probleme avec l'elaboration des tempo des feux par de Timer Output Compare

Ici on utilise le timer par comparaison. On obtient ainsi un temps d'une precision allant jusqu'a 0,5µs. Dans l'exemple precedent le temps etait fixe par le debordement du timer. Ce qui implique que le compteur s'incremente 65535 fois. Avec l'utilisation de la comparaison on choisit le nombre de fois que le compteur s'incremente pour creer un evenement.


Ici on utilise la comparaison du Timer, on ne presentera que cette partie du timer. L'exemple est donne sur TOC2.

 

 

Les bit PR0 et PR1 permettent de prediviser l'horloge par 1, 4, 8, ou 16, ainsi le compteur TCNT peut etre cadence par E, ou E/4 E/8 ou E/16. Ce prediviseur doit etre programme durant les 64 premiers clock d'horloge pour etre pris en compte. La predivision donne la precision du compteur. Pour 8Mhz ce dernier est incremente toutes les 500 ns, 2µs, 4µs ou 8µs selon la combinaison de PR[0:1] Le compteur TCNT est un compteur qui n'est jamais arrete. On peut le lire mais pas l'arreter, pas le forcer a zero ou autres valeurs.
La valeur du compteur sur 16 bits est compare a une valeur sur 16 bits, la valeur de TOC2. Lorsqu'il ya egalite le bit OC2F passe a 1. Si l'on a autorise l'interruption par 0C2I, une requete d'interruption est demande.

Registre TMSK2

Bit 0 et 1 predivision de E

1.24.3.8               Timer Interrupt Mask Register 2 (TMSK2 $1024)

Bit 7

6

5

4

3

2

1

Bit 0

TOI

RTII

PAOVI

PAII

-

-

PR1

PR0

 

PR[1:0]

Predivision

0 0
0 1
1 0
1 1

1
4
8
16

 

 

 

 

Registre TMSK1

Bit 6 Autorisation interruption de TOC 2, sa mise a un autorise l'interruption TOC2. Des que FLAG TOC2 passe a un on part en interruption (voir registre ci-apres).

1.24.3.9               Timer Interrupt Mask Register 1 (TMSK1 $1022)

Bit 7

6

5

4

3

2

1

Bit 0

OC1I

OC2I

OC3I

OC4I

I4/O5I

IC1I

IC2I

IC3I

Registre TFGL1

Bit 6 Flag de TOC 2, des qu'il est a un on part en interruption si l'on est autorise. Il faut donc le remettre a zero a la fin du SP d'interruption par TOC2.

1.24.3.10          Timer FLAG Register 1 (TFLG1 $1023)

Bit 7

6

5

4

3

2

1

Bit 0

OC1F

OC2F

OC3F

OC4F

I4/O5F

IC1F

IC2F

IC3F

Adresse du vecteur d'interruption

$FFDE et $FFE6

Organigrammes de fonctionnement

* fichier feutoc.asc
* Gestion des tempos par timer
* (32s) Rouge feu 1/vert feu 2 - (4s) Rouge feu 1/Orange feu 2 - (2s) Rouge feu 1/Rouge feu 2 
* (32s) Vert feu 1 Orange2 clignotant/Rouge feu 2 - (4s) Orange1 feu 1/Rouge feu 2 - (2s) Rouge feu 1/Rouge feu 2 
* Gestion D'un seul feu
* Feu tricolore 1 sur portB Feu rouge bit 2, orange bit 1 et vert bit 0.
* Feu tricolore 2 sur portB Feu rouge bit 7, orange bit 6 et vert bit 5.
 
* R  O  V  OC    R  O  V
* 7  6  5  4  3  2  1  0 
* 8  4  2  1  8  4  2  1
 
*Equivalences registres
 
portb          equ            $04
pactl          equ            $1026
tmsk1          equ            $22            * Bit 6 autorisation OC2
tmsk2          equ            $24
tflg1          equ            $23
tflg2          equ            $25
toc2           equ            $18
 
*Constantes 
 
dureev  equ            32             * Duree de 32s d'allumage du feu vert
dureeo  equ            4              * Duree de 4s d'allumage du feu orange
duree2r equ            2              * Duree de 2s d'allumage du feu rouge
pile           equ            $ff
 
*Variables
 
               org            $0000
compt          rmb            1              * Compteur contenant le nombre d'interruption RTI permettant
                                              * de conaitre la duree entre 2 interruptions RTI
 
temps          rmb            2              * Temps en seconde, variable ou l'on stocke ;
                                              * le temps a attendre qu'un actionneur soit actif et qui est
                                              * decompte ;
drapeau rmb            1              * Valeur binaire 0 temps non atteint 1 temps atteint ;
compt1  rmb            1              * Compteur de 10 eme de seconde
 
*Debut du programme implantation en EEPROM
 
               org            $F800
 
********************
*   Configuration        
********************
 
*initialisation de la pile
 
start           lds            #pile
 
* Initilisation de Y pour adressage indexe specifique aux instructions BSET BCLR BRSET BRCLR
 
               ldy            #$1000
 
* Init Timer
************
 
*Predivision du timer avant 64 clock d'horloge
*PR0=PR1=1 Predivision par 16 (16*500ns=8µs)
 
               bset           tmsk2,y,#$03   
 
* Init TOC2
************
* Validation de l'interruption OC2
 
               bset           tmsk1,y,#$40
 
*Initialisation de la RTI
**************************
 
* Horloge 8Mhz RTR0=RTR1=1 t=32.77ms
 
               ldaa           #$03
               staa           pactl         
 
* Init compteur 10 * 100ms pour faire 1 s     
 
               ldaa           #10
               staa           compt1
               
* Autorisation des interruptions Generales masquable par I du CCR
 
               cli
 
 
*
********************
*Programme principal  
********************
 
* allumage du feu rouge feux 1 et vert feux 2.
 
debut          ldaa           #$81
               staa           portb,y
 
* tempo de 32 secondes
 
               bsr            tempo32
 
* allumage du feu rouge feux 1 et feu orange feux 2
 
               ldaa           #$82
               staa           portb,y
 
* tempo de 4 secondes
 
               bsr            tempo4
 
* allumage du feu rouge feux 1 et feu rouge feux 2
 
               ldaa           #$84
               staa           portb,y
 
* tempo de 2 secondes 
 
               bsr            tempo2
 
* allumage du feu vert feux 1 et rouge feux 2.
 
               ldaa           #$24
               staa           portb,y
 
* Autorisation de l'interruption RTI *
 
               bset           tmsk2,y,#$40
 
* tempo de 32 secondes
 
               bsr            tempo32
 
* allumage du feu orange feux 1 et feu rouge feux 2
 
               ldaa           #$44
               staa           portb,y
 
* inibition de l'interruption RTI *
 
              bclr             tmsk2,y,#$40
 
* tempo de 4 secondes
 
               bsr            tempo4
 
* allumage du feu rouge feux 1 et feu rouge feux 2
 
               ldaa           #$84
               staa           portb,y
 
* tempo de 2 secondes 
 
               bsr            tempo2
               bra            debut
 
*****************
* Sous programmes  *
*****************
 
* duree de temporisation de 32 secondes
 
tempo32        ldx     #dureev
               stx     temps
               bsr     attente
               rts
 
*Sous programmes tempo4
*********************
* duree de temporisation de 4 secondes
 
tempo4         ldx     #dureeo
               stx     temps
               bsr     attente
               rts
 
*Sous programmes tempo2
**********************
* duree de temporisation de 2 secondes
 
tempo2         ldx     #duree2r
               stx     temps
               bsr     attente
               rts
 
*Sous programmes Attente
**********************
* Attente d'interruption
 
attente        ldaa    drapeau
               beq     attente
               clr     drapeau
               rts
 
 
********************************
* Sous programmes interruption*
********************************
 
* SP TIMER comparaison OC2 *
****************************
 
* Preparation de la prochaine interruption ajout de 100 ms
 
tempo          ldd            #12500
               addd           toc2,y
               std            toc2,y  
 
* Base de 10 fois 100ms = 1s
 
               dec            compt1
               bne            fin1
 
* Init de compt a 10 pour la prochaine interruption
 
               ldaa           #10
               staa           compt1
 
* Temps en seconde executer
 
               ldx            temps
               dex
               stx            temps