Télécharger au format pdf ou txt
Télécharger au format pdf ou txt
Vous êtes sur la page 1sur 41

Mode d'adressage et jeu d'instructions

Le jeu d'instruction des microcontrôleurs AVR contient 5 types d'instructions


– arithmétiques et logiques
– manipulation de bits
– accès mémoires
– sauts et tests
– contrôle du processeur
Ces instructions sont codées sur 2 ou 4 octets.
Code Instruction = opcode = op + opérande
Modes d'adressage

Les mode d'adressages désignent la manière dont une instruction connait


l'adresse (ou le n° de registre) des données qu'elle doit manipuler.

Il y a 4 modes d'adressage principaux (et quelques variantes) :


– l 'adressage par registre(s),
– l'adressage immédiat,
– l'adressage direct
– l'adressage indirect
Adressage par registre unique
Le n0 du registre (entre 0x00 et 0x1F) est indiqué dans opcode.

Exemple INC R20 : incrémente le registre R20


L'opcode de cette instruction a une partie fixe et les
5bits ddddd représentent le numéro du registre
destination.
20 = 0x14 = 1 0100

L'opcode de INC R20 est donc 1001 0101 0100 0011 soit 0x9543
Adressage par registre double
C'est le cas des instructions ALU a 2 opérandes .

Exemple
AND R24,R25 : Et logique entre R24 R25

OP 0010 00
Reg d=24 = 11000, d =24 1 1000
Reg r=25 = 11001 r =25 1 1001
L'opcode est 0010 0011 1000 1001 = 0x2389
Examples d’instructions :

AND Rd, Rs
ADD Rd, Rs
SUB Rd, Rs
MOV Rd, Rs
OR Rd, Rs
Adressage Immédiat
La donnée est fournie « immédiatement », elle est contenue dans l'opcode

Exemple ANDI R18,0x0F


AND Immediate
Ici K=0x0F, la seconde opérande va être encodée à l'intérieur de l'OPCODE.
Attention il y a une restriction sur le choix de Rd (de 16 à 31) afin de pouvoir
coder ce numéro de registre sur 4 bits.
R18 = 0x02 le 3ème registre utilisable par cette instruction du fait de la
restriction 16≤d≤31 K = 0000 1111

l'OPCODE sera donc 0111 0000 0010 1111


Adressage Direct
L'adresse d'une donnée est donnée DIRECTEMENT dans l'OPCODE

Exemple LDS R24,0x0060


Load Direct from data Space
0x0060 est l'adresse de la donnée en SRAM.
d=24 = 1 1000 le n° de registre

l'opcode est 1001 0001 1000 0000


0000 0000 0110 0000 = 0x91800060
216
Adressage indirect par pointeur X,Y,Z
l'adresse de la données est contenu dans une des registre X,Y,Z

Exemple LD R12,X
Load Data Memory Indirect X
Charge la donnée dont l'adresse en mémoire
SRAM est contenue dans X dans le registre R12
c'est le cas (i) du tableau opcode 1001 0001 1000 1100 = 0x918C
L'adressage indirect est très utilisé pour accéder aux tableaux (char A[10] en
C par exemple) et dans ce cas il est très courant d'accéder successivement à
tous les éléments du tableau (A[i++] ou A[--i])

L'adressage indirect des microcontrôleurs AVR supporte 2 variantes :


- la post incrémentation LD R12,X+
le registre X est incrémenté d'une unité après l'accès à la valeur pointée par X
– la pré décrementation LD R12,-X
le registre X est décrémenté AVANT l'accès à la valeur pointé par X
Jeu d'instruction
Instruction ALU :
On y retrouve tout le groupe d'instruction de « calcul » :
– Additions/soustractions : ADD,ADC,ADDW, INC, SUB, SUBI, SBC, SUBIW, DEC...
– Opération logiques : AND, ANDI, OR, ORI, EOR
– les multiplications MUL, MULS, FMUL, FMULS
– affectations particulière SET, CLR,

Instructions de manipulations au niveau bit.


