Kompilaator ei tuvasta ühtegi viga ning kood kompileerib ja käivitab. Seega, et näha, mis juhtub, peame uurima telgitaguseid. Kokkuvõtte saamiseks minge lõpuni.
Teie koodi teine rida on koht, kus juhtub maagia ja kuhu me peame keskenduma.
pinMode (pin, OUTPUT);
pinMode
selle arutelu jaoks oluline osa on järgmine:
void pinMode (uint8_t pin, uint8_t mode) {uint8_t bit = digitalPinToBitMask (pin); // Esimene eksemplar, kus pin-i kasutatakse uint8_t port = digitalPinToPort (pin); if (port == NOT_A_PIN) return; // Tee midagi}
(Täieliku rakenduse leiate jaotisest wiring_digital.c)
Nii näib, et digitalPinToBitMask
näib kasutavat vahebiti arvutamiseks pin
. Edasiseks uurimiseks on digitalPinToBitMask
makro, mis on määratletud jaotises Arduino.h
ja mille määratlus on see ühe reaga:
#define digitalPinToBitMask (P) (pgm_read_byte (digital_pin_to_bit_mask_PGM + (P)))
See imeliku välimusega üks liinilaev teeb väga lihtsa ülesande. See indekseerib massiivi P th elemendi digital_pin_to_bit_mask_PGM
ja tagastab selle. See massiiv digital_pin_to_bit_mask_PGM
on määratletud jaotises pins_arduino.h
või konkreetse kasutatava tahvli pin-kaardil.
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), ...};
Selles massiivis on kokku 20 elementi, nii et meil pole õnne. 999 indekseerib välkmälus asuva mälu asukoha väljaspool seda massiivi, mis toob kaasa ettearvamatu käitumise. Või on see?
Meil on käitamisanarhia vastu veel üks kaitseliin. Selle järgmine rida funktsioonil pinMode
:
uint8_t port = digitalPinToPort (pin);
digitalPinToPort
viib meid sarnast rada pidi. See on määratletud kui makro koos digitalPinToBitMask
-ga. Selle määratlus on järgmine:
#define digitalPinToPort (P) (pgm_read_byte (digital_pin_to_port_PGM + (P)))
Nüüd indekseerime P digital_pin_to_port_PGM
th element, mis on pin-kaardil määratletud massiiv:
const uint8_t PROGMEM digital_pin_to_port_PGM [] = {PD, / * 0 * / PD, .... PC, PC,};
See massiiv sisaldab 20 elementi, seega on 999 jälle vahemikust väljas. Jällegi loeb see käsk välkmälust väärtuse, mille väärtuses me ei saa kindel olla. See toob edaspidi kaasa ettearvamatu käitumise.
On veel üks viimane kaitseliin. See on if
kontrollige pinMode
sisse digitalPinToPort
:
if (port == NOT_A_PIN) return;
NOT_A_PIN
on Arduino.h
-is määratletud kui 0. Niisiis, kui tagastatud bait digitalPinToPort
-ist juhtub olema null, siis pinMode
ebaõnnestub ja naaseb.
Igal juhul ei saa pinMode
meid anarhiast päästa. 999 on määratud hukule.
TL; DR, kood käivitatakse ja selle tulemus on ettearvamatu. Tõenäoliselt ei määrata ühtegi tihvti OUTPUT
ja digitalWrite
nurjuvad. Kui teil juhtub erakordselt ebaõnne, võib juhuslik tihvt olla seatud väärtusele OUTPUT
ja digitalWrite
väärtuseks HIGH
.