Il compilatore non rileverà alcun errore e il codice verrà compilato ed eseguito. Quindi, per vedere cosa succede dobbiamo esplorare la magia dietro le quinte. Per un riepilogo, saltare alla fine.
La seconda riga del tuo codice è dove accadrà la magia ed è qui che dobbiamo concentrarci.
pinMode(pin, OUTPUT);
La parte pinMode
rilevante per questa discussione è:
void pinMode(uint8_t pin, uint8_t mode)
{
uint8_t bit = digitalPinToBitMask(pin); //The first instance where pin is used
uint8_t port = digitalPinToPort(pin);
if (port == NOT_A_PIN) return;
//Do something
}
(L'implementazione completa è disponibile in cablaggio_digital.c )
Quindi, qui, digitalPinToBitMask
sembra che stia usando pin
per calcolare un bit intermedio. Esplorando ulteriormente, digitalPinToBitMask
è una macro definita nella Arduino.h
cui definizione è questo one-liner:
#define digitalPinToBitMask(P) ( pgm_read_byte( digital_pin_to_bit_mask_PGM + (P) ) )
Questa fodera dall'aspetto strano fa un compito molto semplice. Indicizza l' elemento P th nell'array digital_pin_to_bit_mask_PGM
e lo restituisce. Questo array digital_pin_to_bit_mask_PGM
è definito nella pins_arduino.h
pin map per la scheda specifica utilizzata.
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),
...
};
Questo array ha 20 elementi in totale, quindi siamo sfortunati. 999 indicizzerà una posizione di memoria nella memoria flash al di fuori di questo array, portando a comportamenti imprevedibili. O lo sarà?
Abbiamo ancora un'altra linea di difesa contro l'anarchia di runtime. È la riga successiva della funzione pinMode
:
uint8_t port = digitalPinToPort(pin);
digitalPinToPort
ci porta lungo un percorso simile. È definito come una macro insieme a digitalPinToBitMask
. La sua definizione è:
#define digitalPinToPort(P) ( pgm_read_byte( digital_pin_to_port_PGM + (P) ) )
Ora, indicizziamo l' elemento P th di digital_pin_to_port_PGM
cui è un array definito nella pin map:
const uint8_t PROGMEM digital_pin_to_port_PGM[] = {
PD, /* 0 */
PD,
....
PC,
PC,
};
Questo array contiene 20 elementi, quindi 999 è di nuovo fuori portata. Ancora una volta, questo comando legge e restituisce un valore dalla memoria flash di cui non possiamo essere certi. Questo porterà di nuovo a comportamenti imprevedibili da qui in poi.
C'è ancora un'ultima linea di difesa. Questo è il if
check-in pinMode
sul valore di ritorno di digitalPinToPort
:
if (port == NOT_A_PIN) return;
NOT_A_PIN
è definito come 0 pollici Arduino.h
. Quindi, se il byte restituito da digitalPinToPort
risulta essere zero, allora pinMode
fallirà silenziosamente e tornerà.
In ogni caso, pinMode
non possiamo salvarci dall'anarchia. 999 è destinato a provocare il destino.
TL; DR, il codice verrà eseguito e il risultato sarà imprevedibile. Molto probabilmente, nessun pin verrà impostato OUTPUT
e digitalWrite
non riuscirà. Se ti capita di avere sfortuna eccezionalmente, un pin casuale può essere impostato su OUTPUT
e digitalWrite
può impostarlo su HIGH
.