Der Compiler erkennt keinen Fehler und der Code wird kompiliert und ausgeführt. Um zu sehen, was passiert, müssen wir die Magie hinter den Kulissen erforschen. Für eine Zusammenfassung springen Sie zum Ende.
Die zweite Zeile in Ihrem Code ist, wo die Magie passieren wird und wo wir uns konzentrieren müssen.
pinMode(pin, OUTPUT);
Der pinModefür diese Diskussion relevante Teil ist:
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
}
(Die vollständige Implementierung finden Sie in wiring_digital.c )
Hier digitalPinToBitMaskscheint also pinein Zwischenbit zu berechnen. Weiter erforschen, digitalPinToBitMaskist ein Makro definiert, in Arduino.hdessen Definition dieser Einzeiler ist:
#define digitalPinToBitMask(P) ( pgm_read_byte( digital_pin_to_bit_mask_PGM + (P) ) )
Dieser seltsam aussehende Einzeiler erledigt eine sehr einfache Aufgabe. Es indiziert das P- te Element im Array digital_pin_to_bit_mask_PGMund gibt es zurück. Dieses Array digital_pin_to_bit_mask_PGMist in pins_arduino.hoder in der Pin-Map für die jeweilige verwendete Karte definiert .
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),
...
};
Dieses Array enthält insgesamt 20 Elemente, daher haben wir kein Glück. 999 indiziert einen Speicherort im Flash-Speicher außerhalb dieses Arrays, was zu einem unvorhersehbaren Verhalten führt. Oder wird es?
Wir haben noch eine andere Verteidigungslinie gegen die Laufzeitanarchie. Es ist die nächste Zeile der Funktion pinMode:
uint8_t port = digitalPinToPort(pin);
digitalPinToPortführt uns auf einem ähnlichen Weg. Es wird zusammen mit als Makro definiert digitalPinToBitMask. Seine Definition lautet:
#define digitalPinToPort(P) ( pgm_read_byte( digital_pin_to_port_PGM + (P) ) )
Nun indizieren wir das P- te Element, digital_pin_to_port_PGMdessen Array in der Pin-Map definiert ist:
const uint8_t PROGMEM digital_pin_to_port_PGM[] = {
PD, /* 0 */
PD,
....
PC,
PC,
};
Dieses Array enthält 20 Elemente, sodass 999 wieder außerhalb des Bereichs liegt. Wiederum liest dieser Befehl einen Wert aus dem Flash-Speicher und gibt ihn zurück, dessen Wert wir nicht sicher sein können. Dies wird von nun an wieder zu unvorhersehbarem Verhalten führen.
Es gibt noch eine letzte Verteidigungslinie. Das ist das ifEinchecken pinModedes Rückgabewerts von digitalPinToPort:
if (port == NOT_A_PIN) return;
NOT_A_PINist definiert als 0 in Arduino.h. Wenn also das zurückgegebene Byte von digitalPinToPortzufällig Null ist, pinModeschlägt dies stillschweigend fehl und kehrt zurück.
pinModeKann uns auf keinen Fall vor Anarchie retten. 999 ist dazu bestimmt, zum Untergang zu führen.
TL; DR, der Code wird ausgeführt und das Ergebnis ist unvorhersehbar. Höchstwahrscheinlich wird kein Pin auf gesetzt und OUTPUTfällt digitalWriteaus. Wenn Sie außergewöhnlich viel Pech haben, wird möglicherweise ein zufälliger Pin auf gesetzt OUTPUTund auf digitalWritegesetzt HIGH.