Table des matières:
- Étape 1: Description
- Étape 2: Énoncé du problème 1: Faisons clignoter la première LED (verte) toutes les 50 Ms
- Étape 3: Énoncé du problème 2: Faisons clignoter la deuxième LED (bleue) toutes les 1s
- Étape 4: Énoncé du problème 3: Faisons clignoter la troisième LED (rouge) toutes les 16 ms
- Étape 5: écriture de code pour un programme en C. Téléchargement du fichier HEX dans la mémoire flash du microcontrôleur
- Étape 6: Faire le circuit électrique
Vidéo: Microcontrôleur AVR. LED clignotant à l'aide de la minuterie. Interruptions des minuteries. Mode CTC de la minuterie : 6 étapes
2024 Auteur: John Day | [email protected]. Dernière modifié: 2024-01-30 09:08
Bonjour à tous!
Les minuteries sont un concept important dans le domaine de l'électronique. Chaque composant électronique fonctionne sur une base de temps. Cette base de temps permet de garder tout le travail synchronisé. Tous les microcontrôleurs fonctionnent à une fréquence d'horloge prédéfinie, ils ont tous une disposition pour configurer des minuteries. AVR se vante d'avoir une minuterie très précise, précise et fiable. Il offre de nombreuses fonctionnalités, ce qui en fait un vaste sujet. La meilleure partie est que la minuterie est totalement indépendante du CPU. Ainsi, il fonctionne parallèlement au processeur et il n'y a pas d'intervention du processeur, ce qui rend le minuteur assez précis. Dans cette section, j'explique les concepts de base des minuteries AVR. J'écris un programme simple en code C pour contrôler le clignotant LED, à l'aide de minuteries.
Étape 1: Description
Dans ATMega328, il existe trois types de minuteurs:
Timer/Counter0 (TC0) - est un module Timer/Counter 8 bits à usage général, avec deux unités de comparaison de sortie indépendantes et une prise en charge PWM;
Timer/Counter1 (TC1) - L'unité Timer/Counter 16 bits permet une synchronisation précise de l'exécution du programme (gestion des événements), la génération d'ondes et la mesure de la synchronisation du signal;
Minuterie/Compteur2 (TC2) - est un module de minuterie/compteur 8 bits à usage général avec PWM et fonctionnement asynchrone;
Étape 2: Énoncé du problème 1: Faisons clignoter la première LED (verte) toutes les 50 Ms
Méthodologie:
- utiliser un pré-échelonneur Timer0 pour réduire un signal électrique haute fréquence à une fréquence inférieure par division entière;
- utilisation d'une interruption à chaque débordement du Timer0;
Timer0 (8 bits) il compte de 0 à 255 après cela, ils débordent, cette valeur change à chaque impulsion d'horloge.
F_CPU=16MHz: Période d'horloge = 1000ms/16000000Hz = 0,00000625ms
Compte de minuterie = (Délai requis / Période d'horloge) -1 = (50 ms / 0,00000625 ms) = 799999
L'horloge a déjà coché 799999 fois pour donner un délai de seulement 50 ms !
Nous pouvons utiliser une technique de division de fréquence appelée pré-mise à l'échelle pour diminuer le nombre de minuteries. L'AVR nous propose les valeurs de pré-diviseur suivantes parmi lesquelles choisir: 8, 64, 256 et 1024. Voir le tableau récapitulant les résultats de l'utilisation de différents pré-diviseurs.
La valeur du compteur doit toujours être un entier. Choisissons un prescaler 256 !
Dans la plupart des microcontrôleurs, il existe quelque chose appelé Interruption. Cette interruption peut être déclenchée chaque fois que certaines conditions sont remplies. Désormais, chaque fois qu'une interruption est déclenchée, l'AVR s'arrête et enregistre son exécution de la routine principale, s'occupe de l'appel d'interruption (en exécutant une routine spéciale, appelée la routine de service d'interruption, ISR) et une fois qu'il en a terminé, retourne au routine principale et continue de l'exécuter.
Étant donné que le délai requis (50 ms) est supérieur au délai maximum possible: 4 096 ms = 1000 ms / 62 500 Hz * 256, le timer débordera évidemment. Et chaque fois que la minuterie déborde, une interruption est déclenchée.
Combien de fois l'interruption doit-elle être déclenchée ?
50ms / 4.096ms = 3125 / 256 = 12.207 Si le timer a dépassé 12 fois, 12 * 4.096ms = 49.152ms se seraient écoulés. À la 13e itération, nous avons besoin d'un délai de 50 ms – 49,152 ms = 0,848 ms.
À une fréquence de 62 500 Hz (prescaler = 256), chaque tick prend 0,016 ms. Ainsi, pour atteindre un délai de 0,848 ms, il faudrait 0,848 ms / 0,016 ms = 53 ticks. Ainsi, à la 13e itération, nous autorisons uniquement le minuteur à compter jusqu'à 53, puis nous le réinitialisons.
Initialiser Timer0/Counter (voir photo):
TCCR0B |= (1 << CS02) // configurer le timer avec prescaler = 256 TCNT0 = 0 // initialiser le compteur TIMSK0 |= (1 << TOIE0) // activer l'interruption de débordement sei() // activer les interruptions globales tot_overflow = 0 // initialise la variable du compteur de débordement
Étape 3: Énoncé du problème 2: Faisons clignoter la deuxième LED (bleue) toutes les 1s
Méthodologie:
- utiliser un pré-échelonneur Timer1 pour réduire un signal électrique haute fréquence à une fréquence inférieure par division entière;
- en utilisant le mode Clear Timer on Compare (CTC);
- en utilisant les interruptions avec le mode CTC;
Timer1 (16 bits) il compte de 0 à 65534 après cela, ils débordent. Cette valeur change à chaque impulsion d'horloge.
F_CPU=16MHz: Période d'horloge = 1000ms / 16000000Hz = 0.0000625ms Compte de la minuterie = (Délai requis / Période d'horloge) -1 = (1000ms / 0.0000625ms) = 15999999
L'horloge a déjà coché 15999999 fois pour donner un délai de 1s !
Nous pouvons utiliser une technique de division de fréquence appelée pré-mise à l'échelle pour diminuer le nombre de minuteries. L'AVR nous propose les valeurs de pré-diviseur suivantes parmi lesquelles choisir: 8, 64, 256 et 1024. Voir le tableau récapitulant les résultats de l'utilisation de différents pré-diviseurs. La valeur du compteur doit toujours être un entier. Choisissons un prescaler 256 !
En mode Clear timer on Compare (CTC), le registre OCR1A ou ICR1 est utilisé pour manipuler la résolution du compteur. En mode CTC, le compteur est remis à zéro lorsque la valeur du compteur (TCNT1) correspond à l'OCR1A ou à l'ICR1. L'OCR1A ou l'ICR1 définissent la valeur supérieure du compteur, donc aussi sa résolution. Ce mode permet un meilleur contrôle de la fréquence de sortie de comparaison. Il simplifie également l'opération de comptage d'événements externes. Il faut dire à l'AVR de remettre à zéro le Timer1/Counter dès que sa valeur atteint la valeur 62500, donc d'atteindre un délai de 1s.
Initialiser Timer1/Counter (voir photo):
TCCR1B |= (1 << WGM12)|(1 << CS12) // configurer le timer avec prescaler = 256 et mode CTC TCNT1 = 0 // initialiser le compteur TIMSK1 |= (1 << OCIE1A) // activer l'interruption de comparaison OCR1A = 62500 // initialise la valeur de comparaison
Étape 4: Énoncé du problème 3: Faisons clignoter la troisième LED (rouge) toutes les 16 ms
Méthodologie:
- utiliser un pré-échelonneur Timer2 pour réduire un signal électrique haute fréquence à une fréquence inférieure par division entière;
- en utilisant le mode Clear Timer on Compare (CTC);
- en utilisant le mode CTC matériel sans interruptions;
Timer2 (8 bits) il compte de 0 à 255 après cela, ils débordent. Cette valeur change à chaque impulsion d'horloge.
F_CPU=16MHz: Période d'horloge = 1000ms/16000000Hz = 0,00000625ms
Compte de minuterie = (Délai requis / Période d'horloge) -1 = (16 ms / 0,00000625 ms) = 255999
L'horloge a déjà coché 255999 fois pour donner un délai de 16ms !
Voir le tableau récapitulant les résultats de l'utilisation de différents prédiviseurs. La valeur du compteur doit toujours être un entier. Choisissons un prescaler 1024 !
En mode CTC, le compteur est remis à zéro lorsque la valeur du compteur (TCNT2) correspond à l'OCR2A ou à l'ICR2. La broche PB3 est également la broche de comparaison de sortie de TIMER2 - OC2A (voir schéma).
Timer/Counter2 Control Register A – TCCR2A Bit 7:6 – COM2A1:0 – Compare Output Mode for Compare Unit A. Puisque nous devons basculer la LED, nous choisissons l'option: Basculer OC2A sur Compare Match Chaque fois qu'une comparaison se produit, le La broche OC2A est automatiquement basculée. Pas besoin de vérifier un bit d'indicateur, pas besoin de s'occuper d'aucune interruption.
Initialiser Timer2/Compteur
TCCR2A |= (1 << COM2A0)|(1 << WGM21) // configurer la broche OC2A de la minuterie en mode bascule et en mode CTC TCCR2B |= (1 << CS22)|(1 << CS21)|(1 << CS20) // configurer le temporisateur avec prescaler = 1024 TCNT2 = 0 // initialiser le compteur OCR2A = 250 // initialiser la valeur de comparaison
Étape 5: écriture de code pour un programme en C. Téléchargement du fichier HEX dans la mémoire flash du microcontrôleur
Écriture et construction de l'application du microcontrôleur AVR en code C à l'aide de la plate-forme de développement intégrée - Atmel Studio.
F_CPU définit la fréquence d'horloge en Hertz et est courant dans les programmes utilisant la bibliothèque avr-libc. Dans ce cas, il est utilisé par les routines de retard pour déterminer comment calculer les retards.
#ifndef F_CPU
#define F_CPU 16000000UL // indiquant la fréquence du cristal du contrôleur (16 MHz AVR ATMega328P) #endif
#include // en-tête pour activer le contrôle du flux de données sur les broches. Définit les broches, les ports, etc.
Le premier fichier d'inclusion fait partie d'avr-libc et sera utilisé dans pratiquement tous les projets AVR sur lesquels vous travaillez. io.h déterminera le processeur que vous utilisez (c'est pourquoi vous spécifiez la partie lors de la compilation) et à son tour inclura l'en-tête de définition IO approprié pour la puce que nous utilisons. Il définit simplement les constantes de toutes vos broches, ports, registres spéciaux, etc.
#include // en-tête pour activer l'interruption
volatile uint8_t tot_overflow; // variable globale pour compter le nombre de débordements
Méthodologie de l'énoncé du problème: Flash First (vert) LED toutes les 50 ms
- utiliser un pré-échelonneur Timer0 pour réduire un signal électrique haute fréquence à une fréquence inférieure par division entière;
- utilisation d'une interruption à chaque débordement du Timer0;
void timer0_init() // initialise timer0, interruption et variable
{ TCCR0B |= (1 << CS02); // configurer le temporisateur avec prescaler = 256 TCNT0 = 0; // initialise le compteur TIMSK0 |= (1 << TOIE0); // active le débordement ninterrupt sei(); // active les interruptions globales tot_overflow = 0; // initialise la variable de compteur de débordement }
Méthodologie de l'énoncé du problème: seconde DEL clignotante (bleue) toutes les 1 s
- utiliser un pré-échelonneur Timer1 pour réduire un signal électrique haute fréquence à une fréquence inférieure par division entière;
- en utilisant le mode Clear Timer on Compare (CTC);
- en utilisant les interruptions avec le mode CTC;
void timer1_init() // initialise timer1, interruption et variable{ TCCR1B |= (1 << WGM12)|(1 << CS12); // configurer la minuterie avec prescaler = 256 et le mode CTC TCNT1 = 0; // initialise le compteur OCR1A = 62500; // initialise la valeur de comparaison TIMSK1 |= (1 << OCIE1A); // activer l'interruption de comparaison}
Méthodologie de l'énoncé du problème: troisième LED (rouge) clignotante toutes les 16 ms
- utiliser un pré-échelonneur Timer2 pour réduire un signal électrique haute fréquence à une fréquence inférieure par division entière;
- en utilisant le mode Clear Timer on Compare (CTC);
- en utilisant le mode CTC matériel sans interruptions;
void timer2_init() // initialise timer2{ TCCR2A |= (1 << COM2A0)|(1 << WGM21); // configurer la broche OC2A de la minuterie en mode bascule et en mode CTC TCCR2B |= (1 << CS22)|(1 << CS21)|(1 << CS20); // configurer la minuterie avec prescaler = 1024 TCNT2 = 0; // initialise le compteur OCR2A = 250; // initialise la valeur de comparaison }
Routine de service d'interruption de débordement TIMER0 appelée chaque fois que TCNT0 déborde:
ISR(TIMER0_OVF_vect)
{ tot_overflow++; // garde une trace du nombre de débordements }
Cet ISR est déclenché chaque fois qu'une correspondance se produit, par conséquent, basculez ici lui-même:
ISR (TIMER1_COMPA_vect){ PORTC ^= (1 << 1); // bascule la led ici}
int main(void)
{ DDRB |= (1 << 0); // connecter 1 (vert) led à la broche PB0 DDRC |= (1 << 1); // connecter 2 (bleu) led à la broche PC1 DDRB |= (1 << 3); // connecter 3 (rouge) led à la broche PB3 (OC2A) timer0_init(); // initialise timer0 timer1_init(); // initialise timer1 timer2_init(); // initialise timer2 while(1) // boucle indéfiniment {
Si le Timer0 a survolé 12 fois, 12 * 4,096 ms = 49,152 ms se seraient écoulés. À la 13e itération, nous avons besoin d'un délai de 50 ms – 49,152 ms = 0,848 ms. Ainsi, à la 13e itération, nous autorisons uniquement le minuteur à compter jusqu'à 53, puis nous le réinitialisons.
if (tot_overflow >= 12) // vérifier si non. de débordements = 12 REMARQUE: '>=' est utilisé
{ if (TCNT0 >= 53) // vérifie si le compteur de la minuterie atteint 53 { PORTB ^= (1 << 0); // bascule la led TCNT0 = 0; // réinitialiser le compteur tot_overflow = 0; // réinitialiser le compteur de débordement } } } }
Téléchargement du fichier HEX dans la mémoire flash du microcontrôleur:
tapez dans la fenêtre d'invite DOS la commande:
avrdude –c [nom du programmeur] –p m328p –u –U flash:w:[nom de votre fichier hexadécimal] Dans mon cas c'est: avrdude –c ISPProgv1 –p m328p –u –U flash:w:Timers.hex
Cette commande écrit un fichier hexadécimal dans la mémoire du microcontrôleur. Regardez la vidéo avec une description détaillée de la gravure de la mémoire flash du microcontrôleur:
Gravure de la mémoire flash du microcontrôleur…
D'accord! Maintenant, le microcontrôleur fonctionne conformément aux instructions de notre programme. Regardons ça!
Étape 6: Faire le circuit électrique
Connectez les composants conformément au schéma de principe.
Conseillé:
Laboratoire des interruptions (travail en cours) : 3 étapes
Laboratoire d'interruptions (travail en cours) : le but de ce laboratoire est d'exécuter un programme Arduino à l'aide d'interruptions. Ce laboratoire ne fonctionne pas correctement en raison de problèmes de codage. Ce dont vous aurez besoin : - 1 Arduino Uno - 1 planche à pain - 1 bouton-poussoir - 3 LED - Résistances 220 Ohm - Fils de raccordement
Microcontrôleur AVR. Basculez les LED à l'aide d'un interrupteur à bouton-poussoir. Anti-rebond de bouton poussoir. : 4 étapes
Microcontrôleur AVR. Basculez les LED à l'aide d'un interrupteur à bouton-poussoir. Anti-rebond de bouton-poussoir. : Dans cette section, nous allons apprendre comment créer un code C de programme pour ATMega328PU pour basculer l'état des trois LED en fonction de l'entrée d'un interrupteur à bouton. En outre, nous avons exploré une solution au problème de « Switch Bounce ». Comme d'habitude, nous allons
Clignotant LED et oscillateur PWM utilisant la minuterie 555 : 3 étapes
Clignotant LED et oscillateur PWM utilisant la minuterie 555 : Tout le monde est débutant en électronique et pour les débutants, il peut parfois être difficile de construire des circuits fonctionnels. C'est pourquoi j'ai décidé de poster ce genre de projet. Ce circuit est une version simplifiée d'un circuit simple dont les schémas o
Configuration des bits de fusible du microcontrôleur AVR. Création et téléchargement dans la mémoire flash du microcontrôleur du programme de clignotement des voyants : 5 étapes
Configuration des bits de fusible du microcontrôleur AVR. Création et téléchargement dans la mémoire flash du microcontrôleur du programme de clignotement des LED. : Dans ce cas, nous allons créer un programme simple en code C et le graver dans la mémoire du microcontrôleur. Nous allons écrire notre propre programme et compiler le fichier hexadécimal, en utilisant Atmel Studio comme plate-forme de développement intégrée. Nous allons configurer le fusible bi
Contrôle des moteurs à courant continu avec le L298N à l'aide du microcontrôleur CloudX : 3 étapes
Contrôle des moteurs à courant continu avec le L298N à l'aide du microcontrôleur CloudX : Dans ce projet, nous expliquerons comment utiliser notre pont en H L298N pour augmenter et diminuer la vitesse du moteur à courant continu. Le module pont en H L298N peut être utilisé avec des moteurs ayant une tension comprise entre 5 et 35 V CC. Il existe également un régulateur 5 V intégré, donc si votre