Les instructions de rotations et décalage de registre (habituellement classées avec les
instructions ALU) : LSL, LSR, ROR, ROL, ASR
Les instructions d'accès aux registres IO au niveau bit. Ces instructions permettent
d'accéder bit a bit a ces registres. Seuls les registre IO de 0 a 0x1F (les 32 premiers
donc) sont accessible en mode bit a bit. Cela inclus les registres gérant les ports
d'entrée sortie A,B,C, D dont les numéros sont inférieur à 32.
Le groupe des instructions qui manipulent les bits du registre de statut SREG
– SEC (set Carry flag), CLC, SEN,CLN ....
il y a un couple d'instruction (CLER/SET) pour chacun de ces bits.
Instructions d'accès mémoire
Accès à la mémoire donnée
- MOV pour copie entre registre
- LD pour chargement depuis la mémoire
- ST pour écriture en mémoire
Pour l'accès en lecture en mémoire programme par adressage indirect à l'aide du registre Z :
– STM pour charger le registre Z
– LDM pour lecture de la mémoire programme par adressage indirect par le registre Z
Il n'est pas possible d'écrire en mémoire programme.
Pour les accès aux registres IO
- IN et OUT ATTENTION IN R2, 23 charge R2 avec le contenu du registre IO n° 23 (d'adresse
SRAM 0x43 donc)

Pour acces à la pile


