Les bases du microcontrôleur





Cette page a pour but de démystifier les microcontrôleurs et vous aider à faire vos premiers pas avec l'engin.
Il serait ambitieux de vouloir résumer en quelques lignes le fonctionnement des microcontrôleurs. Des ouvrages complets existent pour cela. Je vais essayer de présenter les possibilités du µC, et décrire comment vous pouvez facilement les utiliser.

Voici le sommaire de cette page :

- Que puis-je faire avec un microcontrôleur ?

- Ça ressemble à quoi ? Comment ça marche "à l'intérieur" ? On y trouve quoi ?

- De quoi ais-je besoin pour faire fonctionner un microcontrôleur ?

- Comment brancher un microcontrôleur ? Les montages les plus classiques !

- Comment insérer un programme dans la "puce" ?

- Comment fabriquer le programme ?
- Le langage C
- La structure d'un programme
- Les instructions les plus utiles
- Quelques exemples



1/ Que puis-je faire avec un microcontrôleur ?


La réponse est tellement vaste que l'exhaustivité est impossible. Contrairement à ce qu'on peut faire croire, un µC n'est PAS intelligent. Bien au contraire. Simplement, il fait quelques petites choses élémentaires, précises et ordonnées. Le génie du programmeur c'est de savoir utiliser au mieux les quelques actions possibles.




Actions envisageables sur les sorties du µC :

- Commander ==> C'est souvent la première utilisation souhaitée. On souhaite commander une LED, un moteur à courant continu, un servomoteur , un relais, ou tout élément qui doit s'allumer ou s'éteindre. Chacune de ces actions est le résultat de l'allumage ou de l'extinction d'un port de sortie du µC.

- Compter ==> Tout µC possède un opérateur mathématique. Donc compter... il ne sait faire que ça !!! Il peut en plus faire des opérations logiques, remplaçant toute une palanquée de composants élémentaires. "Compter" suppose aussi "comparer" de façon à déclencher ou non des actions spécifiques.

- Afficher ==> Il y a plein de façons d'afficher des informations. On peut allumer des LEDs, ou commander un écran LCD pour afficher les informations voulues. Ne vous attendez pas à des miracles... un µC n'est pas une carte graphique 3D !!!

