🛠 Timers matériels, interruptions imbriquées et FASTRUN : la vitesse Cortex-M4
Objectifs
Sortir de delay et du polling : la Teensy 3.2 cache une vraie usine à temps réel — un contrôleur d'interructions vectorisées imbriquées (NVIC) avec priorités, 16 canaux DMA à usage général, une batterie de timers (PDB, CMT, LPTMR, 4 compteurs PIT, timers FTM du PWM), le mot-clé FASTRUN pour exécuter des fonctions depuis la RAM, et un bus double 32 bits (fetch d'instruction + données simultanés). Ce tutoriel fait clignoter la LED 13 depuis un IntervalTimer matériel et mesure ce que gagne une boucle de toggle rapide.
Matériel
- 1 Teensy 3.2 (la LED orange sur la broche 13 suffit)
- Optionnel : oscilloscope ou analyseur logique sur une broche libre pour mesurer les fréquences
Code complet
digitalToggle et la classe IntervalTimer sont documentés sur la page boutique PJRC (sections Digital Output Pins / Timing) :
#include <IntervalTimer.h>
IntervalTimer t1;
volatile bool flashing = false;
void flash { // execute depuis un timer matériel, pas la boucle
digitalToggle(13); // broche 13 = LED orange integrée
}
void setup {
pinMode(13, OUTPUT);
t1.priority(0); // attention : sur Teensy, 0 = priorité LA PLUS haute
t1.begin(flash, 500000); // appelle flash toutes les 500 ms (en us)
}
void loop {
// Pour la vitesse brute, digitalToggle en boucle serrée bat les paires
// digitalWrite ; pour une forme d'onde précise, pilotez une broche PWM.
}
Accélérer le code
- digitalToggle en boucle serrée : la sortie numérique la plus rapide en API Arduino ; pour le maximum absolu, l'accès direct aux registres du K20 est possible — la correspondance broche → bit de port doit alors être prise dans le manuel du MK20DX256 (K20P64M72SF1RM.pdf) et la carte de brochage card7a.
- FASTRUN :
FASTRUN void maFonction { ... }place la fonction dans les 64 Ko de RAM (plus rapide que la flash, 256 Ko à 192 Mo/s avec cache 256 octets). - Overclock : le cœur est noté 72 MHz mais officiellement overclockable à 96 MHz (tableau techspecs) — l'horloge vient d'un quartz 16 MHz multiplié par une PLL.
- Priorités d'interruptions : le NVIC accepte l'imbrication (une interruption de plus haute priorité interrompt la plus basse) —
t1.priority(0)est ici la plus haute, convention Teensy. - DMA (16 canaux) : déplacez des blocs (SPI, ADC, UART, mémoire) sans CPU — OctoWS2811 et la bibliothèque Audio en sont les démonstrations.
Vérification attendue
La LED 13 clignote à 1 Hz pile, même si loop est occupé par une boucle de calcul — la preuve que le timer matériel travaille indépendamment. Coupez le flash dans le code : la LED reste fixe, votre code principal continue. À l'oscilloscope sur une broche en toggle libre, mesurez la fréquence maximale, puis comparez avec digitalToggle piloté par IntervalTimer à 1 µs.
Erreurs fréquentes
- Se tromper de sens des priorités : sur Teensy, 0 = la plus haute (contrairement à l'intuition « 0 = aucune »).
- Faire du temps long dans une routine d'interruption ou de timer : delay, Serial.print lourds → blocages en cascade ; gardez les ISR courtes et mettez un flag volatile.
- Oublier volatile sur les variables partagées entre ISR et loop : le compilateur optimise et votre flag ne change jamais « magiquement ».
- Coller TOUT le code en FASTRUN : la RAM fait 64 Ko, la flash 256 Ko — ne placez en RAM que les fonctions critiques.
- Confondre les groupes de timers : les 4 PIT, le LPTMR, le PDB, le CMT et les FTM ne partagent pas les mêmes broches ni les mêmes usages (le LPTMR est optimisé ultra-basse-consommation).
- Attendre un comportement identique après overclock à 96 MHz : vérifiez les bibliothèques dépendant des temporisations (bit-banging, délais calibrés).
Autres tutoriels pour cette carte
- Premiers pas sur la Teensy 3.2 : Teensyduino, HalfKay et premier Blink
- Broches, ADC 13 bits, DAC 12 bits et PWM : dompter les E/S de la Teensy 3.2
- Un instrument MIDI USB en 10 minutes : Bounce, boutons et règle d'or du drain
- Audio Shield SGTL5000 : boucle stéréo 44,1 kHz et outil de conception graphique
- OctoWS2811 : piloter 8 rubans WS2812 en parallèle par DMA (presque zéro CPU)
- Intégration produit : alimentation VIN/VUSB, régulateur 250 mA, RTC à quartz et EEPROM
Exemples de code pour cette carte
clignotante.inoArduinotouche-capacitive.inoArduinoanalogique-12-bits.inoArduinomidi-piano.inoArduinopwm-respiration.inoArduinoservo-angle.inoArduino