Les principales caractéristiques de ce timer sont les suivantes :
- Conception 16-bits ;
- Deux sorties après comparaison indépendantes ;
- Registres de sortie bufferisés (lecture stable pendant le comptage) ;
- Une entrée de capture d’événement, avec suppression du bruit ;
- Réinitialisation du timer à la détection de l’égalité ;
- PWM sans déphasage ;
- PWM à période variable ;
- Générateur de fréquence ;
- Compteur d’événements externes ;
- 4 sources de d’interruption indépendantes.
Pour rappel, ci-dessous, le schéma des fonctions du TIMER1
; il faut évidemment remplacer le n
par 1.
Modulation en largeur d’impulsion (PWM)
C’est l’usage le plus courant de ce timer, c’est donc la configuration qui est proposée en premier ici.
Dans ce mode de fonctionnement, le timer compte de manière incrémentale de 0 (BOTTOM
) à une valeur TOP
, puis se réinitialise à la valeur BOTTOM
. Lorsqu’une des valeurs de comparaison est franchie (OCR1A
ou OCR1B
), la sortie associée change d’état ; de même lorsque la valeur du compteur atteint BOTTOM
. Ainsi les sorties produisent des signaux de fréquence fixe et de rapport cyclique proportionnel à la valeur de comparaison (OCR1x
).
Valeur maximum (TOP
) du compteur
Pour contrôler le fonctionnement du timer, il faut d’abord choisir la valeur maximum (TOP
) que peut atteindre le compteur au moyen des modes indiqués ci-dessous ; cela donne aussi la précision de la modulation :
Mode | Fonctionnement | Description | WGM13,12,11,10 |
---|---|---|---|
5 | Fast PWM, 8 bits | Compte de 0 à 0x00FF | 0101 |
6 | Fast PWM, 9 bits | Compte de 0 à 0x01FF | 0110 |
7 | Fast PWM, 10 bits | Compte de 0 à 0x03FF | 0111 |
14 | Fast PWM | Compte de 0 à ICR1 (OC1B | 1110 |
15 | Fast PWM | Compte de 0 à OCR1A | 1111 |
Le numéro du mode doit être indiqué dans les registres TCCR1A
et TCCR1B
:
Registre TCCR1A
:
Bit | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
Nom | COM1A1 | COM1A0 | COM1B1 | COM1B0 | - | - | WGM11 | WGM10 |
Registre TCCR1B
:
Bit | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
Nom | ICNC1 | ICES1 | - | WGM13 | WGM12 | CS12 | CS11 | CS10 |
Horloge du compteur
Il faut ensuite paramétrer la source de l’horloge qui produit l’incrément du timer. En effet, le timer peut être cadencé, soit sur l’horloge interne, directe ou divisée, soit par une source externe appliquée à la broche T1
. Le tableau suivant précise les valeurs à appliquer aux bits du registre TCCR1B
en fonction de la source choisie :
CS12 | CS11 | CS10 | Description |
---|---|---|---|
0 | 0 | 0 | Pas de source (compteur arrêté) |
0 | 0 | 1 | clkI/O (pas de division) |
0 | 1 | 0 | clkI/O / 8 (pré-division) |
0 | 1 | 1 | clkI/O / 64 (pré-division) |
1 | 0 | 0 | clkI/O / 256 (pré-division) |
1 | 0 | 1 | clkI/O / 1024 (pré-division) |
1 | 1 | 0 | Source sur broche T1 ; sur front descendant |
1 | 1 | 1 | Source sur broche T1 ; sur front montant |
Registre TCCR1B
:
Bit | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
Nom | ICNC1 | ICES1 | - | WGM13 | WGM12 | CS12 | CS11 | CS10 |
Comportement des sorties
Enfin, il faut préciser le comportement attendu des broches de sortie (OC1A
& OC1B
) lors des changements d’état, à savoir :
COM1A1 | COM1A0 | Description |
---|---|---|
0 | 0 | Fonctionnement normal du port ; OC1A déconnectée |
0 | 1 | Modes 14 et 15 : bascule de OC1A lors de la détection d’égalité ;Autres modes : fonctionnement normal du port ; OC1A déconnectée |
1 | 0 | OC1A = 0 lors de la détection d’égalité ;OC1A = 1 lorsque le compteur passe à 0 (BOTTOM )(mode non-inversé) |
1 | 1 | OC1A = 1 lors de la détection d’égalité ;OC1A = 0 lorsque le compteur passe à 0 (BOTTOM )(mode inversé) |
COM1B1 | COM1B0 | Description |
---|---|---|
0 | 0 | Fonctionnement normal du port ; OC1B déconnectée |
0 | 1 | Fonctionnement normal du port ; OC1B déconnectée |
1 | 0 | OC1B = 0 lors de la détection d’égalité ;OC1B = 1 lorsque le compteur passe à 0 (BOTTOM )(mode non-inversé) |
1 | 1 | OC1B = 1 lors de la détection d’égalité ;OC1B = 0 lorsque le compteur passe à 0 (BOTTOM )(mode inversé) |
Les modes de fonctionnement des broches de sortie doivent être indiqués dans le registre TCCR1A
:
Bit | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
Nom | COM1A1 | COM1A0 | COM1B1 | COM1B0 | - | - | WGM11 | WGM10 |
Interruptions
Il est aussi possible d’utiliser des interruptions qui sont déclenchées lors des phases d’égalité du compteur avec les registres de comparaison (OCR1A
& OCR1B
) ou lorsque le compteur se réinitialise de TOP
à BOTTOM
(overflow).
Bonjour, Je découvre les microcontrôleurs ATméga328P. J’ai déjà utilisé la carte arduino uno. Je souhaite m’affranchir de l’interface implémenté et programmer directement en assembleur AVR mes projets pour mieux maîtriser le code. Je recherche un exemple de programme simple me donnant la structure de base pour démarrer un projet. J’aimerai de l’aide pour savoir comment déclarer les vecteurs d’interruptions non utilisés et comment valider une interruption sur une pin d’entrée sur un front montant ou descendant. Je dois aussi connaître la commande assembleur me permettant d’utiliser l’horloge externe avec un quartz. Donc programmer le fusibles internes en conséquences. Peut-être avez-vous quelques éléments de réponses à mes questionnements. Bien à vous…
Bonsoir,
Je ne suis pas convaincu que le passage par l’assembleur soit une bonne solution. Le langage C/C++ de l’IDE Arduino peut très bien faire le job même avec son bootloader. Par contre il est certain qu’il faut faire très attention au code et à l’utilisation des données, la pile (stack) ou le tas (heap). Il est toutefois possible de demander au compilateur de générer le code ASM pour le “regarder”, mais les optimisations peuvent aussi de faire en regardant la taille du code et des données en changeant la manière de rédiger le code. Tous les vecteurs d’interruption sont accessibles dans le code C et la configuration des fusibles est aussi accessible par l’IDE de l’Arduino.
Marc