Sie sind auf Seite 1von 6

Modulation de Largeur d'Impulsion (MLI, PWM)

Il est trs souvent ncessaire de faire varier la puissance transmise une charge. Par exemple, l'intensit d'une lampe doit varier ou la vitesse d'un moteur doit tre rgle. La premire ide qui vient l'esprit est de faire varier la tension ou le courant dans la charge. Mais il faut pour cela des circuits lectronique complexes. Il est gnralement beaucoup plus simple d'alterner des instants o la puissance maximale est transmise la charge avec des moments o aucune puissance n'esttransmise. La technique la plus utilise est la Modulation de Largeur d'Impulsion (MLI) ouPulse Width Modulation (PWM) en anglais.

Comme on le voit sur la figure, le signal est de priode constante, mais la dure de la partie active du signal varie. Dans la premire partie, 25% de la puissance maximale est envoye la charge, vu que le signal est 1 durant 25% du temps alors qu'il est 0 le reste du temps. De mme, la puissance passe 50% au milieu du trac et 75% sur la dernire partie. La frquence du signal va dpendre de l'application. Pour commander une diode lumineuse, la frquence doit tre suprieure 100Hz, pour que l'oeil humain ne voie pas le clignotement. Dans ce cas, c'est bien l'oeil qui effectue l'intgration du signal pour en percevoir une valeur moyenne. Pour un moteur courant continu, ce sont la fois l'inductance de son circuit lectrique et son inertie qui participent cette intgration. Les frquences des signaux PWM peuvent aller couramment jusqu' des centaines de kHz. Mais plus la frquence est leve, plus les pertes lectriques l'instant des commutation sont importantes et peuvent dissiper de l'nergie dans les lments de commutation. . Voici un programme qui gnre un signal PWM: int main() { DDRD = (1<<PD5); char commande=25;

char temps; volatile char i; while (1) { PORTD |= (1<<PD5); for(temps=0; temps<commande; temps++){ for (i=0; i<50; i++); } PORTD &= ~(1<<PD5); for(temps=0; temps<(100-commande); temps++){ for (i=0; i<50; i++); } } } . Les attentes sont obtenues par une boucle d'attente active, dont le nombre d'instructions dtermine le temps. Attention: le terme volatile est ncessaire pour que le compilateur, dans son mode optimis, ne supprime pas les boucles for constatant qu'elles sont vides. Ce programme donne l'impression que la diode lumineuse est demiintensit. C'est li au fait que la rponse de l'oeil n'est pas linaire, mais logarithmique. On remarque aussi que le PWM est visible en dplaant rapidement la diode devant l'oeil. Beaucoup de microcontrleurs disposent l'intrieur de circuits ddis facilitant la gnration de signaux PWM. Ils sont bass sur des timers (dcrits plus en dtail dans la fiche Les Timers). De manire simplifie, le principe est le suivant:

Un compteur binaire (CNT) est actionn par une horloge de frquence rglable, drive de l'horloge du processeur. Deux comparateurs sont prsents. L'un permet de mettre la sortie 1 lors du passage du compteur la valeur 0, l'autre permet de mettre la sortie 0 lorsque le compteur atteint la valeur contenue dans un registre (OC: Output Compare) Voici un programme pour le microcontrleur Attiny2313. Notez que tous les microcontrleurs de la famille AVR ne sont pas identiques au niveau des timers. . int main() { DDRB|=(1<<PB2); // pin PB2 en sortie TCCR0A|=(0b11<<WGM00); // mode fast PWM TCCR0A|=(0b10<<COM0A0); // signal actif "1" TCCR0B|=(0b100<<CS00); // choix de l'horloge: 8MHz divis par 256 OCR0A=64; // valeur du PWM (25% de 256) while(1) { // il n'y a plus rien faire ! } } . Il n'y a malheureusement pas moyen de choisir la pin sur laquelle les PWM est gnr. Dans ce cas, il s'agit de la pin PB2, note aussi OC0A (Output Capture timer0 A). Remarquez le simplicit du programme et la boucle while(1) vide. Le processeur est donc libre pour excuter d'autres tches.

