Cette page et ses descendantes sont encore en cours de construction…

Organisation de la mémoire du PIC16F150x

Les microcontroleurs PIC16F possèdent deux espaces mémoires distincts : l’un pour le programme, l’autre pour les données. On parle alors d’une architecture Harvard (opposée à une architecture Von Neumann).

Selon le modèle de microcontroleur choisi, ces espaces mémoires peuvent avoir des tailles différentes (exemple du PIC16F1509 : 8192 instructions pour le programme et 512 octets pour les données).

On peut cependant déjà noter que ces valeurs sont relativement faibles. Les microcontrôleurs ont des ressources très limitées en terme de mémoire et de puissance de calcul. Ils réalisent des tâches répétitives mais “simples” mais à moindre coût qu’un ordinateur complet, plus puissant mais plus gourmand également en terme d’énergie.

Espace mémoire Programme

La mémoire programme est une zone contiguë de cases mémoires, chacune permettant de stocker une instruction. Un pointeur programme permet de venir successivement adresser ces différentes cases.

On peut remarquer, dans la figure précédente (tirée de la documentation technique du PIC16F1509), que certaines adresses (spécifiées sur le côté gauche en hexadécimale – 0x….) sont un peu plus spécifiques :

  • l’adresse 0x0000 / nommée Reset Vector : première adresse disponible dans la mémoire programme et adresse de la première instruction à être exécutée lors du démarrage (ou reset) du microcontroleur
  • l’adresse 0x0004 / nommée Interrupt Vector : adresse de la première instruction exécutée lors d’une interruption (abordée dans un tutoriel ultérieur – Interruptions)

La gestion de cet espace mémoire est laissée généralement au compilateur qui vient placer les différents blocs d’instructions de manière ordonnée.

Espace mémoire Données

L’espace mémoire prévue pour les données est une zone contiguë, différente de la mémoire programme pour les microcontroleur de ce type. Chaque espace mémoire adressable est appelée un registre. Dans le cas des PIC16F, ces espaces mémoires font 1 octet ou 8 bits.

Chacune des informations binaires placée dans ces registres est répertoriée par le nom du bit associée : le bit b0 correspondant au bit de poids faible (LSB – Less Significant Bit) et le bit b7 au bit de poids fort (MSB – Most Significant Bit).

Par la suite, selon le type de registre, ils pourront posséder eux-mêmes un nom. Chacune des informations binaires présentes dans ces registres pourra également porter un nom spécifique en fonction de son rôle dans la configuration des modules du microcontroleur.

Dans les microcontroleurs PIC16F, cette mémoire est découpée selon le schéma de la figure suivante (tirée de la documentation technique du PIC16F1509) :

L’espace mémoire de données est subdivisée en plusieurs catégories :

  • des registres spécifiques : permettant de configurer le microcontroleur et certains de ces modules
    • Core Registers : registres importants accessibles à tout moment et rapidement
    • Special Function Registers : registres de configuration accessibles uniquement dans certaines banques de mémoire
  • des registres à usage général (RAM) : permettant de stocker les variables de l’application embarquée

Accès aux registres d’un PIC16Fxxxx

L’ensemble des registres du microcontroleur étant accessibles en lecture et en écriture, nous allons nous intéresser ici à leur utilisation et leur accès.

Registres à usage général

Les registres à usage général servent essentiellement à stocker les variables de l’application.

Ainsi, lorsqu’en C vous déclarez dans votre programme des variables typées :

char a;
int b;

le compilateur va leur attribuer une place en RAM en fonction de leur type (et donc de leur taille) et de la place disponible.

Une variable de type char est codée sur 1 octet. Lorsqu’elle est non signée, elle permet de stocker un entier entre 0 et 255.
Une variable de type int est codée sur 2 octets. Lorsqu’elle est non signée, elle permet de stocker un entier entre 0 et 65535.

Il est ensuite possible d’écrire des valeurs dans ces variables de plusieurs façons :

a = 41;              // en décimal
a = 0x29;            // en hexadécimal
a = 0b0010 1001;     // en binaire

Registres à usage spécifique

Par la suite, vous serez amené à programmer ce type de microcontroleur en langage C. L’interface de développement MPLABX, en plus d’un compilateur et d’un éditeur de texte, propose un ensemble de fonctions permettant d’accèder à l’ensemble des registres du microcontroleur par leur nom.

Ainsi, on peut par exemple accèder au registre qui permet de contrôler le port d’entrées/sorties nommés A par l’intermédiaire du registre nommé PORTA.
On pourra alors soit écrire une valeur sur l’ensemble du registre (valeurs semblables écrites en décimal ou en binaire) :

PORTA = 41;              // en décimal
PORTA = 0b0010 1001;     // en binaire

L’une ou l’autre de ces instructions aura pour effet de mettre des 1 et des 0 aux bits correspondants dans ce registre nommé PORTA (à l’adresse 0x0C de l’espace mémoire de données du microcontroleur).

Une autre solution est d’affecter uniquement un bit dans l’ensemble du registre. Pour cela, on peut utiliser la syntaxe suivante (qui fonctionne pour n’importe quel registre mentionné dans la documentation technique) :

PORTAbits.RA3 = 0; 

Cette instruction aura pour effet de ne modifier que le bit nommé RA3 dans le registre nommé PORTA.

Les autres bits ne seront pas affectés.

Etat de la mémoire – DashBoard

Il est également possible à tout moment, après compilation, de connaître l’état de la mémoire et de son occupation.
L’environnement MPLABX propose un outil, le Dashboard, qui résume les ressources utilisées par le programme sur la cible : que ce soit en terme de mémoire programme ou de mémoire de données.

Ce module est accessible par le menu Window / Dashboard.

Principaux registres du PIC16F150x

Certains registres sont plus utilisés que d’autres. En voici une liste non exhaustive.

RegistresDescriptionExemplePIC16F1503 / ppPIC16F1509 / pp
OSSCONPermet de régler la fréquence de fonctionnement du microcontroleur :
– IRCF : choix de la fréquence
– SCS : choix du type d’horloge
Configuration de l’horloge FOSC à 1MHz :
OSCCONbits.IRCF = 0b1011;
Chap 5 / pp 42-50
OSCCON – p. 49
 
INTCONPermet de gérer les interruptions sur le microcontroleur :
– GIE : Validation générale
– INTE : Broche INT / RA2
– TMR0IE : Timer 0
– INTF : Flag de l’interruption INT
– TMR0IF : Flag de l’interruption sur TMR0
Configuration des interruptions sur RA2 :
TRISAbits.TRISA2 = 1;
ANSELAbits.ANSELA2 = 0;
INTCONbits.INTF = 0;
INTCONbits.INTE = 1;
INTCONbits.GIE = 1;
Chap 7 / pp 59-71
INTCON – p. 64
 
TRISxPermet de configurer la direction des entrées/sorties numériques   
PORTx    
ANSELx    
     
Microchip PIC16F / Registres internes PIC16F150x