Contrôlez les broches de l'ATmega328P en accès direct : DDRx, PORTx, PINx
Sur les microcontrôleurs AVR, les broches GPIO sont organisées en ports de 8 bits. L'ATmega328P possède 3 ports : PORTB, PORTC et PORTD. Chaque broche d'un port peut être configurée individuellement comme entrée ou sortie.
Contrairement à Arduino qui utilise une numérotation continue (D0–D13, A0–A5), la programmation AVR utilise la notation native du microcontrôleur : PB0, PB1… PD7, PC0… etc. Cela correspond directement aux registres matériels.
Chaque port est contrôlé par exactement 3 registres 8 bits. Comprendre ces registres est la clé de la programmation AVR :
Définit la direction de chaque broche du port :
DDRB |= (1 << PB5); // PB5 en sortie (broche 13 Arduino)
DDRD &= ~(1 << PD2); // PD2 en entrée (broche 2 Arduino)
DDRB = 0xFF; // Tout PORTB en sortie
DDRD = 0x00; // Tout PORTD en entrée
Deux rôles selon la direction de la broche :
PORTB |= (1 << PB5); // PB5 = HIGH (LED allumée)
PORTB &= ~(1 << PB5); // PB5 = LOW (LED éteinte)
PORTD |= (1 << PD2); // Activer pull-up sur PD2 (entrée)
Lit l'état logique actuel de chaque broche du port, quelle que soit sa direction :
if (PIND & (1 << PD2)) { // Tester si PD2 est à HIGH
// Bouton non pressé (avec pull-up)
} else {
// Bouton pressé (PD2 = LOW)
}
💡 Astuce — Toggle rapide : Écrire un 1 dans le registre PINx permet de basculer (toggle) la sortie correspondante sur certains AVR récents : PINB |= (1 << PB5); inverse l'état de PB5. C'est une fonctionnalité spécifique aux AVR, plus rapide qu'un XOR sur PORTx.
La manipulation des registres AVR repose sur les opérations bit à bit du langage C. Voici les 4 opérations fondamentales :
| Opération | Syntaxe | Effet |
|---|---|---|
| Mettre un bit à 1 | REG |= (1 << n) | SET bit n, les autres inchangés |
| Mettre un bit à 0 | REG &= ~(1 << n) | CLEAR bit n, les autres inchangés |
| Basculer un bit | REG ^= (1 << n) | TOGGLE bit n (0→1 ou 1→0) |
| Tester un bit | if (REG & (1 << n)) | Vrai si bit n = 1 |
Ces opérations sont identiques à celles utilisées sur les PIC (voir notre tutoriel Configuration Binaire PIC). Seuls les noms des registres changent.
#include <avr/io.h>
#include <util/delay.h>
int main(void) {
// Configuration
DDRB |= (1 << PB5); // PB5 (D13) en sortie → LED
DDRD &= ~(1 << PD2); // PD2 (D2) en entrée → Bouton
PORTD |= (1 << PD2); // Activer pull-up sur PD2
while (1) {
if (!(PIND & (1 << PD2))) { // Bouton pressé (LOW)
PORTB |= (1 << PB5); // LED ON
} else {
PORTB &= ~(1 << PB5); // LED OFF
}
}
}
Ce programme allume la LED quand le bouton (connecté entre PD2 et GND) est pressé. Grâce à la pull-up interne, aucune résistance externe n'est nécessaire pour le bouton.
| Arduino Pin | AVR Port | Arduino Pin | AVR Port |
|---|---|---|---|
| D0 | PD0 | D8 | PB0 |
| D1 | PD1 | D9 | PB1 |
| D2 | PD2 | D10 | PB2 |
| D3 | PD3 | D11 | PB3 |
| D4 | PD4 | D12 | PB4 |
| D5 | PD5 | D13 | PB5 |
| D6 | PD6 | A0 | PC0 |
| D7 | PD7 | A5 | PC5 |