Le monde des micro contrôleurs Périphériques des micro contrôleurs Éléments de programmation du 12F509 Éléments de programmation du 12F675 |
Sous le nom "périphériques", je décris ici les dispositifs commandés ou lus par le MCU.
C'est la première utilisation à laquelle on pense lorsqu'on veut réaliser une animation : allumer différentes lumières. Il existe des ampoules à filament miniatures, mais le composant le plus utilisé dans ce rôle est la diode électroluminescente, plus connue sous son acronyme anglais "LED" (Light Emitting Diode). Contrairement à une ampoule, une LED est polarisée, c'est à dire qu'une de ses broches, appelée "anode", doit être reliée au pôle positif, l'autre, appelée "cathode", au pôle négatif. En général, la broche la plus longue est l'anode (broche positive). ![]() Pour pouvoir émettre de la lumière, une LED doit être traversée par un courant constant. Ce courant est une des données techniques de la LED, l'autre donnée à prendre en compte est la chute de tension à ses bornes (UL). Les LEDs standards travaillent avec un courant compris entre 10 et 20 mA et une valeur de UL d'environ 2 V. Ces valeurs varient suivant la couleur, elles sont fournies avec la fiche descriptive de la LED. Pour limiter le courant alimentant une LED, quand on a une tension supérieure à UL, le moyen le plus simple est d'intercaler une résistance, du côté positif ou de l'autre, ça n'a pas d'importance. Pour calculer la valeur de cette résistance, on applique la loi d'Ohm sous sa forme :
Dans notre cas, la tension U à prendre en compte est en réalité la tension d'alimentation (Ubat) diminuée de UL. La formule devient donc :
où R est en ohms, Ubat et UL en volts et I en ampères. Prenons un exemple concret : nous avons une LED rouge, fonctionnant avec une intensité (I) de 10 mA (0.01 A) et ayant une chute de tension (UL) de 2 V. Nous l'alimentons avec une tension (Ubat) de 5 V. La valeur de la résistance sera : (5 - 2) / 0.01 = 300 que nous arrondissons à 330 ohms. Le schéma électronique correspondant est le suivant : ![]()
Le MOSFET (Metal Oxide Semiconductor Field Effect Transistor) est un transistor, il a trois broches, appelées G (Gate ou Grille), S (Source) et D (Drain). Une tension appliquée entre les broches G et S permet de commander le passage d'un courant entre les broches S et D. ![]() Comme on peut le voir sur le schéma, la grille est isolée électriquement des autres électrodes, ce qui donne une impédance (résistance) d'entrée très élevée, de l'ordre de 1018 ohms (1 suivi de 18 zéros). En pratique, on pourrait considérer que le transistor est commandé par une tension et non par l'intensité entre grille et source. Ce n'est pas tout à fait le cas : l'entrée G est en réalité un condensateur de faible capacité et un courant circule au moment où la tension est appliquée. On n'en tient pas compte en général, mais, si on veut que le transistor réagisse très rapidement, il faut en tenir compte et ne surtout pas intercaler une résistance sur l'entrée, qui jouerait le rôle d'un retardateur. Par contre, ce condensateur est le seul point faible du MOSFET : l'isolant est très mince et peut être détruit si on applique une tension trop élevée entre les broches G et S (20 V pour un BS170). La courbe de gain (variation de la tension d'entrée commandant le courant de sortie) est très abrupte, passé un certain seuil de tension, le transistor laisse passer le courant avec une résistance de passage très faible, de l'ordre du 1/10ème d'ohm. En utilisant les sorties d'un MCU (0 ou 5 V), le transistor se conduit comme un interrupteur. Avec un boîtier de taille réduite, le MOSFET permet de faire passer des intensités relativement élevées, par exemple 500 mA en continu pour le BS170 en boîtier TO92. ![]() Du fait de son impédance d'entrée élevée et de sa faible résistance de passage, il est possible de brancher plusieurs MOSFETs en parallèle pour augmenter l'intensité commandée, les intensités de sortie se répartissent en fonction de la résistance de passage de chaque transistor et aucun composant additionnel n'est nécessaire. L'examen du schéma montre qu'une diode est intégrée entre les broches S et D, elle sert de protection lorsqu'on commande une charge inductive, telle qu'un électro-aimant, un relais ou un moteur électrique. Les tensions d'entrée et de sortie peuvent être de sources différentes, mais les masses doivent être communes, comme dans le schéma ci dessous : ![]()
Nous avons vu que brancher une seule LED sur une sortie du MCU est facile. Le problème se complique un peu lorsqu'on veut en brancher plusieurs. Il existe deux possibilités : le branchement en série ou le branchement en parallèle. Pour les exemples ci-dessous, j'utilise les mêmes LEDs rouges que précédemment, avec UL = 2 V et I = 0.01 A (j'en ai tout un stock).
![]() Ce branchement est à utiliser quand toutes les LEDs ont les mêmes caractéristiques de tension (UL) et d'intensité, la valeur de la résistance intercalaire est donnée par la formule :
Il y a toutefois une limite : la tension Ubat doit être supérieure ou égale à la somme des tensions UL, lorsque la tension Ubat est égale à la somme des UL, la résistance n'est pas nécessaire : ![]()
![]() C'est le schéma de base, chaque LED a sa propre résistance, et peut donc avoir des caractéristiques différentes des autres. On peut vouloir économiser toutes ces résistances et n'en utiliser qu'une seule, dans le cas où toutes les LEDs sont de mêmes caractéristiques : ![]() La valeur de la résistance intercalaire est donnée par la formule :
Il y a, là encore, une limitation qui est la puissance maximale que peut dissiper la résistance. Cette puissance est calculée par la formule :
P est en watts (W), U est la tension aux bornes de la résistance (Ubat - UL) en volts (V) et I est l'intensité en ampères (A). La puissance maximale que peut dissiper une résistance standard est 0.5 watt. Dans le schéma ci-dessous, la somme des intensités est égale à 0.06 A, La tension aux bornes de la résistance est égale à 10 V, la puissance qu'elle doit dissiper est donc : 10 V * 0.06 A = 0.6 W, ce qui est trop important, pas de beaucoup, mais la résistance va chauffer et se détériorer dans le temps. ![]() Donc, sauf cas particulier, il est préférable d'utiliser une résistance par LED lors des branchements en parallèle.
Jusqu'à présent, je n'ai parlé que d'un modèle de transistor : le BS170, un MOSFET de type canal N. Les MOSFETs canal N sont les plus courants et les plus faciles à mettre en oeuvre : à partir d'une tension de commande faible, ils agissent comme des interrupteurs entre la tension de référence (0 V) et le dispositif à commander, sans nécessiter de composant supplémentaire. Il existe aussi des MOSFETs de type canal P, complémentaires des types N, dont je parle plus loin. Si vous voulez approfondir la théorie, vous pouvez lire l'article sur les MOSFETs dans Wikipedia. Mais cela n'a rien d'une obligation, les composants fonctionneront quand même ! Revenons au BS170 qui peut commander un courant jusqu'à 500 mA. Si vous avez besoin d'un courant supérieur, il vous donc faut choisir un autre composant. Les principaux critères de choix sont l'intensité et la tension maximales. Il vous faut donc, en première approche, sélectionner quelques modèles dans le catalogue de votre fournisseur préféré, puis rentrer dans les détails en consultant leurs fiches de caractéristiques (datasheets en anglais). Il n'existe pas de datasheet en français, mais il n'y a pas besoin d'être un expert pour les lire. Les caractéristiques à prendre en compte sont :
D'autres caractéristiques sont à vérifier, qui concernent les temps de fermeture ou d'ouverture de la liaison Source/Drain (td(on) , tr, tf et td(off)), tant qu'elles sont exprimées en nanosecondes, c'est bon. Bonne recherche dans les datasheets !
Nous avons vu que le MOSFET canal N conduit lorsqu'on applique une tension positive sur la broche G et qu'il agit comme un interrupteur polarisé sur le 0 V. Cela convient pour la plupart des cas, mais, quelquefois, il est nécessaire que le transistor conduise lorsque la tension de commande est inférieure à + V, par exemple pour interrompre une alimentation du côté positif ou pour commander un montage de pont en H (dont je parle plus loin). Le composant permettant cela est le MOSFET canal P, qu'on appelle complémentaire du canal N. Lorsqu'on regarde sa datasheet, on constate que les tensions (et les intensités) sont exprimées avec des valeurs négatives. Avec ce transistor, la tension de référence (0 V) est mesurée à partir du pôle positif de l'alimentation. Lorsque cette tension de référence est appliquée à la Gate, le transistor est bloqué, pour qu'il conduise, il faut lui appliquer une tension inférieure à sa caractéristique -VGS(th). Le composant à commander sera branché entre le pôle négatif de l'alimentation (- V) d'un côté et au Drain du transistor de l'autre côté. J'en vois dans le fond qui ont l'air de n'avoir pas tout compris bien ! Faisons le parallèle avec un MOSFET canal N, utilisé pour commander un moteur, le schéma est le suivant : ![]() Lorsqu'on applique une tension positive sur la broche G, le transistor conduit et le moteur reçoit du 0 V sur la borne reliée à la broche D. Comme l'autre borne est reliée au + V, le moteur tourne. Voyons maintenant le schéma pour commander ce même moteur avec un MOSFET canal P : ![]() Comme on peut le voir, tout est inversé par rapport au canal N : la source est branchée côté +0 V et le drain côté -5 V (à travers le moteur). (À noter que j'ai écrit +0 V pour bien marquer que cette ligne est reliée au pôle positif de l'alimentation et donc le -5 V est relié au pôle négatif.) Le transistor conduit lorsque la broche G reçoit une tension négative par rapport à la référence 0 V. Le moteur va alors recevoir du 0 V sur la borne reliée à la broche D et du -5 V sur l'autre, il va donc tourner ! À part les inversions des signes de polarité, les deux schémas sont très proches. Par contre, les choses vont se compliquer lorsqu'on utilise un MOSFET canal P dans un circuit ayant deux alimentations de tensions différentes et dont les masses (pôles négatifs de l'alimentation) sont communes. Dans ce cas, la tension de commande risque de ne pas être assez proche du +0 V pour bloquer le transistor. Il est alors nécessaire d'ajouter une résistance dite de "pullup" qui va forcer le blocage en l'absence de signal de commande et un interrupteur, activé par la tension de commande, servant à envoyer le -V sur la broche G : ![]() Lorsque l'interrupteur S est fermé, il envoie du -V sur la broche G et le transistor conduit. Plutôt que d'employer un interrupteur mécanique commandé par une tension, nous allons utiliser un petit MOSFET canal N, qui est tout indiqué pour cet emploi : ![]()
Avant d'entrer dans le vif du sujet, je reviens sur le dernier schéma du MOSFET canal P pour indiquer les tensions sous une forme plus conventionnelle : ![]() Dans ce schéma, le petit MOSFET et la résistance agissent comme un pilote de MOSFET (MOSFET driver) inverseur : ![]() Le montage est dit "inverseur" car lorsqu'on applique une tension de 0 V sur l'entrée "in", on obtient une tension positive, égale à la "haute" tension, sur la sortie "out", de même qu'une tension positive sur l'entrée produit une tension de 0 V sur la sortie. Ce montage peut être repris tel quel pour piloter un gros MOSFET canal N, comme dans le schéma ci-dessous : ![]() Mais pourquoi utiliser un pilote sur un MOSFET canal N, alors qu'il fonctionne déjà très bien en appliquant une tension de +5 V sur la broche G ? Il y a plusieurs bonnes raisons pour faire cela :
Toutes ces raisons (et d'autres) font qu'il y a, sur le marché, environ un millier de références de pilotes de MOSFETs en circuits intégrés. L'intégration permet de produire des composants de faible taille, d'excellentes caractéristiques et de plus faible coût (pour le fabricant, pas forcément pour le client ! ) que les composants qu'il remplace. Parmi cette multitude, j'ai choisi de vous parler de la série des TC4426, TC4427 et TC4428, fabriqués par Microchip. D'abord parce que j'en ai un sous les yeux sur mon bureau, ensuite parce qu'ils ont une architecture relativement plus récente que certains autres modèles. Le diagramme fonctionnel, extrait de la datasheet, est le suivant : ![]() Nous y trouvons le MOSFET canal N en entrée, la résistance est remplacée par un générateur de courant constant, tout un tas d'autres composants (il faut bien que les concepteurs justifient leurs salaires) et une sortie de type CMOS. Il y a deux pilotes par boîtier. Le TC4426 a deux pilotes inverseurs, le TC4427 deux pilotes non inverseurs et le TC4428 un pilote inverseur et un pilote non inverseur. En utilisant la moitié d'un circuit TC4426, le schéma du circuit avec le MOSFET canal P devient le suivant : ![]() L'entrée "in 1" commande la sortie "out 1". Si l'entrée "in 2" n'est pas utilisée, il faut la relier à la masse.
Les commandes par MOSFETs que nous avons vues jusqu'à présent ne laissent passer le courant que dans un sens, dans le cas d'un moteur électrique, par exemple, je ne peux donc le faire tourner que dans un sens ou l'arrêter. Le montage que je propose maintenant permet d'inverser la tension au bornes de la charge. En électromécanique, cela se réalise avec deux interrupteurs inverseurs suivant ce schéma : ![]() Quand I1 est en bas et I2 en haut, le moteur tourne dans un sens, I1 en haut et I2 en bas, le moteur tourne dans l'autre sens, quand I1 et I2 sont tous les deux en haut ou tous les deux en bas, le moteur ne tourne pas. Ce montage s'appelle un pont en H et des tonnes de littérature ont été écrites à son sujet. Comme je veux faire un montage avec des MOSFETS, qui ne savent pas inverser les tensions, je modifie ce schéma électromécanique en utilisant des interrupteurs couplés mécaniquement, comme ceci : ![]() Pour obtenir ce genre de montage en électronique, nous allons utiliser, dans chaque branche du H, un MOSFET canal N et un MOSFET canal P. Leur entrées G seront reliées ensemble et leurs sorties D aussi, suivant ce schéma : ![]() Lorsque l'interrupteur S est ouvert, la broche G du MOSFET canal P reçoit du +12 V (+0 V dans sa logique), via la résistance de 10 K et le transistor est bloqué (il ne conduit pas), la broche G du MOSFET canal N reçoit elle aussi du +12 V et le transistor conduit, nous trouvons donc du 0 V sur la sortie "out". Lorsque l'interrupteur S est fermé, la broche G du MOSFET canal P reçoit du 0 V (-12 V dans sa logique) et le transistor conduit, la broche G du MOSFET canal N reçoit elle aussi du 0 V et le transistor est bloqué, nous trouvons donc du +12 V sur la sortie "out". Bien évidemment, nous n'allons pas utiliser un interrupteur mécanique, mais un petit MOSFET, comme dans les exemples précédents : ![]() Le schéma complet, avec les petits MOSFETs et les résistances est le suivant : ![]() Lorsque l'entrée "in 1" reçoit du +5 V et l'entrée "in 2" du 0 V, le moteur tourne dans un sens, quand on inverse ces tensions sur les deux entrées, le moteur tourne dans l'autre sens. Lorsque les deux entrées reçoivent les même tensions, les deux bornes du moteur sont mises en court circuit et, s'il tournait, il est freiné. Pour terminer, voici le schéma utilisant le pilote de MOSFETs TC4426, permettant de s'affranchir des petits MOSFETs et des résistances : ![]() Avec un boîtier huit broches et quatre MOSFETs, il va être difficile de faire plus dépouillé !
Quand on parle de périphériques, on pense tout d'abord à ceux de sortie. Un MCU peut aussi recevoir des entrées de l'utilisateur. Le cas le plus fréquent est le bouton poussoir, servant à configurer un mode de fonctionnement, par exemple. Pour lire la position d'un bouton, on pourrait penser qu'il suffit de configurer un port en entrée, sur lequel on brancherait le bouton et de tester la valeur reçue, 0 ou 1. Les choses ne sont pas aussi simples. Il faut tout d'abord décider de la tension à appliquer lorsque le bouton est enfoncé. Si on choisit que ce sera le +V, il faut maintenir le port à 0 V quand le bouton est relâché, ce qui se fait en branchant une résistance de quelques kilohms entre le 0 V et le port. Cette résistance s'appelle "pull-down" (tirer vers le bas) et nous fait ajouter un composant supplémentaire. Heureusement, la plupart des MCU ont la possibilité d'activer des résistances internes, dites de "pull-up" (tirer vers le haut) sur les ports en entrée. Comme leur nom l'indique, elles sont connectées au +V et évitent donc tout composant supplémentaire. Le bouton sera alors connecté au 0 V et, quand il sera enfoncé, le port sera mis à zéro. Pour activer cette résistance sur le port GP0 d'un PIC 12F675, les instuctions suivantes sont nécessaires :
Un autre problème se pose : un bouton est un élément électromécanique et le contact ne s'établit pas instantanément, mais par rebonds.
Pour être sûr que le contact soit bien établi, on peut brancher une résistance et un condensateur sur le port, pour lisser et stabiliser la tension.
Ce qui nous fait deux composants supplémentaires. On peut éviter cela par programme en attendant quelques millisecondes pour que la
tension sur le port soit bien stable. C'est le but du sous-programme "
La fonction de bibliothèque "__delay_ms()" attend que le nombre de millisecondes qui lui est passé en paramètre soit écoulé.
Un clavier est un autre périphérique d'entrée utilisable par un MCU. Il se présente sous la forme d'un panneau de plusieurs touches, qui actionnent des boutons poussoirs. Voici, par exemple, un clavier de 12 touches qui va nous servir pour la suite : ![]() Les touches sont rangées en quatre rangées, appelées R1 à R4, sur trois colonnes, appelées C1 à C3. Pour économiser les connexions, les boutons sont branchés en parallèle sur les conducteurs des lignes et des colonnes, suivant le schéma ci-dessous : ![]() Ce genre de montage s'appelle une matrice d'interrupteurs et ce genre de clavier est un clavier matriciel (ou matricé). Il n'y a que 7 connexions, au lieu de 24 si tous les boutons poussoirs étaient indépendants. En réalité, sur ce clavier particulier, il y a 9 connexions car les colonnes C1 et C2 sont doublées, pour des problèmes de réalisation. Son brochage est indiqué sur la photo ci-dessous : ![]() Pour trouver le bouton qui a été enfoncé, le programme va appliquer successivement une tension sur chacune des rangées et il va lire chaque colonne jusqu'à retrouver la tension correspondante. Pour éviter des composants supplémentaires, nous allons utiliser le 0 V et activer les résistances de "pull-up" sur les entrées C1, C2 et C3. Par exemple, si j'appuie sur la touche "8", lorsque le programme envoie du 0 V sur la rangée R3, il va trouver du 0 V sur la colonne C2 et seulement sur celle-là. Le sous-programme ci-dessous a été écrit pour un PIC 16F1825, qui a suffisamment de broches pour cet usage. Tous les bits du port C sont configurés en sortie et connectés aux rangées R1 à R4. Les bits 3, 4 et 5 du port A sont configurés en entrée et connectés aux colonnes C1, C2 et C3, leurs résistances de "pull-up" sont activées. Le sous-programme de décodage se présente comme suit :
La valeur de retour sera zéro si aucune touche n'est enfoncée ou le numéro de la touche, dans l'ordre "1", "2", "3", "4", "5", "6", "7", "8", "9", "*", "0" et "#".
Un potentiomètre est un autre périphérique d'entrée utilisable par un MCU. Il se présente sous diverses formes, tailles et types. En voici quelques exemples : ![]() C'est une résistance variable avec trois bornes, les deux bornes extérieures de la résistance sont reliées à une source de tension, la borne centrale est relié à un curseur, permettant de délivrer une tension variable en fonction de la position du bouton de commande. Le type qui nous intéresse pour nos applications est le type linéaire, qui délivre sur le curseur une tension proportionnelle à la position angulaire. Nous utiliserons un modèle ayant une résistance comprise entre 5 et 50 kOhms. La tension aux bornes peut ne pas être strictement proportionnelle à la position de l'arbre, il s'agit, là encore, d'un dispositif électro-mécanique, imparfait du point de vue électronique. De plus, il peut y avoir des variations d'un modèle à l'autre dans une même série. Pour lire la tension présente sur le curseur, nous allons utiliser un convertisseur analogique vers numérique (ADC), présent dans la plupart des MCUs.Nous allons brancher les bornes extérieures du potentiomètre entre le 0 V et le + V et le curseur sur une entrée analogique du MCU. Le principe étant le même pour la plupart des MCUs, je vais utiliser le PIC 12F675 pour les explications. La précision maximum du convertisseur de ce circuit est de 10 bits, soit une valeur variant de 0 à 1023. Il dispose de quatre entrées analogiques, mais d'un seul circuit de conversion, ce qui oblige à lire les entrées les unes après les autres. Dans l'exemple, je vais n'utiliser qu'une seule entrée, appelée AN0 qui se trouve sur la broche GP0. Pour commencer, il faut initialiser le convertisseur :
Pour lire la valeur d'une entrée analogique, le sous-programme suivant est utilisé :
Comme dit précédemment, du fait des imprécisions du système mécanique, le résultat ne sera pas une valeur angulaire précise au 1/1024ème. Le programme devra tenir compte de cela.
Un encodeur rotatif est un périphérique d'entrée qui envoie une information en fonction de la position angulaire de son arbre. Contrairement au potentiomètre, qui est limité dans sa possibilité de rotation, l'encodeur rotatif n'a pas de butée et son arbre peut effectuer un nombre infini de tours. Un de ses usages courants est la roulette de la souris d'un ordinateur ou le bouton de recherche de stations sur un autoradio. Il est parfois couplé à un ou plusieurs boutons poussoirs. Il existe deux types d'encodeurs :
Voici une photo de deux codeurs de type incrémental, celui de droite dispose de 5 boutons poussoirs : ![]()
Il y a un certain nombre de positions pour un tour complet de l'arbre, dépendant des modèles. À chaque changement de position, les valeurs sur les broches de sortie changent suivant un ordre bien précis. La valeur de ces broches est vu par le MCU comme un nombre sur deux bits, pouvant donc prendre les valeurs "00", "01", "10" et "11". Voyons comment cela se passe avec le dessin ci-dessous : ![]() Les lignes rouges indiquent les changements de position, les nombres dans les rectangles verts sont le résulat de la valeur précédente multipliée par 4 et additionnée à la valeur courante. Nous voyons que pour chaque sens de rotation, il n'y a que 4 valeurs possibles :
Voici un exemple de sous-programme, il peut être appelé par une interruption déclenchée par un changement d'état sur les broches d'entrée ou par un timer :
Les broches de l'encodeur sont connectées sur les broches RA0 et RA1 d'un MCU disposant d'un port A. Le tableau "state[ ]" contient les indications de direction, rangées dans l'ordre des valeurs définies précédemment. Il n'y a pas de détection des rebonds dans ce bout de code. Une solution pourrait être de vérifier que les entrées restent dans le même état pendant un certain temps avant de les utiliser, ce temps étant à déterminer en fonction de l'utilisation.
Nous entrons là dans le domaine professionnel et il y a une multitude d'offres, la plupart à des tarifs laissant rêveur ! Il existe pourtant un composant accessible aux amateurs, appelé EAW ACE-128 et fabriqué par Bourns. Il est vendu environ 8.50 €. Comme son nom l'indique, il y a 128 positions pour un tour complet de l'arbre et la valeur absolue de la position est disponible sur 8 broches, 2 autres broches sont utilisées pour donner la référence 0 V. C'est un composant électro-mécanique, avec toutes ses imperfections (rebonds) et il a une durée de vie donnée pour 50 000 tours minimum. Ce n'est pas spécifié, mais il est fort probable qu'une vitesse de rotation élevée doit l'abréger. Puisqu'il y a huit broches pour lire la valeur, on aurait pu penser qu'on retrouverait directement un résultat variant séquentiellement de 0 à 127. Il n'en est rien et il faut utiliser une table de transcodage pour retrouver une valeur humainement logique. Le code nécessaire se trouve ci-dessous :
Il existe aussi quelques encodeurs magnétiques sans contact qui offrent de meilleures performances mécaniques (durée de vie supérieure à cent millions de tours et un régime de rotation jusqu'à 10 000 tours par minute), avec une résolution pouvant aller jusqu'à 1024 positions par tour. Leurs prix (à partir de 35.00 € HT) sont relativement modérés, mais s'éloignent quand même d'un budget amateur.
L'usage habituel d'un servomoteur (servo) est d'être branché sur une prise d'un récepteur de radiocommande. Mais on peut également le brancher sur une broche de sortie d'un MCU et lui envoyer le signal qu'il attend. Ce signal est une impulsion de largeur variable (PWM = Pulse Width Modulation), variant entre 900 et 2100 µs, répétée à intervalle régulier, généralement de l'ordre de 20 000 µs (50 hz). Certains servos de type numérique peuvent accepter une fréquence de répétition plus rapide, mais il vaut mieux expérimenter auparavant. Le neutre est indiqué par une impulsion de 1500 µs. Les variateurs pour moteurs à balais et les contrôleurs pour moteurs sans balai se commandent aussi avec ce genre de signal. L'impulsion de commande est générée en mettant à l'état 1 la broche durant le temps voulu et en la remettant à l'état 0 durant le temps restant pour l'impulsion de répétition. Ceci implique donc l'utilisation d'un timer. Je donne deux exemples de code. Dans les deux, le timer 1 est réglé pour compter directement en microsecondes. Le premier est un sous-programme appelé régulièrement à chaque intervalle de répétition, généré par ailleurs par un moyen que je ne détaillerai pas :
Dans l'exemple ci-dessus, le sous-programme d'interruption sert juste à positionner un indicateur lorsque le temps est écoulé. Le deuxième exemple génère l'impulsion et l'intervalle de répétition directement dans le sous-programme d'interruption :
Cet exemple permet de ne pas bloquer pas le reste du programme, comme le faisait le premier avec la boucle d'attente de l'indicateur de temps écoulé.
Un moteur pas-à-pas est un moteur sans balai (brushless) qui ne se déplace que d'une fraction de tour à la fois. On peut ainsi le positionner à un angle précis et lui faire effectuer autant de tours que nécessaire. Il est constitué d'un arbre rotatif portant des aimants permanents, appelé rotor, et d'une partie fixe supportant des électro-aimants, appelée stator.
Il y a 4 modes de fonctionnement :
Le choix du mode de fonctionnement dépend de l'utilisation envisagée :
Il existe 2 types de moteurs pas-à-pas :
Pour faire tourner le moteur, le programme de commande doit donc exécuter les instructions d'activation des électro-aimants dans le bon ordre et avec la bonne temporisation, pour que le rotor ait le temps de se positionner entre deux pas.
Dans le cas d'un moteur unipolaire, les sorties "A" à "D" sont directement reliées à des transistors commandant les électro-aimants. Dans le cas d'un moteur bipolaire, les sorties "A" à "D" sont reliées aux entrées des deux ponts en H, pour pouvoir activer avec la bonne polarité les couples de bobines "A+C" et "B+D". Dans le programme, les valeurs sont rangées dans un tableau, indiquant les bits du port à positionner. Le tableau est parcouru dans l'ordre croissant pour le sens horaire et dans l'ordre décroissant pour le sens inverse. Par exemple :
Ce sous-programme déplace le moteur d'un pas à chaque appel, il est appelé autant de fois que nécessaire. Le bit 0 du port est relié à "A", le bit 1 à "B", le bit 2 à "C" et le bit 3 à "D".
Deux programmes complets se trouvent dans les descriptions de montage pour le PIC 12F675. Ils utilisent le moteur 28BYJ-48, que l'on trouve un peu partout à moins de $3.00, port compris, avec son driver basé sur un circuit ULN2003, sa prise et 4 LEDs de contrôle : ![]() Évidemment, à ce prix, il ne faut pas s'attendre à une grande qualité de réalisation. Voici deux photos de l'intérieur : ![]() ![]()
Un afficheur 7 segments est un périphérique de sortie utilisable par un MCU, permettant d'afficher une valeur numérique. Il se présente sous divers types, tailles et couleurs. Il peut être composé d'un seul afficheur ou de blocs de 2, 3, 4 (ou plus) afficheurs. Il existe deux modèles dans les blocs de 4 afficheurs : un pour réaliser des instruments de mesure, où il y a 4 points décimaux et un autre pour réaliser une horloge, où les deux diodes superposées entre les deux afficheurs du milieu remplacent les points décimaux. Voici, par exemple un afficheur quadruple, monté sur une plaquette d'essais : ![]() Il est constitué de huit LEDs, nommées selon le dessin ci-dessous : ![]() Lorsqu'on a affaire à un bloc d'afficheurs, les cathodes ou les anodes des LEDs de chaque afficheur sont reliées ensemble, comme dans les schémas ci-dessous : ![]() Le schéma du haut montre un montage à cathodes communes (CC, Common Cathode), celui du dessous un montage à anodes communes (CA, Common Anode). Le dessin ci-dessous montre le brochage vu de dessus d'un bloc de 4 afficheurs à cathodes communes : ![]()
Pour afficher un nombre à plusieurs chiffres, nous devons afficher chaque chiffre successivement, en alimentant pendant un certain temps les LEDs des segments A à DP et la broche commune du chiffre à afficher. Si la vitesse de changement est suffisamment élevée, la persistance rétinienne ne permet pas de distinguer de clignotement. Par exemple, ce sous-programme, activé par un timer, permet de piloter un bloc de quatre afficheurs à cathodes communes :
Pour dessiner correctement un chiffre, nous avons besoin d'une table indiquant les segments à allumer. C'est ce qui est réalisé dans le sous-programme suivant, toujours pour des afficheurs à cathodes communes :
Chaque LED nécessite un courant d'une dizaine de mA, il faut donc intercaler une résistance de limitation entre la sortie du MCU et la broche de l'afficheur. Il existe des réseaux de huit résistances, qui se présentent sous la forme d'un circuit intégré de 16 broches et évitent donc d'avoir à positionner et souder chaque résistance une à une. La broche commune peut nécessiter un courant pouvant aller jusqu'à 90 mA, ce que le MCU pourrait ne pas être capable de fournir.
Il faut donc intercaler, dans ce cas, un petit MOSFET entre les sorties du MCU et chaque broche commune, comme dans le schéma ci-dessous : ![]()
Jusqu'à présent, nous avons vu des périphériques qui ne fournissent ou ne nécessitent que peu d'informations. Il y en a toutefois d'autres qui ont besoin de plus, par exemple un afficheur graphique ou un module GPS. Pour satisfaire ce besoin, plusieurs interfaces ont été développées au cours du temps, permettant d'envoyer ou recevoir beaucoup d'informations tout en minimisant le nombre de connexions. Je vais en énumérer quelques unes, compatibles avec les MCUs, sans trop entrer dans les détails. J'approfondirai par la suite, si nécessaire.
|