🛠 Manipulation directe des registres PORT : le bit-banging à 16 MHz

Arduino Duemilanove — Board Fiche · avance · Schéma : IMG-duemilanove-avance-2-manipulation-registres-port-avr.svg — boîtier ATmega328 vu de dessus avec les ports PORTB (broches 8 à 13) et PORTD (broches 0 à 7) surlignés, tableau de correspondance broche Arduino → bit de port (broche 13 = PORTB bit 5), oscilloscope montrant un créneau rapide sur la broche 13.

Objectives

digitalWrite is convenient but slow on an 8-bit AVR: about ten cycles per call, limiting the pulse width to a few tens of kHz. To drive neopixels, multiplexed displays, or a custom protocol, you drop down to the register level: DDRx, PORTx, PINx. The official Arduino pin ↔ port bit mapping table (PinMapping168) is your navigation map. You will generate a pulse measurable with an oscilloscope and write to an entire port in a single write operation.

Hardware

Complete code

// Carre rapide sur la broche 13 = PORTB bit 5 (voir PinMapping168)
// Broches 8..13 = PORTB bits 0..5 ; broches 0..7 = PORTD bits 0..7 ;
// broches analogiques A0..A5 = PORTC bits 0..5.

void setup {
  DDRB |= (1 << DDB5);      // broche 13 en sortie (registre DDR du port B)
  // Equivalence : pinMode(13, OUTPUT);
}

void loop {
  noInterrupts;           // le timer0 du millis perturbe les mesures
  PORTB |=  (1 << PORTB5);  // broche 13 a 1  -> 1 cycle CPU
  PORTB &= ~(1 << PORTB5);  // broche 13 a 0  -> 1 cycle CPU
  // NB : |= et &= font 2 ecritures ; en assembleur, sbi/cbi font 1 cycle.
  interrupts;
}

Writing to 8 LEDs at once: PORTD = B10101010; sets pins 0–7 to the desired state in a single instruction (note: pins 0/1 are the FTDI serial link — do not break the monitor during uploading).

Expected verification

On the oscilloscope connected to pin 13, you should see a pulse with a period measured in hundreds of nanoseconds (C loops run at around ~1–2 MHz switching speed, much faster with sbi/cbi in assembly) — compared to ~50 kHz maximum with digitalWrite. LED 13 remains dimly lit (natural PWM due to duty cycle). The "one write, 8 LEDs" test toggles an entire port simultaneously.

Common errors

Other tutorials for this board

Code examples for this board

← Back to the board 🛠 All tutorials