Introduction aux interruptions


Avec un microcontrleur, les sorties sont parfaitement matrises au cours du temps. En effet, toutes les sorties sont zro au moment du reset, il est possible de les modifier tout moment et chaque sortie conserve son tat tant qu'on ne le change pas. Pour les entres, c'est plus compliqu. La lecture d'une entre est une sorte de photographie de sa valeur. Une autre lecture s'effectuant un

instant plus tard permet d'avoir une nouvelle valeur. Mais le moment exact d'un changement d'une entre est difficile connatre. Pire, deux changements successifs peuvent tre manqus. . La lecture des entres est en fait un chantillonnage. Toute la thorie correspondante s'applique... . La figure met en vidence ce mcanisme, dans le cas d'un chantillonnage frquence fixe.

On voit que le signal lu ne correspond pas bien au signal d'entre. On a mme dans ce cas une impulsion perdue au centre du trac. . Le mcanisme d'interruptions, existant sur pratiquement tous les processeurs, permet de rsoudre ce problme. En quelques mots, une interruption permet une routine de s'excuter la suite d'un vnement. . En programmation, on appelle routine ou sous-routine une partie de programme se terminant par l'instruction RET (return, retour). L'instruction CALL (appel) permet d'excuter les instructions de la routine et de revenir au programme appelant aprs l'instruction RET. En langage C, les procdures utilisent ce mcanisme. . Une routine d'interruption (Interrupt Routine ou Interrupt Sub-Routine, ISR) se prsente comme une routine normale, sauf qu'elle se termine gnralement par l'instruction RETI (return from interrupt). Mais cette routine n'est jamais appele explicitement par un programme. Son excution a pour cause un vnement. Les vnements peuvent tres externes au microcontrleur, comme par exemple le changement d'tat d'une entre. Ils peuvent aussi tre internes, comme par exemple ceux lis un timer.

. Examinons le programme suivant: #include <avr/io.h> #include <avr/interrupt.h> ISR (PCINT_vect) { PORTD^=(1<<PD6); // inverse PD6 } int main() { PORTB|=(1<<PB0)|(1<<PB1); // pull-up sur les entres PCMSK=(1<<PCINT0)|(1<<PCINT1); // Active les interruptions // par PCINT0 et 1 (PB0 et 1) GIMSK=(1<<PCIE); // Active Pin Change Interrupt sei(); // Active l'ensemble des interruptions while(1) { // il n'y a rien faire ! } } Il est ncessaire d'importer les symboles lis aux interruptions, par #include <avr/interrupt.h>. La routine d'interruption dbute par ISR (no_du_vecteur). Le numro du vecteur correspond au rang dans une table situe au dbut de la mmoire flash. La routine d'interruption change l'tat de la sortie PD6, pour mettre en vidence les vnements. Rappel: le signe ^ est le ou exclusif sur un champ de bit. . Le programme principal contient trois lignes pour l'initialisation des interruptions choisies: 1. L'activation des interruptions provenant des entres PCINT0 et PCINT1 (et exclusion des autres entres PCINT2 PCINT7), en activant les bits correspondant dans le Pin Change Mask (PCMSK). 2. L'activation de l'interruption PCINT et donc de la routine d'interruption qui lui est associe, par la mise un du bit PCIE dans le General Interrupt Mask (GIMSK).

3. L'activation gnrale des interruptions par l'instruction sei() (= set interrupt). L'instruction cli() (=clear interrupt) permettrait de dsactiver toutes les interruptions. On l'utilise parfois pour une courte routine qui serait sensible la dure d'excution. Finalement, la boucle sans fin while(1) ne fait rien dans ce cas. Et pourtant, chaque changement sur PB0 ou PB1 va changer l'tat de PD6 ! . Lorsque d'autres interruptions doivent tre utilises, on retrouve gnralement les trois tapes d'initialisation: 1. Rglage des conditions particulires de l'interruption choisie 2. Activation de l'interruption choisie 3. Activation gnrale des interruptions.

Das könnte Ihnen auch gefallen