mercredi 2 novembre 2011

Les ports d'entrée-sortie du MSP430

Pour expliquer notre premier programme, nous allons tout d'abord rentrer dans l'architecture du MSP430G2231 et parler des ports d'entrée-sortie.

Comme vous l'avez sans doute remarqué, le MSP430G2231 possède 16 pattes. Pour trouver la fonction électrique de chacune de ces pattes, il faut consulter un document qui s'appelle le "datasheet" du MSP430G2231. Chez Texas Instruments, un datasheet est un document qui décrit et qui donne toutes les caractéristiques d'un circuit. Vous pouvez trouver le datasheet du MSP430G2231 au format PDF ici : http://www.ti.com/lit/ds/symlink/msp430g2231.pdf .

Au début du document, vous trouverez la description des pattes du circuit :


La patte 1 est utilisée pour l'alimentation. Elle doit être relié à une source de tension d'environ 3 volts (entre 2 volts et 3.6 volts pour être précis). En général, on utilise du 3.3 volts. Sur le Launchpad elle est déjà reliée au 3.3 volts.
La patte 14 doit être reliée à la masse (0 volts) ou à la broche '-' d'une pile. Sur le Launchpad elle est déjà reliée à la masse.
Les pattes 2 à 9 sont utilisées (entre autre) par le port d'entrée-sortie P1. Ce port d'entrée-sortie possède 8 connections nommées P1.0 à P1.7.
Les pattes 12 et 13 sont utilisées (entre autre) par le port d'entrée-sortie P2 (P2.6 et P2.7).
On voit aussi que certaines pattes ont plusieurs fonctionnalités. Par exemple la patte 12 peut être soit P2.7, soit XOUT (utilisé par un oscillateur externe). Par défaut, à la mise sous tension, ce sont les fonctionnalités des ports d'entrées-sorties qui sont active. Si on veut utiliser une autre fonctionnalité, il faudra écrire une instruction dans le programme pour cela.

Voici un schéma fonctionnel de notre circuit (également tiré du datasheet) :


On retrouve nos 2 pattes d'alimentation (DVCC; DVSS) et nos 2 ports d'entrées-sortie (P1.x et P2.x). On voit également les périphériques internes du microcontrôleur (nous les détaillerons dans un autre post).

C'est bien beau tout ça, mais revenons à nos moutons : c'est quoi donc une patte d'entrée-sortie ?
C'est une patte du microcontrôleur qu'on peut définir soit :
- en entrée : dans ce cas, on peut lire la valeur logique appliqué sur cette tension. Par exemple, si on applique 3 volts sur cette patte, le programme pourra lire la valeur de cette entrée à un '1' logique. Par contre si on met cette entrée à la masse, on lira un '0' logique. Cela permet par exemple de détecter l'appui sur un bouton poussoir.
- en sortie : dans ce cas, le programme peut contrôler la valeur logique sur cette patte. Le programme peut écrire un '1' - on aura alors environ 3 volts sur cette patte. Il peut écrire un '0' - cette pate sera à un potentiel proche de la masse.
Un port d'entrée sortie regroupe plusieurs de ces pattes (par exmple le port P1 regroupe 8 signaux P1.0 à P1.7).

Mais comment peut-on commander les ports d'entrée sortie ?
Pour cela on utilise ce qu'on appelle des registres du micro. Les registres sont des cases mémoires qui sont reliées aux périphériques du micro. Il y a plusieurs centaines de registres dans un MSP430. Il y en a pour les ports d'entrée-sortie, mais aussi pour d'autres périphériques comme les timers, l'UART, les horloges (nous parlerons de ces périphériques un autre jour).

Aujourd'hui, on va s'intéressé à 3 registres du port P1. Leur petits noms sont P1DIR, P1IN et P1OUT.

P1DIR sert à définir la direction des pattes du ports P1 : en entrée ou en sortie. P1DIR est stocké sur 1 octets, c'est à dire sur 8 bits. Chaque bit correspond à une patte (bit 0 pour P1.0, but 1 pour P1.1, etc...). Par définition, un bit ne peut prendre que 2 valeurs 0 ou 1. Les bits à 0 placent la patte correspondante en entrée. Les bits à 1 placent les pattes correspondantes en sortie.


Sur l'image ci-dessus, on voit les 8 bits de P1DIR. Dans cet exemple, on constate que P1.0 et P1.6 sont en sortie. Les autres ports sont en entrée. (sur le Launchpad, les ports P1.0 et P1.6 sont utilisés pour commander les 2 LEDs).