– PUSH, POP
Le fonctionnement de ces 2 instructions est très spécifique :
La pile est gérée par le pointeur de pile SP (Stack Pointer). Le pointeur de pile est initialisé à la
fin de la mémoire (SP = 0x45F sur un ATmega16)
Dans l'exemple suivant on échange le contenu de 2 registre (R12 et
R13) en passant par la pile. On suppose que SP = 0x45F (fin de la
mémoire SRAM d'un ATMega16). Le code est le suivant :

Le contenu de R12 est copié à l'adresse contenu dans SP


PUSH R12 (0x45F), R12 est copié sur le dessus de la pile. SP est
décrementé(0x45E) et pointe toujours sur le haut de la pile
Le contenu de R13 est copié à l'adresse contenu dans SP
PUSH R13 (0x45E), R13 est copié sur le dessus de la pile (au dessus de
R12) (0x45D), SP est décrementé
Le haut de la pile (SP-1) qui contenait une copie de R13 est copié dans
POP R12
R12, SP est incrémenté (le haut de la pile descends)
Le haut de la pile (SP-1) qui contenait la copie de R12 est copié
POP R13
dans R13, SP est incrémenté (le haut de la pile descends)
Instructions de branchement et sauts
Dans un programme et à l'exception des instructions de branchement et saut,
le Program Counter PC s'incrémente après chaque instruction. Cela a pour
effet d'exécuter les instructions dans l'ordre et les unes après les autres. Les
instructions de branchement sont les seules instructions qui permettent de
changer cet ordre naturel d'exécution des instructions. Ces instructions de
branchement sont générés par les structure de contrôle du C du type if, for,
while ? Et les appels de fonctions.

– JUMP, RJUMP, IJUMP permettent de faire un saut à une adresse programme


spécifiée
– CALL, RET : couple d'instruction pour les appels et retours de fonctions
– RETI : retour d'interruptions
– SKIP : Sbxx permet de sauter l'instruction suivante si le bit spécifié est à 1 ou 0
– BRANCH : Bxxx : saut (relatif) à l'adresse donnée si la condition est vérifiée
Instructions spéciales
– NOP : ne fait rien .... Mais son éxécution dure 1 cycle d'horloge
– SLEEP : endort le processeur (faible consommation)
– WDR : Rendort de chien de garde....
– BREAK : arrete le processeur (debug)
Les périphériques internes : Interface parallèle
Permet de communiquer des états logiques via des broches externes, en entrée/sortie
Ces broches sont généralement organisées en ports, souvent 8 ou 16 bits, ce qui
permet la communication de mots
Peut être associée à un gestionnaire de bus externe, de façon à pouvoir adresser des
composants extérieurs comme s'ils faisaient partie de la RAM interne.
Interface série
contrairement à l'interface parallèle, les mots sont envoyés séquentiellement sur une seule ligne
mode Half-Duplex (1 émetteur et 1 récepteur) ou Full-Duplex (2 émetteurs/récepteurs)
synchrone ou asynchrone
I2C
communication à 2 fils (Two-Wire Interface: TWI)
SDA : données
SCK : horloge
développé par Philips dans les années 1980
bus de communication entre 1 maître et 1 ou plusieurs esclaves, avec rôles
interchangeables
sélection de l'esclave par adressage
Half-Duplex
vitesse modérée (5Mhz)
SPI
communication à 4 fils
MISO, DI ou SDI : données entrantes
MOSI, DO ou SDO : données sortantes
SCK ou CLK : horloge
SS ou CS : sélection
également maître/esclaves
si plusieurs esclaves, chacun a sa propre ligne « Chip Select »
Full-Duplex
vitesses élevées (50Mhz), grosses quantités de données : alternative aux ports parallèles
pas de protocole précis, varie suivant fabricant
Convertisseur Analogique Numérique (CAN)
•Périphérique interne destiné à faire des mesures de tension (entre 0 et 5V)
•Procède par échantillonnage et quantification
•Généralement plusieurs entrées multiplexées sur l'interface parallèle

Timer
•Mesure des évènements
•si tops d'horloge : fonction de « temporisateur »
•si impulsions externes : fonction de « compteur »
•Il sert donc à :
•mesurer des temps
•exécuter des tâches périodiquement
•générer des signaux périodiques
•compter des évènements.
Les ports parallèles d'E/S
Caractéristiques générales
L'Arduino UNO dispose de 23 broches d'E/S, organisées en 3 ports parallèles
numériques
ce sont les ports B, C et D
port B : broches numériques 8 à 13
port C : broches analogiques (0 à 5)
port D : broches numériques 0 à 7
Ils sont tous bidirectionnels
le port C peut aussi être utilisé comme « port d'entrée analogique » (CAN)
Leurs lignes peuvent être configurées/utilisées individuellement
On peut changer les directions des ports par les instructions SBI and CBI.
Tous les pins des ports possèdent les résistances pull-up.

une broche I/O= Pxn

“x” represente les


lettres B, C ou D
pour le port,
“n” represente le
numéro du bit.
PORTB3 pour bit no.
3 du Port B,
(PORTxn)
Registres de contrôle des ports
Chaque port x (B, C ou D) est contrôlé par 3 registres
DDRx : le registre de direction (sens de transfert) du port
PORTx : le registre de donnée du port
PINx : le registre d'entrée du port
Chacun de leur bit contrôle une ligne particulière du port
exemple : le port B regroupe les broches numériques 8 à 13
le bit 0 de ses registres est donc associé à la broche numérique 8
Fonction des registres
Seuls PORTx et DDRx se comportent comme des variables mémoires
un composant mémoire leur ait associé, qui joue le rôle de verrou (=latch)
les écritures dans ces registres sont donc persistentes
DDRx : détermine la direction de chaque broche du port x
0 pour une Entrée, 1 pour une Sortie (« 0/1 » pour « E/S »)
PORTx = pour l'ECRITURE de valeurs en sortie
pour les broches en sortie : 0 pour tension basse, 1 pour tension haute
pour les broches en entrée : 1 pour activer la résistance « pull-up », 0 sinon
PINx = pour la LECTURE de la valeur en entrée (n'est pas un composant mémoire)
il est directement connecté aux lignes du port x, et traduit donc leur
tension indique la tension des broches : 0 pour tension basse, 1 pour
tension haute
• Data Register PORTx —> used to write output data to the port.
pour l'ECRITURE de valeurs en sortie
• Data Direction Register DDRx —> used to set a specific port pin to
either output (1) or input (0).
détermine la DIRECTION de chaque broche du port (1-sortie 0-entrée)
• Input Pin Address PINx —> used to read input data from the port.
pour la LECTURE de la valeur en entrée
// Exemple ecriture de sortie
void setup()
{
DDRB |= 0x40; // config PB6 en sortie
PORTB &= ~0x40; // PORTB.6 <-0 (écrire PB6 à 0)
}
// Exemple lecture d'entrée
void setup()
{
DDRD &= ~0x08; // config. PD3 entrée
}
void loop()
{
if((PIND&0x08)!=0) { // si entrée PD3 à 1
...
}
}
If selected for input, the pin may be selected for either an input pin or to
operate in the high impedance (Hi-Z) mode.
Note that the data direction register (DDRx) is first used to set the pins as
either input or output, and then the data register (PORTx) is used to set the
initial value of the output port pins.
The Port Input Pins I/O location is read only, while the Data Register and the
Data Direction Register are read/write.
However, writing a logic one to a bit in the PINx Register, will result in a toggle
in the corresponding bit in the Data Register.
In addition, the Pull-up Disable – PUD bit in MCUCR disables the pull-up
function for all pins in all ports when set.
//initialize_ports: initial configuration for I/O ports
void initialize_ports(void)
{
DDRA=0xfc; //set PORTA[7:2] as output, PORTA[1:0] as input (1111_1100)
PORTA=0x03; //initialize PORTA[7:2] low

DDRB=0xa0; //PORTB[7:4] as output, set PORTB[3:0] as input


PORTB=0x00; //disable PORTB pull-up resistors

DDRC=0xff; //set PORTC as output


PORTC=0x00; //initialize low

DDRD=0xff; //set PORTD as output


PORTD=0x00; //initialize low
}
To read the value from a port pin configured as input,

the variable used to read the value from the input pins is declared as an
unsigned char (both the port and this variable type are eight bits wide).

unsigned char new_PORTB; //new values of PORTB


:
:
:
new_PORTB = PINB; //read PORTB

Reading from the address PORTx, when the port is configured as output,
returns the last value written to the port.
two data registers, PINx, is used when the port is configured as input, and
PORTx, is used when the port is configured as output.

Writing to PORTx
when DDRx = 0
(port configured as
input) connects
internal pull-up
resistors to the
input lines
corresponding to
the bits in
PORTx set to 1.
Special instructions have been provided to allow software access to the I/O
ports or to the individual bits thereof.
IN Rd,ioport ;read from the address ioport to register Rd
OUT ioport,Rs ;write data from Rs to ioport
SBI ioport,bit ;set specified bit to ioport
CBI ioport,bit ;clear specified bit to ioport

configuration and access to PORTB:


LDI R16, $F0 ;configure upper nibble of PORTB as output
OUT DDRB,R16
LDI R16,$0F
OUT PORTB,R16 ;enable internal pull-ups on lower nibble and write 0 in the upper nibbl
IN R0,PINB ;read the input lines
;using CBI and SBI to write to ports
SBI DDRB,1 ;make bit 1 as output bit on PORTB
CBI PORTB,1 ;make PORTB bit 1 as "0"
SBI PORTB,1 ;make PORTB bit 1 as "1"
;Another way to change port values is by using the IN and OUT instructions
;using OUT instruction to write to ports
LDI R18,0b00000010
OUT DDRB,R18 ; make bit 1 as output bit on PORTB
LDI R18,0b00000000
OUT PORTB,R18 ; make PORTB bit 1 as "0"
LDI R18,0b00000010
OUT PORTB,R18 ; make PORTB bit 1 as "1«
;using IN instruction to read from ports
LDI R18,0b00000000
OUT DDRB,R18 ; make all bits as input bit on PORTB
LDI R18,0b11111111
OUT PORTB,R18 ; enable the pullup resistors on the PORTB
IN R18,PINB ; read the pins on the PORTB. R18 has the result.
Tous les ports parallèles autorisent l’utilisation réelle des instructions du type
lecture/modification/écriture : il est possible de changer le sens de
fonctionnement d’une ligne au moyen d’une instruction SBI ou CBI sans
affecter les autres ligne

De nombreux µC ne fonctionnent pas comme cela : toute action sur un seul bit
se traduit par lecture et une réécriture complète de tout le registre.

Cela conduit à des problèmes.

Vous aimerez peut-être aussi