Il file contiene la mappatura che permette di associare il numero o il nome del pin al relativo registro o porta interna del microcontrollore.
La mappatura è specifica, infatti esiste per ogni modello di microcontrollore un suo file pin header.
Per capirne il funzionamento puoi seguire i passaggi ad esempi iniziando dalla funzione digitalwrite contenuta in wiring_digital.c
void digitalWrite(uint8_t pin, uint8_t val)
{
uint8_t timer = digitalPinToTimer(pin);
uint8_t bit = digitalPinToBitMask(pin);
uint8_t port = digitalPinToPort(pin);
volatile uint8_t *out;
if (port == NOT_A_PIN) return;
// If the pin that support PWM output, we need to turn it off
// before doing a digital write.
if (timer != NOT_ON_TIMER) turnOffPWM(timer);
out = portOutputRegister(port);
uint8_t oldSREG = SREG;
cli();
if (val == LOW) {
*out &= ~bit;
} else {
*out |= bit;
}
SREG = oldSREG;
}
come vedi per settare il valore viene ricercato la porta e il bit relativo al numero del pin immesso.
Questo viene fatto con due funzioni digitalPinToBitMask(pin) e digitalPinToPort(pin) che sono definite in Arduino.h
#define digitalPinToPort(P) ( pgm_read_byte( digital_pin_to_port_PGM + (P) ) )
#define digitalPinToBitMask(P) ( pgm_read_byte( digital_pin_to_bit_mask_PGM + (P) ) )
Questi due define (che vengono sostituiti in fase di compilazione) richiamano la funzione pgm_read_byte che non fa altro che leggere il valore delle costanti: digital_pin_to_port_PGM + (P) e digital_pin_to_bit_mask_PGM + (P) che sono definite in pins_arduino.h
const uint8_t PROGMEM digital_pin_to_port_PGM[] = {
PD, /* 0 */
PD,
PD,
PD,
PD,
PD,
PD,
PD,
PB, /* 8 */
PB,
PB,
PB,
PB,
PB,
PC, /* 14 */
PC,
PC,
PC,
PC,
PC,
};
const uint8_t PROGMEM digital_pin_to_bit_mask_PGM[] = {
_BV(0), /* 0, port D */
_BV(1),
_BV(2),
_BV(3),
_BV(4),
_BV(5),
_BV(6),
_BV(7),
_BV(0), /* 8, port B */
_BV(1),
_BV(2),
_BV(3),
_BV(4),
_BV(5),
_BV(0), /* 14, port C */
_BV(1),
_BV(2),
_BV(3),
_BV(4),
_BV(5),
};
Ecco che magicamente dal pin 5 si passa al Bit X della Porta Y.
Il valore di out viene invece individuato tramite portOutputRegister(port) che è definito in Arduino.h come:
#define portOutputRegister(P) ( (volatile uint8_t *)( pgm_read_word( port_to_output_PGM + (P))) )
che va a leggere tramite pgm_read_word il valore di port_to_output_PGM + (P) in:
const uint16_t PROGMEM port_to_output_PGM[] = {
NOT_A_PORT,
NOT_A_PORT,
(uint16_t) &PORTB,
(uint16_t) &PORTC,
(uint16_t) &PORTD,
};
Note che tutte le costanti sono definite come array il cui indice è il numero del pin indicato in ingresso con il digitalwrite e opportunamente modificato.