mercredi 13 mars 2019

Modulation par largeur d'impulsion (PWM) et STM32

N.B.: Ce billet a été mis à jour le 16 novembre 2019 afin de tenir compte des particularité du nouveau STM32 Core.

Les cartes STM32 comportent plusieurs sorties qui peuvent produire un signal modulé en largeur d'impulsion (aussi appelé PWM pour "pulse width modulation"). Ce type de signal est souvent utilisé pour contrôler la luminosité d'une LED ou la vitesse de rotation d'un moteur.

Voyons comment produire un tel signal en programmant la carte au moyen l'IDE Arduino (veuillez vous référer à cet article pour des informations de bases sur la programmation des cartes STM32 avec l'IDE Arduino).

Les broches PWM de la Blue Pill

Les 15 broches de la carte STM32F103 Blue Pill qui peuvent produire un signal PWM sont A0, A1, A2, A3, A6, A7, A8, A9, A10, B0, B1, B6, B7, B8, B9.


Les broches PWM de la carte Nucleo

Ma carte Nucleo F030R8 comporte 10 broches PWM sur ses connecteurs femelles compatibles Arduino: PA4 (A2), PB0 (A3), PB8 (D15), PB9 (D14), PA6 (D12), PA7 (D11), PB6 (D10), PC7 (D9), PB4 (D5) et PB5 (D4).

Curieusement, les broches D3 et D6 sont identifiées "PWM" sur la carte, mais elles ne semblent pas en mesure d'émettre un tel signal.
(Si ça ne vous suffit pas, 7 sorties PWM supplémentaires ne sont accessibles que sur les connecteurs mâles "morpho").

Les broches PWM de la STM32F030 Demo Board

Officiellement, la STM32F030 Demo Board comporte 9 broches PWM: PA0, PA1, PA2, PA3, PA5, PA6, PA7 et PB1.

Toutefois, avec mon exemplaire de cette carte, je n'ai réussi à produire un signal PWM que sur les 4 broches suivantes: PA4, PA6, PA7 et PB1. J'ignore pour quelle raison.

analogWrite(),  analogWriteResolution() et analogWriteFrequency()

Dans notre programme, un signal PWM est produit grâce à la fonction analogWrite(). Cette fonction nécessite deux arguments: le numéro de la broche de sortie et un entier qui représente le rapport cyclique ("duty cycle") désiré.

Par défaut, le signal produit aura une fréquence de 1000 Hz et une résolution de 8 bits. Toutefois, il est possible de modifier la fréquence au moyen de la fonction analogWriteFrequency(), et de modifier la résolution au moyen de la fonction analogWriteResolution().

Par exemple, les 3 lignes de code ci-dessous produiront sur la broche PA6 un signal PWM de 1000 Hz, ayant un rapport cyclique de 50%:

    analogWriteResolution(8);   // résolution 8 bits
    analogWriteFrequency(1000);  // fréquence de 1000 Hz
    analogWrite(brochePWM, 128);  // rapport cyclique 50%

À une résolution de 8 bits, le rapport cyclique peut prendre n'importe quelle valeur entière entre 0 (0%) et 255 (100%).

Les 3 lignes ci-dessous produiront plutôt un signal PWM de 5000 Hz ayant un rapport cyclique de 25%:

    analogWriteResolution(16);   // résolution 16 bits
    analogWriteFrequency(5000);  // fréquence de 5000 Hz
    analogWrite(brochePWM, 16384);  // rapport cyclique 25%

Cette fois, puisque la résolution est de 16 bits, le rapport cyclique peut prendre n'importe quelle valeur entière située entre 0 (0%) et 65535.

Voici un signal PWM dont le rapport cyclique est de 25% (le signal est au niveau logique HAUT pendant 25% du temps, et au niveau logique BAS pendant 75% du temps):


Rapport cyclique de 50%:


Rapport cyclique de 75%:




Pour terminer, voici le sketch (minimaliste) que j'ai utilisé pour mes tests. L'oscilloscope était branché à la broche PA6 de la carte STM32.


Yves Pelletier   (TwitterFacebook)

Aucun commentaire:

Enregistrer un commentaire