Derleyici herhangi bir hata algılamaz ve kod derlenir ve yürütülür. Bu nedenle, neler olduğunu görmek için sahne arkasındaki sihri keşfetmeliyiz. Özet için, sonuna atlayın.
Kodunuzdaki ikinci satır, büyünün gerçekleşeceği ve odaklanmamız gereken yer.
pinMode(pin, OUTPUT);
pinModeBu tartışmayla ilgili kısmı :
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
}
(Uygulamanın tamamı wiring_digital.c adresinde bulunabilir )
Yani, burada, bir ara bit hesaplamak digitalPinToBitMaskiçin kullanılıyor gibi görünüyor pin. Daha fazla araştırmak, tanımı bu tek katmanlı olan digitalPinToBitMaskbir makrodur Arduino.h:
#define digitalPinToBitMask(P) ( pgm_read_byte( digital_pin_to_bit_mask_PGM + (P) ) )
Bu garip görünümlü bir astar çok basit bir görev yapar. Dizideki Pth öğesini dizine alır digital_pin_to_bit_mask_PGMve döndürür. Bu dizi digital_pin_to_bit_mask_PGM, pins_arduino.hkullanılan belirli kart için tanımlanır veya pin haritası.
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),
...
};
Bu dizi toplam 20 elemente sahip, bu yüzden şansımız kalmadı. 999, flash bellekte bu dizinin dışındaki bir bellek konumunu endeksler ve böylece öngörülemeyen davranışlara yol açar. Yoksa olacak mı?
Çalışma zamanı anarşisine karşı başka bir savunma hattımız daha var. Fonksiyonun bir sonraki satırı pinMode:
uint8_t port = digitalPinToPort(pin);
digitalPinToPortBizi benzer bir yol izliyor. İle birlikte bir makro olarak tanımlanır digitalPinToBitMask. Tanımı:
#define digitalPinToPort(P) ( pgm_read_byte( digital_pin_to_port_PGM + (P) ) )
Şimdi, pim öğesinde pim haritasında tanımlanan bir dizi olan Pth öğesini indeksliyoruz digital_pin_to_port_PGM:
const uint8_t PROGMEM digital_pin_to_port_PGM[] = {
PD, /* 0 */
PD,
....
PC,
PC,
};
Bu dizi 20 öğe içerir, bu nedenle 999 tekrar aralık dışındadır. Yine, bu komut, değerini bilmediğimiz flash bellekten bir değer okur ve döndürür. Bu da bundan sonra öngörülemeyen davranışlara yol açacaktır.
Hala son bir savunma hattı var. Yani ifonay pinMode, dönüş değerinin digitalPinToPort:
if (port == NOT_A_PIN) return;
NOT_A_PIN, 0 inç olarak tanımlanır Arduino.h. Böylece, gelen bayt digitalPinToPortsıfır olursa pinMode, sessizce başarısız olur ve geri döner.
Her durumda, pinModebizi anarşiden kurtaramaz. 999 mahkumiyetle sonuçlanır.
TL; DR, kod yürütülecek ve bunun sonucu tahmin edilemez olacaktır. Büyük olasılıkla, hiçbir pin ayarlanmaz OUTPUTve digitalWritebaşarısız olur. Eğer son derece kötü bir şansınız varsa, rastgele bir pin ayarlanmış olabilir OUTPUTve digitalWritebunu ayarlayabilir HIGH.