- Mémoriser ==> Grâce à la mémoire intégrée à tout µC (l'EEPROM) il peut stocker, même si l'alimentation est coupée, tout type d'information de la plus élémentaire (l'état d'un bit) à la plus évoluée (un fichier de son). Attention, la mémoire est vite pleine avec certains µC! il faut bien choisir celui que vous allez utiliser.

- Communiquer ==> Et oui, il peut le faire. Il y a, dans le µC des "blocs" de communication "I2C", "TX", "ISP"... qui permettent d'établir un dialogue avec d'autres composants qui utilisent le même protocole de communication. Ces "Blocs" sont reliés à des pattes spéciales. Il suffit d'activer la communication à l'aide de registres spéciaux.


Acquisitions envisageables sur les entrées du µC :

- Mesurer un état binaire ==> C'est le cas le plus simple. On surveille l'état d'une patte pour connaître l'état (ON ou OFF) du capteur qui y est branché. Cela permet de  détecter un niveau souhaité sur une patte d'entrée afin de déclencher un sous-programme ("interruption"). Sur mes décodeurs, j'utilise cette fonctionnalité pour détecter la trame.

- Mesurer une tension ==> On surveille la tension (en volts) sur une patte. Mais le µC ne connait pas les valeurs intermédiaires entre 0 et 5v. Il possède donc un dispositif qui est capable de convertir la valeur de la tension en une valeur numérique (sur 8 bits). C'est le rôle du "CAN" (Convertisseur Analogique Numérique). Je n'utilise pas cette fonctionnalité pour mes décodeurs.

- Mesurer une durée ==> Sachant qu'une horloge  incrémente des compteurs internes à intervalles réguliers, il est possible connaître le temps écoulé entre 2 évènements. Ces évènements peuvent être externes (détection d'un capteur) ou internes (déclenchement automatique d'un "TIMER"). C'est très utilisé, surtout pour nos décodeurs !

- Communiquer ==> un microcontrôleur doit être capable de recevoir des informations depuis un autre composant. Les protocoles I2C, Tx-Rx, ISP permettent de recevoir (et d'envoyer) des données. Je n'utilise pas cette fonctionnalité pour mes décodeurs.




2/ Ça ressemble à quoi ? Comment ça marche "à l'intérieur" ?


Il existe de nombreux types de microcontrôleurs. Actuellement, trois familles se partagent le marché : INTEL (PIC), ATMEL, Motorola. Les seuls que nous pouvons programmer avec des moyens économiques sont les "PIC" et les "ATMEL".  Je n'évoquerai que les ATMEL avec lesquels j'ai l'habitude de travailler. Je rappelle que l'arduino n'est qu'une interface de programmation. au coeur de l'arduino, il y a ...un µC ATMEL !!!!! cette photo en est la preuve !

Ca ressemble à quoi ?
Tout simplement à un morceau de plastique avec "plein" de pattes autour. Le nombre de pattes est variable suivant les possibilités du µC et le type de support (DIl, cms, SOIC...).

Mais le plus important ce sont les fonctionnalités internes. Il faut choisir le µC adapté à votre usage. Il existe des tableaux qui permettent de comparer les puces. Parmi les plus intéressants, j'utilise surtout ceux-ci :
Nom du µC
nombre
de pattes
Nb
E-S
Nombre de
TIMERS
Convertisseur
analog<->digital
mémoire Flash
(programme)
Mémoire
 vive
EEPROM
ATtiny85
8
6
1 (8bits)
4 pattes * 10 bits
8 kOctets
512 octets
512 octets
ATtiny861
20
16
1 (8bits) + 1 (16bits) 11 pattes*10bits
8 kOctets 512 octets 512 octets
ATmega8535
40
32
2 (8bits) + 1 (16bits) 8 pattes * 10 bits
 8 kOctets
512 octets 512 octets
ATmega162
40
35
2 (8bits) + 2 (16bits) 8 pattes * 10 bits 16 kOctets
512 octets 1024 octets
nota : Les TIMERS sont les "chronomètres" internes. Plus il y en a plus on peut mesurer de choses simultanément.

Dans ce petit tableau, remarquez surtout que les critères de choix sont :
 -le nombre d'entrées-sorties du µC,
- le nombre de TIMERS (chronomètres) internes
- la taille des différentes mémoires
Les ATtiny ont des dimensions et des capacités de mémoire relativement modestes tandis que les ATmega sont des µC relativement balaises.



Comment ça marche à l'intérieur ?

Il y a tellement de choses à régler pour le fonctionnement interne d'un µC qu'elles sont réparties en "Registres" internes.

Sans rentrer dans les détails....Il y a un calculateur (contrôleur) qui organise les discussions entre toutes les parties du µC. Evidemment, il ne les fait pas dialoguer n'importe comment pour le plaisir. C'est votre programme qui va dire qui communique avec qui et à quel moment.

Remarquez que les registres qui nous intéressent le plus sont ceux qui ont une sortie à l'extérieur du µC (PORTA, PORTB, PORTC, PORTD) et les TIMERS.

L'avantage de fonctionner avec des blocs, c'est qu'ils peuvent travailler simultanément sur des opérations indépendantes. C'est ce qui fait la force de ce genre d'architecture.
Par exemple : Une patte du portA peut générer un signal  PWM pour un servomoteur (de façon totalement indépendante), pendant que le premier timer mesure une durée, et que le registre d'interruptions surveille en permanence l'état d'un capteur, et que le registre de conversion A/N fait sa conversion. Ils ne solliciteront le calculateur que pour le départ ou la fin de leur tâche ou lors d'évènements externes. Pendant ce temps, le calculateur peut tranquillement effectuer un calcul pour préparer le prochain "évènement".

==> Le contrôleur est, en quelque sorte, le chef d'orchestre tandis que les registres sont les musiciens. Et votre programme, c'est la partition !!!!

Vous comprenez donc que votre programme va surtout chercher à écrire des mots clés dans les registres adéquats au moment opportun.


Exemples d'extraits de programme utilisant les registres :

TCNT1=0;
Remise à zéro du compteur du chronomètre 1 (TIMER1)

if
(TCNT1=25) {PORTB=0b01101110;}
si le registe TCNT1 (c'est le compteur du TIMER1) est égal à 25, alors il faut écrire l'octet "01101110" sur les pattes du port B.
EEPROM_Write($03,102)
Ecriture de la valeur "102" dans le tiroir "03" de l'EEPROM

SREG
=$80
On règle la clé de registe "SREG" à la valeur 80. (cette clé appartient au registre de gestion des interruptions. Elle autorise toutes les interruptions dans le µC.
Nota : Ces quelques exemples de clés de registres (en bleu) sont utilisés dans l'immense majorité des µC. Il y a quelques différences mineures d'un µC à l'autre. Il n'y a pas besoin de les connaître par cœur puisque le datasheet du composant les détaille tous.




3 /De quoi ais-je besoin pour faire fonctionner un microcontrôleur ?

Alors là, ça va être très rapide ! car le microcontrôleur allège considérablement nos cartes électroniques. Il n'a besoin que de quelques rares composants (très peu !!!) pour fonctionner. Et encore, on peut faire sans.... trop fort !!!

En définitive, le microcontrôleur peut fonctionner dès lors qu'on lui a donné une alimentation 5v bien régulée. C'est le seul critère strictement indispensable. Un régulateur de tension (7805)  ou une alimentation stabilisée ou une alimentation à découpage (MC34063) feront parfaitement l'affaire. Attention, certains µC "modernes" se contentent d'une alimentation 3,3V. Economie d'énergie oblige !



Vous allez me dire "oui mais il a besoin d'une horloge avec des impulsions régulières pour cadencer son fonctionnement".
Et oui ! c'est VRAI ! mais même ça, c'est déjà inclus dans le microcontrôleur. Le seul souci c'est que l'horloge interne n'est pas d'une très grande précision. On préfèrera lui ajouter un quartz, conformément au montage ci-dessus. Les deux pattes qui recevront le quartz portent un nom particulier : XTAL1 et XTAL2.

Remarque :  certaines pattes permettent aussi la programmation du µC.
Mais si vous utilisez une platine d'essais de chez MikroC, cette information ne vous intéresse que très peu.



4/ Comment brancher un microcontrôleur ? Les montages classiques !

On arrive à la partie qui vous intéresse le plus : les branchements ! Pour chaque montage, je vais expliquer comment et pourquoi on s'y prend ainsi.

En premier lieu, voyons les différents états d'une "entrée-sortie" :

- soit elle est réglée pour contrôler quelque-chose ==> donc en sortie, dans ce cas elle peut prendre 2 états

L'état 1 correspond à une patte reliée au 5v tandis que l'état "0" correspond à une patte reliée à la masse. Donc, quand une patte est en sortie, il faut prendre garde à ne pas la relier directement au 5v ou à la masse. Sinon c'est le cour-jus assuré et le µC est mort !

- soit elle est réglée pour "recevoir" une information ==> donc en entrée

L'état est compris comme "0" à condition que la tension d'entrée soit à moins de 1v tandis que l'état "1" est obtenu dès que la tension d'entrée dépasse 4v. Ça offre une certaine flexibilité bien utile dans certains cas.



4-1/ Une seule LED en sortie :

C'est le montage le plus facile !
La patte qui commande l'allumage est en "sortie". il y a deux variantes.
Soit la LED est située entre le µC et la masse, soit elle est située entre le µC et le 5v. Le sens de la LED n'est pas le même dans les 2 cas :

- Reliée à la masse (commun des LEDs à la masse) :  Elle s'allume à l'état "1"


- Reliée au 5v (commun des LEDs au +5v) : Elle s'allume à l'état "0"




4-2/ Deux LEDs en sortie :

C'est un complément aux deux montages ci-dessus. On s'aperçoit que les deux états sont complémentaires. On peut donc les utiliser simultanément pour allumer deux LEDs alternativement. La patte qui commande l'allumage est en "sortie".

A l'état "0",  la LED rouge et R2 sont soumises à aucune tension puisqu'ils sont situés entre la masse et la sortie à 0v. Il ne peut donc y avoir aucun courant dans cette branche. C'est donc la LED verte qui est allumée. A l'état "1",  c'est exactement l'inverse. Remarquez que si la sortie du µC est débranchée, les deux LEDs s'allument !



4-3/ Un bouton poussoir en entrée :

Cette fois, la patte du µC est en "entrée". Surtout pas en sortie ! sinon PAF ! c'est mort !
La tension qui y rentre dépend du circuit qui y est branché. L'appui sur le bouton-poussoir doit permettre d'amener la tension voulue dans l'entrée du µC. Ici aussi, deux montages sont possibles :

- En plaçant le BP entre le 5v et l'entrée du µC, on obtien un niveau "1" lorsqu'on appuie sur le BP.

- En plaçant le BP entre la masse et l'entrée du µC, on obtient un niveau "0" lorsqu'on appuie sur le BP.



4-4/ Un optocoupleur à la place du bouton-poussoir :

    La patte qui reçoit l'information est en "entrée". Surtout pas en sortie ! sinon PAF ! c'est mort !
    L'optocoupleur est un "interrupteur" piloté par de la lumière. Il peut donc laisser passer des fréquences bien supérieures à celles de notre doigt sur le BP. Il est donc TRES tentant de remplacer le bouton-poussoir ci-dessus par un optocoupleur !


C'est TRES exactement ce que je fais pour détecter la trame dans mes décodeurs. La tension rectangulaire de 18v est donnée par les rails. La tension rectangulaire de 5v qui rentre dans le µC est donc l'image de celle qui se trouve dans les rails.

C'est aussi ce genre de montage que j'utilise pour détecter une consommation de courant. Il suffit de placer quelques diodes en parallèle de l'entrée de l'optocoupleur. Voir pour cela la page sur la détection de courant.



4-5/ Commander un relais :

La patte qui commande le relais est en "sortie"
Ça présente un intérêt lorsqu'il faut établir un contact,
de façon continue, entre deux fils. De plus, si les tensions manipulées sont en dehors des tensions que le µC peut supporter, l'utilisation du relais est obligatoire. Le schéma ci-dessous montre comment le µC peut allumer une lumière pour éclairer mon réseau avec une ampoule de 220 volts. (ATTENTION : je rappelle que la tension de 220V est DANGEREUSE !)

Evidemment, le relais peut être utilisé pour toutes les applications classiques. Ici, notre propos consiste à le commander à l'aide du µC.


4-6/ Commander un servomoteur :

C'est probablement ce qu'il y a de plus simple en matière de branchement. La patte du µC est en "sortie". Elle est directement branchée sur le fil de "signal" (généralement jaune) du servomoteur. Aucun autre composant n'est nécessaire.

En revanche, si le branchement est simple, la programmation, elle, est sérieusement plus compliquée. Le signal qui est généré par le µC doit être très précis pour éviter les mouvements parasites. Le programme devra donc utiliser une référence de temps (le TIMER) pour générer les fronts montants ou descendants au moment opportun. Il existe deux solutions. Nous verrons cela sur la page consacrée à la programmation.



4-7/ Commander un moteur à courant continu :


4-7-1/  dans un seul sens :

Malheureusement, le µC seul est rigoureusement incapable de fournir le dixième du courant nécessaire au moteur. Par contre, il peut faire en sorte d'établir un contact pour laisser passer un gros courant jusqu'au moteur.  Il y a deux montages possibles :
- Le montage à base de relais (quasi-identique à celui vu plus haut). Le moteur tournera à la vitesse maximale (constante) autorisée par sa tension d'alimentation :


- Le montage à base de transistor de puissance. Ce montage est utilisé quand on veut piloter la vitesse du moteur. En effet, le transistor peut être commandé en MLI (Modulation de Largeur d'Impulsion =PWM en Anglais) afin de diminuer la tension moyenne appliquée au moteur. Attention cependant à utiliser un transistor de puissance qui supporte le courant de démarrage du moteur. Un transistor "darlington" sera préféré car il contient plusieurs transistors en cascade et possède une amplification plus importante.



4-7-2/ dans les deux sens :

Là encore, on trouve les deux solutions :
- A l'aide d'un relais pour l'inversion du sens de rotation : Deux sorties sont nécessaires. L'une d'elles contrôlera le sens de rotation grâce à son action sur le relais. L'autre contrôlera la mise en marche grâce à son action sur le transistor de puissance. Ici encore, le transistor peut être commandé à l'aide d'un signal M.L.I. afin de contrôler la vitesse du moteur. Cette solution fait appel à 5 composants...PAS GLOP !


- A l'aide d'un pont de transistors :  Quand
on peut se passer de relais (élément souvent défaillant et cher) on s'en passe ! Il faut alors utiliser un "pont en H" à l'aide de 4 transistors de puissance. Ça marche bien et c'est assez solide.

Les deux sorties A0 et A1 servent à contrôler la vitesse en générant une M.L.I., tandis les sorties A2 et A3 servent à inverser le sens de circulation du courant.



4-7-3/ avec un driver de moteur :

C'est un bien grand mot pour pas grand-chose ! Le "driver" de moteur est  l'équivalent du pont de transistors vu précédemment. Sauf qu'ils sont encapsulés dans un circuit intégré. Il possède quelques pattes en plus pour "valider" la mise en marche. Je connais deux références célèbres (L293D ou SN754410NE) mais il en existe d'autres. J'ai utilisé le SN754410 pour le décodeur de la plaque tournante.

Ce composant peut controler de 2 à 4 moteurs (ça dépend des sens de rotation souhaités). Je ne montre ici qu'un seul coté, mais le second coté possède un câblage identique pour un second moteur. Il est possible d'économiser la sortie A2 du µC en inversant l'état de A1. Ces deux commandes sont opposées en permanence.



4-8/ Mesurer une tension (convertisseur analogique => numérique)

Difficile de proposer un montage spécifique... tout se passe à l'intérieur du µC. L'objectif c'est de transformer une valeur analogique (entre 0v et 5v) en une valeur numérique de façon à pourvoir faire des calculs avec.

La façon la plus simple de faire varier une tension c'est d'utiliser un diviseur de tension. Le point central du potentiomètre est relié à l'entrée du µC. Il suffit de faire tourner le bouton du potentiomètre pour changer la tension "U" qui rentre dans le µC.


En fonction de "la tension observée le µC va générer un chiffre" qui est l'image de la valeur lue.



2-10/ Générer une tension (convertisseur numérique => analogique)

C'est exactement l'opération inverse du montage précédent. Ça correspond à ce que fait votre lecteur de CD ! Il lit une suite de "1" et de "0",  et lorsqu'il a constitué un octet, il transforme cet octet en une tension sur une patte. Il n'y a pas de montage spécial, tout se passe à l'intérieur du µC. Il faut seulement piger que "en fonction du chiffre de l'octet, le µC associe une tension sur une patte"
Valeur de l'octet
Tension générée

0
0v
1
0.019v
2
0,039v
...
...
255
5v
Attention, la tension est générée, mais le µC ne peut toujours pas fournir d'intensité élevée. Pour contrôler un élément, il faudra faire appel à un transistor.




5/ Comment insérer un programme dans la "puce" ?


Je passe sur l'étape d'écriture du code, qui demande une initiation au langage C et une page dédiée au programme du décodeur.
Une fois que le programme est terminé, compilé, transformé en langage machine, il faut l'implanter dans la puce. Il existe au moins 2 méthodes :
 - Il est possible de programmer le µC directement sur la carte où il travaille. Cela suppose qu'il y a un port ISP (In Situ Programming) sur cette carte. D'ailleurs, vous avez remarqué que le µC possède des pattes dédiées à la programmation. Ce n'est pas la méthode que je préfère car les décodeurs sont déjà bien denses sans avoir de port dédié à la programmation. En plus cela fait appel à une carte d'interface entre le PC et le µC. Il existe de nombreux sites qui donnent des schémas en tous genres. Celui-ci conclue même que ma seconde solution est finalement la meilleure...

- Ma seconde solution, la voici : Je préfère ne pas avoir à gérer le port ISP sur mes cartes, donc je fais appel à carte de développement qui fait cela très bien et qui gère la communication avec le PC. Il faut seulement placer le µC sur le support adapté à sa taille puis lancer le chargement du programme. On replace ensuite le µC sur la carte définitive. C'est fini !

Cette platine permet de programmer plusieurs sortes de µC. Elle permet même de faire les tests directement sur la carte. C'est un peu cher au départ (quoique...) mais ça aide bien et c'est très fiable.
Celle-ci est vendue avec le logiciel de programmation en langage C : "MikroC Pro".
Pour l'utilisation, je vous invite à me poser des questions précises, ou à vous référer au forum du fabricant "MikroElectronica"



EN CONCLUSION :

En détaillant les montages et le fonctionnement, vous remarquez que j'ai, à chaque fois, insisté sur l'état  logique des pattes d'entrées-sorties. Votre programme devra donc tout faire pour que les ports d'entrée-sortie reçoivent l'état que vous souhaitez au moment où vous le souhaitez. Il faudra pour cela vous aider des registres qui gèrent tout là-dedans.

Avant de passer à la programmation il me semble nécessaire d'ajouter quelques compléments sur ces fameux registres du µC. C'est l'objet de la prochaine page.

Ensuite, nous pourrons aborder la partie "Programmation".
- Les commandes de base avec les registres

- La programmation du décodeur


C'est tout pour aujourd'hui.
N'hésitez pas à me signaler des erreurs à l'adresse habituelle : (enlevez tous les "z" dans l'adresse)

mise à jour le 10/08/2016