P1OUT sert à définir la valeur effective sur les pattes de sorties. P1OUT contient également 8 bits (ça on s'en doutait !). Un bit à '1' applique une tension proche de VCC ( ici 3.3 volts) sur la patte correspondante. Un bit à '0' applique une tension proche de GND (0 volts) sur la patte correpondante.


P1IN permet de lire les valeurs logiques appliquées sur les pattes (qu'elles soient en entrée ou en sortie).


Maintenant nous allons nous amuser à modifier ces registres grâce au debugger de Code Composer Studio.

Pour cela, déramez Code Composer en utilisant le même workspace que dans le post précédent. Vous devriez tomber sur une fenêtre similaire à la suivante :



On retrouve le programme que nous avions créé dans le post précédent. Si vous n'êtes pas dans cette configuration, suivez les étapes décrites dans le post précédent.
On peut vérifier les propriétés du projet en faisant Project->Properties :


En choisissant l'option "CCS Build", on peut vérifier que le processeur ciblé est bien un MSP430G2231.

Maintenant passons en mode Debug. Pour cela, cliquez sur le petit insecte vert (je l'ai entouré en rouge sur  la copie d'écran de l'interface). Bien sûr à ce stade, le Launcpad doit être branché sur un port USB du PC pour que le Debuger puisse communiquer avec lui.


Maintenant nous allons visualiser quelques registres du MSP430 grâce au Debuger. Pour cela : View->Registers
Maintenant, choisissez Port_1_2. En effet nous voulons visualiser les registres liés aux ports d'entrée-sortie :


Oh miracle ! Voici les fameux registres P1IN P1OUT et P1DIR dont nous avons parlé !  :)
On va pouvoir faire joujou. Grâce au débugger on peut directement modifier la valeur de ces registres dans le MSP430.
Commençons par mettre P1.0 et P1.6 en sortie. Pour cela, on modifie P1DIR :


Vous vous rappelez sans doute que P1.0 et P1.6 sont reliés aux 2 LEDs du Launchpad. Maintenant on peut commander ces LEDs grâce à P1OUT. On va les allumer en mettant P1OUT.P0 et P1OUT.P6 à '1' :


Oh magie ! Comme c'est beau ! Notre Launchpad s'illumine :


De la même manière vous avez aussi accès à P1IN pour lire les valeurs en entrée (bien que cet affichage ne soit pas 100% dynamique pour les entrées).
Vous remarquez qu'on a changé les valeurs des registres un bit après l'autre. Dans la vue sur les registres, on peut aussi changer la valeur globale d'un registre (donc plusieurs bits à la fois). Par exemple on aurait pu directement modifier P1DIR en lui donnant la valeur 0x41.
Mais c'est quoi ce 0x ? Le 0x signifie que la valeur est affichée en hexadécimal.... Je vous vois faire une drôle de tête ! Je vais devoir expliquer ce qu'est la représentation hexadécimale qui est beaucoup utilisé pour la programmation des registres.

Compter en hexadécimal :
Dans la vie de tout les jours on utilise la représentation décimale (base 10) pour compter. Cela veut dire qu'on utilise 10 caractères de base pour compter qui sont 0, 1, 2, 3, 4, 5, 6, 7, 8 et 9.
La représentation hexadécimale (base 16) utilise 16 caractère pour compter : 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F.
Pour vous donner une idée des différences, voici un tableau de conversion décimal vers hexadécimal :


Par exemple 46 en décimal, c'est 0x2E en hexa. En effet 46 = 2*16 + 15. Ce qui donne '2' et 'E' (15) => 0x2E.
Da,s la programmation en C embarqué, on utilisé souvent cette notation. Un des avantages de cette notation est de pouvoir écrire 8 bits sur 2 caractères. En effet avec 8 bits, on peut compter de 0 à 255, ce qui en hexadécimal fait de 0x00 à 0xFF. Notre tableau contient également les équivalence entre hexa et bianire. On remarque que :

0b00000000 = 0x00
0b00000001 = 0x01
0b00000010 = 0x02
0b00000100 = 0x04
0b00001000 = 0x08
0b00001111 = 0x0F
0b00010000 = 0x10
0b00100001 = 0x20
0b01000010 = 0x40
0b10000100 = 0x80
0b11111111 = 0xFF


Pour revenie à P1DIR, on a mis les bits 0 et 6 à 1, ce qui donne :

0b01000001 = 0x41

On retrouve la valeur 0x41 affichée dans notre fenêtre de Debug.
Essayez dès à présent de vous habituer à utiliser la représentation binaire. Vous verrez, cela deviendra vite un automatisme pour vous, et vous en comprendrez les avantages.


Bien sûr ce que nous avons fait grâce au debugger, nous pouvons aussi le faire par le biais d'un programme en C. Reprenons donc notre premier programme pour l'expliquer.

1 commentaire:

  1. Merci pour l'explication c'est vraiment super bien fait!
    Cependant, si tu pouvais faire la même chose pour les registres P1SEL, P1SEL2 et P1REN et si possible aussi P1IES c'est des registres dont j'ai du mal à comprendre le fonctionnement.
    Merci d'avance!!!

    RépondreSupprimer