- Qu'est-ce qu'un signal PWM?
- Programmation PIC pour générer PWM sur les broches GPIO
- Schéma
- Simulation
- Configuration matérielle pour contrôler le servomoteur à l'aide du microcontrôleur PIC
La génération de signaux PWM est un outil essentiel dans tous les arsenaux d'ingénieurs embarqués, ils sont très utiles pour de nombreuses applications comme le contrôle de la position du servomoteur, la commutation de quelques circuits intégrés électroniques de puissance dans les convertisseurs / onduleurs et même pour un simple contrôle de la luminosité des LED. Dans les microcontrôleurs PIC, les signaux PWM peuvent être générés à l'aide des modules Compare, Capture et PWM (CCP) en définissant les registres requis, nous avons déjà appris comment le faire dans le didacticiel PIC PWM. Mais cette méthode présente un inconvénient considérable.
Le PIC16F877A peut générer des signaux PWM uniquement sur les broches RC1 et RC2, si nous utilisons les modules CCP. Mais nous pouvons rencontrer des situations où nous avons besoin de plus de broches pour avoir la fonctionnalité PWM. Par exemple dans mon cas, je veux contrôler 6 servomoteurs RC pour mon projet de bras robotique pour lequel le module CCP est sans espoir. Dans ces scénarios, nous pouvons programmer les broches GPIO pour produire des signaux PWM à l'aide de modules de minuterie. De cette façon, nous pouvons générer autant de signaux PWM avec n'importe quelle broche requise. Il existe également d'autres hacks matériels comme l'utilisation d'un circuit intégré multiplexeur, mais pourquoi investir dans du matériel alors que la même chose peut être obtenue par la programmation. Donc, dans ce tutoriel, nous allons apprendre à convertir une broche PIC GPIO en une broche PWM et pour la tester nous la simulerons sur proteus avec un oscilloscope numérique etcontrôler la position du servomoteur à l'aide du signal PWM et faire varier son cycle de service en faisant varier un potentiomètre.
Qu'est-ce qu'un signal PWM?
Avant d'entrer dans les détails, examinons un peu ce que sont les signaux PWM. La modulation de largeur d'impulsion (PWM) est un signal numérique le plus couramment utilisé dans les circuits de commande. Ce signal est réglé haut (5v) et bas (0v) dans un temps et une vitesse prédéfinis. Le temps pendant lequel le signal reste haut est appelé «temps de marche» et le temps pendant lequel le signal reste bas est appelé «temps d'arrêt». Il existe deux paramètres importants pour un PWM, comme indiqué ci-dessous:
Cycle de service du PWM
Le pourcentage de temps pendant lequel le signal PWM reste HAUT (temps d'activation) est appelé comme facteur de marche. Si le signal est toujours activé, il est en cycle de service de 100% et s'il est toujours désactivé, il est en cycle de service de 0%.
Cycle de service = temps d'activation / (temps d'activation + temps d'arrêt)
Nom de variable |
Fait référence à |
PWM_Frequency |
Fréquence du signal PWM |
T_TOTAL |
Temps total nécessaire pour un cycle complet de PWM |
TONNE |
À l'heure du signal PWM |
DANDY |
Temps d'arrêt du signal PWM |
Cycle de service |
Cycle de service du signal PWM |
Alors maintenant, faisons le calcul.
Ce sont les formules standard où la fréquence est simplement la réciproque du temps. La valeur de la fréquence doit être décidée et définie par l'utilisateur en fonction des besoins de son application.
T_TOTAL = (1 / PWM_Frequency)
Lorsque l'utilisateur modifie la valeur du cycle de service, notre programme devrait automatiquement ajuster l'heure T_ON et l'heure T_OFF en fonction de cela. Ainsi, les formules ci-dessus peuvent être utilisées pour calculer T_ON en fonction de la valeur de Duty_Cycle et T_TOTAL.
T_ON = (Duty_Cycle * T_TOTAL) / 100
Puisque le temps total du signal PWM pour un cycle complet sera la somme du temps de marche et du temps d'arrêt. Nous pouvons calculer le temps d'arrêt T_OFF comme indiqué ci-dessus.
T_OFF = T_TOTAL - T_ON
Avec ces formules à l'esprit, nous pouvons commencer à programmer le microcontrôleur PIC. Le programme implique le module de minuterie PIC et le module PIC ADC pour créer un signal PWM basé sur un cycle de service variable en fonction de la valeur ADC du POT. Si vous êtes nouveau dans l'utilisation de ces modules, il est fortement recommandé de lire le tutoriel approprié en cliquant sur les hyperliens.
Programmation PIC pour générer PWM sur les broches GPIO
Le programme complet de ce tutoriel se trouve au bas du site Web comme toujours. Dans cette section, comprenons comment le programme est réellement écrit. Comme tous les programmes, nous commençons par définir les bits de configuration. J'ai utilisé l'option vues de la mémoire pour la définir pour moi.
// CONFIG #pragma config FOSC = HS // Bits de sélection de l'oscillateur (oscillateur HS) #pragma config WDTE = OFF // Bit d'activation de la minuterie de surveillance (WDT désactivé) #pragma config PWRTE = OFF // Bit d'activation de la minuterie de mise sous tension (PWRT disabled) #pragma config BOREN = ON // Bit d'activation de réinitialisation de Brown-out (BOR activé) #pragma config LVP = OFF // Bit d'activation de programmation série en circuit basse tension (alimentation simple) (RB3 est une E / S numérique, HV on MCLR doit être utilisé pour la programmation) #pragma config CPD = OFF // Data EEPROM Memory Code Protection bit (Data EEPROM code protection off) #pragma config WRT = OFF // Flash Program Memory Write Enable bits (Write protection off; toute la mémoire programme peut être écrite par la commande EECON) #pragma config CP = OFF // Bit de protection du code de la mémoire du programme Flash (protection du code désactivée) // Les instructions #pragma config doivent précéder les inclusions du fichier de projet. // Utiliser les énumérations de projet au lieu de #define pour ON et OFF. #comprendre
Ensuite, nous mentionnons la fréquence d'horloge utilisée dans le matériel, ici mon matériel utilise un cristal de 20 MHz, vous pouvez entrer la valeur en fonction de votre matériel. Vient ensuite la valeur de fréquence du signal PWM. Puisque mon objectif ici est de contrôler un servomoteur RC amateur qui nécessite une fréquence PWM de 50 Hz, j'ai défini 0,05 KHz comme valeur de fréquence, vous pouvez également la modifier en fonction des exigences de votre application.
#define _XTAL_FREQ 20000000 #define PWM_Frequency 0,05 // en KHz (50Hz)
Maintenant que nous avons la valeur de Fréquence, nous pouvons calculer le T_TOTAL en utilisant les formules décrites ci-dessus. Le résultat est plongé par 10 pour obtenir la valeur du temps en milli secondes. Dans mon cas, la valeur de T_TOTAL sera de 2 milli secondes.
int T_TOTAL = (1 / PWM_Frequency) / 10; // calculer le temps total à partir de la fréquence (en milli sec)) // 2msec
Ensuite, nous initialisons les modules ADC pour lire la position du potentiomètre comme indiqué dans notre tutoriel ADC PIC. Ensuite, nous avons la routine de service d'interruption qui sera appelée à chaque fois, le minuteur déborde, nous y reviendrons plus tard, pour l'instant vérifions la fonction principale.
Dans la fonction principale, nous configurons le module de minuterie. Ici, j'ai configuré le module Timer pour qu'il déborde toutes les 0,1 ms. La valeur du temps peut être calculée en utilisant les formules ci-dessous
RegValue = 256 - ((Delay * Fosc) / (Prescalar * 4)) delay en sec et Fosc en hz
Dans mon cas, pour un délai de 0,0001 seconde (0,1 ms) avec un prescalaire de 64 et un Fosc de 20 MHz, la valeur de mon registre (TMR0) devrait être de 248. La configuration ressemble donc à ceci
/ ***** Configuration du port pour la minuterie ****** / OPTION_REG = 0b00000101; // Timer0 avec freq externe et 64 comme prescalaire // Active également PULL UPs TMR0 = 248; // Charge la valeur de temps pour 0,0001s; delayValue peut être compris entre 0 et 256 uniquement TMR0IE = 1; // Activer le bit d'interruption du temporisateur dans le registre PIE1 GIE = 1; // Activer l'interruption globale PEIE = 1; // Activer l'interruption périphérique / *********** ______ *********** /
Ensuite, nous devons définir la configuration d'entrée et de sortie. Ici, nous utilisons la broche AN0 pour lire la valeur ADC et les broches PORTD pour sortir les signaux PWM. Alors lancez-les en tant que broches de sortie et réduisez-les en utilisant les lignes de code ci-dessous.
/ ***** Configuration du port pour les E / S ****** / TRISD = 0x00; // Indique au MCU que toutes les broches du PORT D sont sorties PORTD = 0x00; // Initialise toutes les broches à 0 / *********** ______ *********** /
À l'intérieur de la boucle while infinie, nous devons calculer la valeur de on time (T_ON) à partir du rapport cyclique. Le sur le temps et le devoir du cycle varie en fonction de la position du POT donc nous le faisons à plusieurs reprises à l' intérieur du tout boucle, comme illustré ci - dessous. 0,0976 est la valeur qui doit être multipliée par 1024 pour obtenir 100 et pour calculer T_ON, nous l'avons multipliée par 10 pour obtenir la valeur en milli secondes.
tandis que (1) { POT_val = (ADC_Read (0)); // Lire la valeur de POT en utilisant ADC Duty_cycle = (POT_val * 0.0976); // Mappe 0 à 1024 à 0 à 100 T_ON = ((Duty_cycle * T_TOTAL) * 10/100); // Calculer le temps de fonctionnement en utilisant l'unité de formule en milli secondes __delay_ms (100); }
Etant donné que le temporisateur est réglé sur un dépassement de débit toutes les 0,1 ms, la routine de service d'interruption de temporisation ISR sera appelée toutes les 0,1 ms. Dans la routine de service, nous utilisons une variable appelée count et l'incrémentons toutes les 0,1 ms. De cette façon, nous pouvons suivre le temps. Pour en savoir plus sur les interruptions dans le microcontrôleur PIC, suivez les liens
if (TMR0IF == 1) // L'indicateur de minuterie a été déclenché en raison d'un dépassement de la minuterie -> réglé sur un débordement pour 0,1 ms { TMR0 = 248; // Charge le minuteur Valeur TMR0IF = 0; // Effacer le nombre d' indicateurs d'interruption du minuteur ++; // Compter les incréments toutes les 0,1 ms -> count / 10 donnera la valeur de count en ms }
Enfin, il est temps de basculer la broche GPIO en fonction de la valeur de T_ON et T_OFF. Nous avons la variable de comptage qui enregistre le temps en milli secondes. Nous utilisons donc cette variable pour vérifier si le temps est inférieur à l' heure , si oui, nous gardons la broche GPIO activée, sinon nous la désactivons et la maintenons désactivée jusqu'au début du nouveau cycle. Cela peut être fait en le comparant au temps total d'un cycle PWM. Le code pour faire de même est indiqué ci-dessous
if (count <= (T_ON)) // Si le temps est inférieur au temps RD1 = 1; // Activez GPIO sinon RD1 = 0; // Sinon, désactiver GPIO if (count> = (T_TOTAL * 10)) // Gardez-le désactivé jusqu'à ce qu'un nouveau cycle commence count = 0;
Schéma
Le schéma de circuit pour générer PWM avec la broche GPIO du microcontrôleur PIC est vraiment simple, il suffit d'alimenter le PIC avec l'oscillateur et de connecter le potentiomètre à la broche AN0 et le servomoteur à la broche RD1, nous pouvons utiliser la broche GPIO pour obtenir le signal PWM, j'ai sélectionné RD1 juste hors du hasard. Le potentiomètre et le servomoteur sont tous deux alimentés par 5V qui sont régulés à partir du 7805 comme indiqué ci-dessous dans le schéma de circuit.
Simulation
Pour simuler le projet, j'ai utilisé mon logiciel proteus. Construisez le circuit illustré ci-dessous et liez le code à votre simulation et exécutez-le. Vous devriez obtenir un signal PWM sur la broche GPIO RD1 selon notre programme et le cycle de service du PWM devrait être contrôlé en fonction de la position du potentiomètre. Le GIF ci-dessous montre comment le signal PWM et le servomoteur réagissent lorsque la valeur ADC est modifiée via le potentiomètre.
Configuration matérielle pour contrôler le servomoteur à l'aide du microcontrôleur PIC
Ma configuration matérielle complète est indiquée ci-dessous, pour les personnes qui suivent mes tutoriels, cette carte devrait sembler familière, c'est la même carte que j'ai utilisée dans tous mes tutoriels jusqu'à présent. Vous pouvez vous référer au tutoriel LED clignotant si vous souhaitez savoir comment je le construis. Sinon, suivez simplement le schéma ci-dessus et tout devrait fonctionner correctement.
Téléchargez le programme et faites varier le potentiomètre et vous devriez voir le servo changer la position en fonction de la position du potentiomètre. Le fonctionnement complet du projet est montré dans la vidéo donnée à la fin de cette page. J'espère que vous avez compris le projet et que vous avez apprécié la construction, si vous avez des cahiers, n'hésitez pas à les poster sur le forum et je ferai de mon mieux pour y répondre.
Je prévois de faire avancer ce projet en ajoutant des options pour contrôler plusieurs servomoteurs et ainsi en construire un bras robotique, similaire au bras robotique Arduino que nous avons déjà construit. Alors d'ici là, à bientôt !!