Ahogy olvasom, az R-Pi-ben ezen a két lábon van egy-egy 1.8 kΩ-os ellenállás a 3.3 V felé. Tehát valóban csak össze kell kötni a GND-ket, SDA-kat, SCL-eket, s mivel gondolom, ugyanaz lesz a tápegység, így a +5 V-okat.
Az enyhe aggodalmam az, hogy ha egy programhiba miatt az Arduinoban az SDA vagy SCL vonalak valamelyikét kifelé forgatod, s oda logikai magas szintet küldesz, akkor a kontroller oda kiteszi az 5 V-ot. Két dolgot reméljünk: aki a libet írta, körültekintően járt el. A másik pedig az, hogy nem lesz olyan programhiba, ami ekkora felfordulást okoz. Azért ennek kicsi a valószínűsége, hiszen több dolognak kell balul elsülnie.
Körültekintés alatt azt értem, hogy ebben az esetben hamarabb kell az adatregiszterbe írni, mintsem az irányt meghatározóba. Ezeket az MCU-kat nem ismerem, de a PIC-eket igen, ezzel kapcsolatban mondok egy érdekes lehetőséget a szívásra. Ez pedig a read-modify-write típusú utasítások használata, tehát leegyszerűsítve szinte minden, például a porton egy meghatározott bit törlése. Ezt az MCU úgy csinálja, hogy beolvassa a portot, az adott bitet törli, majd az eredményt visszaírja a kimeneti latch-be. Mi ebben a kockázat? Több is van.
Mondjuk van a porton egy bemeneti és egy kimeneti lábad. Tegyük fel, a bemenetin épp I2C-t kezelsz software-esen, a kimenetin pedig egy LED hajtasz meg. Tök' jó. Az I2C miatt a bemeneti port adat bitjét 0-ba írtad, így ha ezt a vonalat alacsony szinten akarod hajtani, csak kimenetre állítod ezt a bitet, s mivel az adat 0, alacsony szintre húzza a vonalat a kontroller. Ha meg magas szintet szeretnél, befelé forgatod a portbitet, nagy impedanciás lesz, az ellenállás tápra húzza a vonalat, illetve visszaolvasva meg tudod nézni, valaki más lehúzza-e, vagy el van engedve a vonal. Hurrá, eddig minden jó.
Tegyük fel, ez a vonalad bemenet és magas szintű, akár azért, mert még a start bit előtt vagyunk. A mellete lévő biten lévő alacsony szintre aktív LED-et meg kigyújtod, mert olyan kedved van, tehát végrehajtatod azt az utasítást, hogy a LED bitje legyen alacsony szintű, egy bitet törölsz a porton.
Hogyan is hajtódik ez végre? Beolvassa az MCU a portot, tehát a bemenetként kapcsolt I2C vonaladon bejön a magas logikai szintnek megfelelő 1-es. A LED-nél is, de ez most kevésbé érdekes. A LED bitjét törli az MCU, majd visszaírja a regisztert. A LED kigyullad, az I2C-hez tartozó adat pedig 1 - hiszen ezt olvasta be, s nem nyúl hozzá. Még nincs baj, hiszen az a vonal még bemenet. Aztán hajtanád a vonalat alacsony szinttel, így kiforgatod a portbitedet. S mi történt? Kis impedanciával hajtasz magas szintet!
Ez nagy baj, mert egyfelől nem fog működni, másfelől zárlatba kerül a meghajtásod egy korrekt meghajtóval, aki kis impedancián húz alacsony szintre. Tehát fizikailag is sérülhet az eszköz. Nem mellesleg sok sikert a debugoláshoz, ha nincs benne elég rutinod. :)
A másik dolog, amire a read-modify-write típusú utasításoknál figyelni kell, hogy az írás az utolsó órajelben, míg az olvasás az elsőben történik, így ha gyorsan van hajtva az MCU, netán néhány pF terheli a vonalat, még nem változott meg annyi ideje a vonal állapota, hogy azt stabilan, helyes adattal vissza lehessen olvasni a következő utasítással, nem tartod be setup time nevű paramétert, így az MCU téveszteni fog. Hacsak nem figyelsz erre, s hajtatsz végre egy porttól független utasítást, vagy jobb ötlet hiányában egy NOP-ot a következő portot piszkáló utasítást megelőzően.
Amúgy ezen dolgok miatt is jobban szeretek assembly-ben programozni. Itt már lényegében a CPU flip-flopjaira, kombinációs hálózataira, regisztereire írja az ember a programot, néha látni kell az áramköri megvalósítást is, olvasni a mikrokontroller időzítéseire előírt paramétereket, hol hány ns időt kell mindenképpen biztosítani. Azokat a paramétereket nem azért adja meg a gyártó, hogy soha meg se nézzük, meg biztos minden magától teljesül, s így tovább.
tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE