Elektroda.pl
Elektroda.pl
X
Computer ControlsComputer Controls
Proszę, dodaj wyjątek dla www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

Karta ISA do obsługi wyświetlacza HD44780 oraz I2C

phanick 06 Sty 2015 15:08 12483 14
  • Karta ISA do obsługi wyświetlacza HD44780 oraz I2C
    Konstrukcja będąca tematem wątku powstała jako projekt na zaliczenie przedmiotu na uczelni, którego celem było napisanie sterownika dla systemu Linux do jakiegoś urządzenia. Ponieważ miałem swobodę wyboru tematu sterownika, postanowiłem stworzyć jakieś urządzenie w postaci karty ISA. Złącze to nie występuje już w obecnych komputerach, ja jednak mam sentyment do antyków. Projekt oprócz wartości akademickiej (zaliczenie przedmiotu) ma też sporo walorów edukacyjnych - poznanie magistrali ISA, oprogramowanie jakiegoś istniejącego protokołu (I2C), zaangażowanie programowalnego układu CPLD do jego realizacji.

    1. Komputer testowy
    Jakiś czas temu nabyłem płytę wraz z procesorem 386DX (40 MHZ przy włączonym turbo). Płyta ta strasznie mnie urzekła swoim małym rozmiarem. Postanowiłem więc stworzyć dla niej specjalną małą obudowę z drewna, gdyż w wielkiej obudowie AT byłoby zbyt dużo niewykorzystanego wolnego miejsca.
    Do konstrukcji używałem programu Google SketchUp. W efekcie powstała dość oryginalna obudowa w pełni funkcjonalna: przyciski ON/OF, turbo, wskaźnik turbo, wskaźnik pracy dysku, przycisk reset oraz z tyłu wnęka na karty rozszerzeń. Zasilacz AT użyty w projekcie został wyjęty z obudowy, gdyż w ten sposób zaoszczędzimy połowę wolnego miejsca.

    Komputer posiada następujące karty rozszerzeń (ISA):
    - karta sieciowa
    - karta graficzna
    - karta dźwiękowa
    - karta kontrolera HDD, FDD, LPT1, Gameport, COM1, COM2

    Posiada 8 slotów na pamięci SIMM (30 pin). Obecnie włożonejest 20 MB z uwagi na trudności w zdobyciu kolejnych modułów SIMM po 4 MB.
    Karta ISA do obsługi wyświetlacza HD44780 oraz I2C Karta ISA do obsługi wyświetlacza HD44780 oraz I2C Karta ISA do obsługi wyświetlacza HD44780 oraz I2C

    Na komputerze testowym zainstalowałem najpierw system MS DOS, później Windows 3.11 for Workgroups, następnie Windows 95 oraz Linux.
    Windows 3.11 For Workgroups (w odróżnieniu od Windows 3.11) posiada wbudowaną obsługę sieci (nawet TCP!)
    Karta ISA do obsługi wyświetlacza HD44780 oraz I2C
    Karta ISA do obsługi wyświetlacza HD44780 oraz I2C

    Z systemem linux miałem drobny kłopot - konieczne było wybranie w miarę nowej dystrybucji, która jednak nie obciążałaby zbytnio procesora.
    W 2012 roku padła wiadomość, że kolejne dystrybucje Linuxa nie będą już obsługiwać procesora 386:
    http://www.komputerswiat.pl/nowosci/programy/...50/linux-bez-wsparcia-dla-procesorow-386.aspx

    Jednak nawet wcześniejszej dystrybucji nie da się już uruchomić pod tym procesorem - występuje błąd podczas uruchamiania systemu:
    This kernel doesn't support CPU's with broken WP. Recompile it for a 386!

    Jak udało mi się wyczytać, spowodowane jest to ignorowaniem bitu ochrony zapisu do pamięci przez procesor 386, przez co Linux uruchomiony na takiej maszynie nie byłby bezpieczny.
    Ostatnim jądrem obsługującym bez problemu ten procesor jest 2.4.18, zatem wybór padł na dystrybucje Slackware 8.1 (data wypuszczenia: 2002-06-18)

    2. Konstrukcja urządzenia
    Celem urządzenia była najpierw obsługa wyświetlacza HD44780 (część łatwiejsza, w celu poznania magistrali ISA) oraz druga część trudniejsza - obsługa protokołu I2C.
    Nie będę długo rozpisywał się o magistrali ISA, gdyż podsunę dla zainteresowanych garść ciekawych informacji, z których sam korzystałem:
    http://pinouts.ru/Slots/isa_pinout.shtml
    http://ece.wpi.edu/~wrm/Courses/EE3803/Labs/isa/
    http://web.archive.org/web/20130501013016/htt...=ContentExpress&func=display&ceid=215
    http://web.archive.org/web/20130501023824/htt...=ContentExpress&func=display&ceid=152
    https://ia601605.us.archive.org/17/items/ISA_System_Architecture/ISA_System_Architecture.pdf

    W skrócie powiem tylko, że na magistrali dostępne są m.in.:
    - wszystkie linie adresowe generowane przez procesor,
    - linie danych,
    - linie określające, jakiego rodzaju cykl wykonuje aktualnie procesor (odczyt/zapis do pamięci/urządzenia IO)
    - zasilanie
    - zegar

    Komunikacja z kartą polega zatem na umieszczeniu jej w pewnym obszarze przestrzeni adresowej i/o, zaplanowanie adresów dla rejestrów sterujących, dekodowanie adresów i obsługa rejestrów. Jako układ będący sercem logiki użyłem CPLD Xilinx XC9572XL.

    Trudności napotkane podczas realizacji:
    a) podczas projektowania PCB złącze na goldpinie nazwałem LCD_ENA1, a przy CPLD LCD_ENA, przez co ścieżka nie została stworzona
    b) użyłem niepoprawnego rozkładu pinów w złączu JTAG (ile układów CPLD/FPGA i ile programatorów, tyle różnych możliwości)
    c) jedna ze ścieżek przechodząca obok blisko położonego pinu miała niedotrawienie.
    d) podczas oprogramowania układu CPLD, plik UCF (w którym przyporządkowane są sygnały do wyprowadzeń układu) nie miał ustawionego View Association na Implementation, przez co środowisko ignorowało ten plik i przyporządkowywało piny wedle swojego widzimisie. Taka karta oczywiście po włożeniu do komputera blokowała cała maszynę, w efekcie płyta nie startowała (nie włączał się nawet monitor).
    Karta ISA do obsługi wyświetlacza HD44780 oraz I2C

    Trochę później zauważyłem, że Module Association dla tego pliku także musi być ustawione na odpowiedni moduł główny projektu.
    Karta ISA do obsługi wyświetlacza HD44780 oraz I2C

    e) Gdy już karta nie blokowała systemu, czas na obsługę wyświetlacza HD44780. Magistrala tego wyświetlacza jest praktycznie całkowicie zgodna z magistralą ISA. Potrzeba jedynie sygnału sterującego odczytem/zapisem (który jest jedną linią w przeciwieństwie do dwuliniowego na ISA) oraz sygnału aktywującego wyświetlacz, gdy procesor odwoła się do odpowiedniego adresu. O ile zapisywanie do wyświetlacza jakoś działało, o tyle odczyt działać nie chciał (a odczyt jest konieczny do badania, czy wyświetlacz przetworzył poprzednie polecenie i jest gotów do wykonania następnego).
    Myślałem, że może wyświetlacz jest zbyt wolny (w końcu magistrala taktowana jest zegarem 8 MHz) i wyświetlacz po aktywacji nie zdąża wystawić danych i procesor odczytuje śmieci. Dodałem nawet obsługę linii WAIT (urządzenie może ją ściągnąć do masy, gdy nie jest gotowe na wystawienie danych, wtedy procesor czeka), jednak to nie pomogło. Zdesperowany zacząłem oglądać w analizatorze logicznym, kiedy wyświetlacz jest aktywowany (przypisałem mu adres 0x300). Jak się okazało, był on aktywowany nawet w momentach gdy ja go nie aktywowałem! Wtedy przypomniałem sobie, że karta sieciowa w komputerze także korzysta z adresu 0x300. Po przeniesieniu wyświetlacza pod adres 0x340 zaczął już działać normalnie (i wcale nie trzeba wstrzymywać procesora!)

    f) Obsługa I2C: tutaj sprawa była bardzo trudna. Ogólnie I2C jest dość wolnym protokołem, dlatego do obsługi stworzyłem następujące rejestry; I2C_CONFIG (odczyt/zapis)
    I2C_RW (odczyt/zapis)
    I2C_R_STROBE (zapis).
    - Odczytując rejestr I2C_CONFIG możemy sprawdzić, czy karta jest gotowa na przyjęcie kolejnego rozkazu
    - Zapisując do rejestru I2C_CONFIG możemy ustalać, czy mają zostać wysłane sygnały START/STOP
    - Zapisując do rejestru I2C_RW bajt, wysyłamy po magistrali I2C 8 bitów owego bajtu (+ ewentualnie START/STOP)
    - Zapisując do rejestru I2C_R_STROBE aktywujemy odczyt z magistrali I2C 8 bitów (+ ewentualnie wysłanie STOP)
    - gdy urządzenie wykona odczyt (znów będzie gotowe), z rejestru I2C_RW można odczytać odczytany bajt.

    W protokole I2C, po wysłaniu 8 bitów odczytujemy następnie potwierdzenie od urządzenia, dzięki czemu można sprawdzić, czy do urządzenia dotarły dane, itp. Niestety mimo prób, urządzenie raz odpowiadało, raz nie, czyli coś, czego najbardziej nie lubimy.
    Jak się później okazało, zapis do rejestru czasami aktywował pojedyncze, a czasami dwukrotne wysłanie bajtu!

    Problemem był sposób dekodowania adresu, proponowany w kilku powyższych źródłach. Źródła te mówiły, że można wykorzystać
    linie adresowe, linie ISA_IOnR, ISA_IOnW oraz linie ISA_AEN. Niestety linie te zmieniają się w dowolnej kolejności, więc czasami na skutek
    nieustabilizowania się linii adresowych można przez przypadek aktywować rejestr. Dlatego generacja poniższego asynchronicznego sygnału
    jest zła:
    Code:

    I2C_W_STROBE <= '1' when ISA_A = I2C_W_REG and ISA_AEN = '0' and ISA_IOnW = '0' else '0';


    Sam doszedłem więc do pomysłu, że zapis należy aktywować w momencie, gdy sygnał zegarowy ma stan wysoki, gdyż wówczas oznacza to ustabilizowanie się adresu. Jednak nadal nie można robić tego w sposób synchroniczny, gdyż na jeden cykl rozkazowy przypada kilka (5) cykli zegarowych, dlatego zawsze otrzymalibyśmy pięciokrotną aktywacje linii:
    Code:

    I2C_W_STROBE <= '1' when ISA_CLK = '1' and ISA_A = I2C_W_REG and ISA_AEN = '0' and ISA_IOnW = '0' else '0';


    Konieczne jest więc synchroniczne generowanie tego sygnału w momencie rosnącego zbocza na linii zegarowej ISA:
    Code:

    process (ISA_RESET, ISA_CLK) is begin
       if ISA_RESET = '1' then
          I2C_W_STROBE <= '0';
       elsif rising_edge(ISA_CLK) then
          if ISA_A = I2C_W_REG and ISA_AEN = '0' and ISA_IOnW = '0' then
             I2C_W_STROBE <= '1';
          else
             I2C_W_STROBE <= '0';
          en dif;
       end if;
    end process;


    Takie rozwiązanie zapewni odpowiednią aktywacje zapisu.

    g) Kolejnym problemem była już obsługa samego protokołu. Sygnał zegarowy I2C powinien być w okolicach 100 kHZ. Pomyślałem więc, że sygnał zegarowy ISA (8 MHZ) podziele sobie od razu i cały moduł obsługujący I2C będę taktował już tym podzielonym sygnałem. Niestety rozwiązanie to pomimo początkowej prostoty, okazało się zupełnie nietrafione. Rozjazd pomiędzy sygnałem zegarowym a sygnałem po podzieleniu i konieczne wprowadzenie sporej liczby stanów w automacie stanowym sprawiło, ze komunikacja znowu była niedeterministyczna.
    Dalsze ulepszanie tego rozwiązania (nad którym spędziłem ok. 2 dni) także nie przyniosło rezultatu. Wtedy zdenerwowany postanowiłem napisać moduł od nowa, wykorzystując inny pomysł taktujmy moduł do obsługi I2C sygnałem magistrali z ISA i niech moduł sam zlicza sobie ilość tych cykli, aby w odpowiednich momentach sterować liniami SCL/SDA. Pomysł ten był strzałem w dziesiątkę. W efekcie udało się osiągnąć pełną kontrolę nad liniami SCL/SDA i teraz zmiana linii SDA następuję zawsze, gdy na linii SCL jest stan niski, po odpowiednim odczekaniu aż sygnały się ustabilizują (brak zmiany obu sygnałów w jednym czasie). W efekcie udało się nawet osiągnąć prostszy automat stanowy a zużycie zasobów CPLD także spadło (wcześniej dochodziłem do ok. 95%, a teraz jest ok. 71%).

    Tak więc wyglądają poprawne przebiegi z symulatora przy wysyłaniu po magistrali I2C:
    Karta ISA do obsługi wyświetlacza HD44780 oraz I2C
    Widać, zmiany sygnału SDA dokładnie w połowie czasu trwania stanu niskiego na SCL

    h) Obie linie magistrali I2C są liniami typu otwarty kolektor, dlatego układ chcąc wystawić zero, ściąga linie do masy, a chcąc wystawić jedynkę - przechodzi w stan wysokiej impedancji (linia jest podciągana zewnętrznym rezystorem). Wcześniej chcąc wystawić jedynkę, ustawiałem na linii stan wysoki. Nie był to dobry pomysł, gdyż mogło nawet dochodzić do zwarć! Zwłaszcza, że układ slave (odbiorca) może ściągnąć linie SCL (którą normalnie zawsze generuje układ master - nadawca) do masy w momencie, gdy nie jest gotowy na odbiór następnej komendy.

    h) Dotychczasowe testy pisałem w Turbo Pascalu, gdyż DOS uruchamia się w kilkanaście sekund, a do tego obsługa portów IO w magistrali ISA jest banalnie prosta - wystarczy zapis/odczyt prefefiniowanej w Pascalu tablicy PORT. Jednak celem przedmiotu jest napisanie sterownika do systemu Linux. W efekcie powstał więc sterownik jako urządzenie znakowe, w którym za pomocą funkcji ioctrl można ustawić port, do którego ma się odbywać odczyt/zapis, natomiast pisząc/czytając z urządzenia, dokonujemy wysłania/odczytania bajtów pod uprzednio ustawiony port.

    W samym sterowniku oczywiście zapisana jest jedynie powyższa obsługa portu. Program (w C) chcąc komunikować się z kartą, otwiera odpowiednie urządzenie znakowe, pisząc i czytając z niego dane wedle ustalonych reguł.
    W C pod linuxem jest kilka funkcji do obsługi portów (inb, outb, inw, outw, inl, outl, inb_p, outb_p, inw_p, outw_p, inl_p, outl_p).
    Prefix (in / out) oznacza, czy chcemy czytać/wystawiać dane na port.
    Sufix b/w/l oznacza, czy chcemy wykonywać transfer b - bajtu (8 bitów), w - słowa (16 bitów) czy l - podwójnego słowa (32 bitów).
    Ponadto sufix _p oznacza, że procesor poczeka aż owa operacja dobiegnie końca (nie wiem w zasadzie, na co miałby czekać, skoro operacja trwa 1 cykl rozkazowy, ale używanie funkcji bez _p nie działało!). Zatem korzystam z funkcji inb_p/outb_p.
    A gdyby tego było mało, parametry do funkcji outb_p są podawane w niestandardowej kolejności - pierwszy to dana do wysłania, a drugi numer portu!

    i) przy próbie komunikacji z zegarkiem PCF8563, odczytywałem wszystkie rego rejestry i ku mojemu zdziwieniu, wartości zmieniały się co około sekunde.
    Jak się okazuje - bity oznaczone `-` są niezaimplementowane i odczytują się nie jako zera, ale jak chcą.
    Ponadto wyjście CLKOUT jest typu otwarty dren zatem trzeba je podciągnąć do VCC...
    Karta ISA do obsługi wyświetlacza HD44780 oraz I2C

    W efekcie powstały więc następujące płytki:
    - Główna płyta kontrolera w postaci karty ISA (złącze do podłączenia wyświetlacza, I2C, programatora oraz potencjometr do regulacji kontrastu wyświetlacza)
    - Płytki z urządzeniami I2C (zegar czasu rzeczywistego, pamięci eprom)
    - Rozgałęziacz I2C.
    Na razie nie mam jeszcze wlutowanych złącz, gdyż muszę kupić specjalne goldpiny, które uniemożliwią odwrotne podłączenie wtyczki.

    - Na chwile obecną mam oprogramowane wysyłanie tekstu do wyświetlacza
    - Skanowanie magistrali I2C (wyświetlenie adresów wszystkich aktywnych urządzeń)
    - Odczyt z zegara rtc na i2c (pcf8563) aktualnej daty

    W przyszłości planuje dołożenie termometru i2c, jakiegoś przetwornika ad/c oraz mikrokontrolera, który będzie w trybie slave wykonywał polecenia, przesyłane z komputera po magistrali 2c.

    Karta ISA do obsługi wyświetlacza HD44780 oraz I2C Karta ISA do obsługi wyświetlacza HD44780 oraz I2C Karta ISA do obsługi wyświetlacza HD44780 oraz I2C Karta ISA do obsługi wyświetlacza HD44780 oraz I2C
    Karta ISA do obsługi wyświetlacza HD44780 oraz I2C

    Fajne! Ranking DIY
    Potrafisz napisać podobny artykuł? Wyślij do mnie a otrzymasz kartę SD 64GB.
    O autorze
    phanick
    Poziom 28  
    Offline 
    phanick napisał 2291 postów o ocenie 2133, pomógł 50 razy. Mieszka w mieście Warszawa. Jest z nami od 2007 roku.
  • Computer ControlsComputer Controls
  • #2
    linuxtorpeda
    Poziom 21  
    Czy nierówności na złączu ISA (pogrubienia wynikającej z nadmiernej ilości cyny) nie powodują problemów przy wkładaniu karty do komputera?

    Projekt bardzo fajny :) Czemu nie zdecydowałeś się na nowszy standard złącza? PCI również ma swoje lata, a występuje jeszcze w niektórych komputerach.
  • #3
    kuuczoo
    Poziom 26  
    linuxtorpeda: może dlatego że PCI wymaga trochę więcej zasobów... :)
    Link
  • #4
    phanick
    Poziom 28  
    Nierówności tylko tak wyglądają na zdjęciu z uwagi na nierówne oświetlenie, tak naprawdę nadmiar cyny zebrałem plecionką aby powierzchnia była w miarę gładka, jednak takie styki i tak w porównaniu ze złoconymi są marnej jakości.
  • #5
    nsvinc
    Poziom 35  
    phanick napisał:
    z u wagina nierówne

    wagina...:D :D Widzę że świętujesz :P

    phanick napisał:
    Płyta ta strasznie mnie urzekła swoim małym rozmiarem.

    Pokaż fotke? (płyty, nie waginy) ;] Bardzo wiele starych płyt przerobiłem, zadna nie urzekła mnie rozmiarami, i przewaznie klasycznie pasowała w pudło typu mini/midi tower.

    Co do samego projektu - sądzę ze wartość edukacyjną na pewno ma, ale troche nie te czasy. Ja bym się osobiście nie wziął za zrobienie czegokolwiek pod standard który ma 30 lat i nikt już tego nie używa; chcąc zaszaleć polazłbym w stronę USB3.0.

    Nawet gdybyś szarpnął się na PCI (pod wpływem magicznych sił) to i tak ten standard konczy żywot. Do kart wymagających szalonej przepustowości jest PCI-E, do pamięci masowych SATA, do wszystkiego innego - USB...
  • Computer ControlsComputer Controls
  • #6
    PPK
    Poziom 26  
    Łezka się w oku kręci. Chyba zrobię to samo, bo mam w piwnicy jeszcze wszystkie oryginalne części do 386DX łącznie z HDD 80MB oraz FDD 360 i 1,2. Stary DOS 3,30 i WIN 3.11 też się znajdą :). Nawet trochę programów ocalało. A obudowę mam malutką z zasilaczem 150W od stacji roboczej. Ale to wszystko pod kątem LPT i RS232 do obsługi urządzeń zewnętrznych.
    p.s. 80385 to koprocesor ? Sam sobie odpowiedziałem, sorki.
  • #7
    phanick
    Poziom 28  
    nsvinc napisał:
    Pokaż fotke? (płyty, nie waginy) ;] Bardzo wiele starych płyt przerobiłem, zadna nie urzekła mnie rozmiarami, i przewaznie klasycznie pasowała w pudło typu mini/midi tower.

    Karta ISA do obsługi wyświetlacza HD44780 oraz I2C
    Chodzi o to, że (chyba wszystkie) płyty od 486 i sporo od 386 są 2 razy dłuższe, gdyż posiadają sloty vesa logic bus.

    PPK napisał:
    p.s. 80385 to koprocesor

    80387 to koprocesor
  • #8
    PPK
    Poziom 26  
    phanick napisał:
    nsvinc napisał:
    Pokaż fotke? (płyty, nie waginy) ;] Bardzo wiele starych płyt przerobiłem, zadna nie urzekła mnie rozmiarami, i przewaznie klasycznie pasowała w pudło typu mini/midi tower.

    Karta ISA do obsługi wyświetlacza HD44780 oraz I2C
    Chodzi o to, że (chyba wszystkie) płyty od 486 i sporo od 386 są 2 razy dłuższe, gdyż posiadają sloty vesa logic bus.

    PPK napisał:
    p.s. 80385 to koprocesor

    80387 to koprocesor


    Te sloty to nie jest Vesa logic tylko właśnie ISA :)


    sorki, Intel A82385 - Eisa bus controller (EBC). Koprocesor to oczywiście 387
  • #9
    snicek
    Poziom 15  
    Coś pięknego. Ja 2001 roku pisząc prace dyplomową zaprojektowałem i zrobiłem kartę ze złączem ISA jako sterownik uniwersalny. Przedstawiłem jej działanie jako sterownik inteligentnego domu. Wtedy takie hasło w google polskim wyskakiwało w może 20-30 wątkach. W ISA "zakochałem" się z powodu prostoty budowy. Części do karty zdobywałem z innych starych płyt głównych np: 7485 jako komparator dwójkowy 4-bit, do transmisji 74245 i utrzymania danych. Do nadawania 74273 a do sprzętowego wyboru ukł. scalonego 74138.
    Też pierwszy program napisałem w Pascalu ale z braku możliwości szybko przesiadłem się na C++.
    Kartę z braku naświetlarki wykonałem na uniwersalnej płytce a ścieżki zastąpił kynar.
    To złącze ISA jest banalne i można z łatwością pisać programy. Minus to prędkość, ale i tak się dało wiele zrobić.
  • #11
    mdm150
    Poziom 26  
    Wprawdzie to nie tylko płyty z prockami 386 miały bo i na późniejszych z pentium/celeron oraz amd też występowało te ISA... .
  • #12
    komatssu
    Poziom 28  
    mdm150 napisał:
    Wprawdzie to nie tylko płyty z prockami 386 miały bo i na późniejszych z pentium/celeron oraz amd też występowało te ISA... .

    Po drodze, między 386 i pentium, były jeszcze procesory 486...
    Zaś celerony pojawiły się dopiero równolegle z pentium II.
  • #13
    linuxtorpeda
    Poziom 21  
    W zasadzie to i pomiędzy pojawieniem się pentium a pentium II na rynku były też dostępne pentium pro, no ale to już raczej w serwerach
    http://pl.wikipedia.org/wiki/Pentium_Pro

    W ogóle to warto wspomnieć o tym, że kart ISA nadal używa się w komputerach przemysłowych, do tej pory można kupić (po dość wysokich cenach) karty ISA z interfejsem RS232 oraz LPT.
  • #14
    jestam
    Specjalista Automatyk
    linuxtorpeda napisał:
    W ogóle to warto wspomnieć o tym, że kart ISA nadal używa się w komputerach przemysłowych


    Używa się, ale nie dlatego, że ISA jest fajna czy lepsza od innych. Po prostu nie ma alternatywyy, gdy sterowanie maszyną jest sprzed 20 lat, ma jakieś stare karty (np. ARCnet, FIP albo jeszcze coś innego), a przerabianie tego na współczesny sprzęt jest zabójczo drogie.
  • #15
    phanick
    Poziom 28  
    Po zdobyciu odpowiednich gniazd, dokończyłem lutowanie wszystkich modułów i teraz całość prezentuje się tak.

    Karta ISA do obsługi wyświetlacza HD44780 oraz I2C Karta ISA do obsługi wyświetlacza HD44780 oraz I2C Karta ISA do obsługi wyświetlacza HD44780 oraz I2C Karta ISA do obsługi wyświetlacza HD44780 oraz I2C Karta ISA do obsługi wyświetlacza HD44780 oraz I2C

    Poprawiłem komunikacje z zegarkiem i zaimplementowałem komunikacje z pamięcią EEPROM. Niestety wciąż sen z powiek spędzał mi jeden problem - podczas wyszukiwania urządzeń na magistrali, czasami urządzenie zamiast dwóch, zajmowało trzy adresy. Myślałem, że to może zakłócenia spowodowane zbyt długimi kablami, ale np. odczyt pamięci EEPROM nigdy nie dawał przekłamanych wyników, jedyny problem był właśnie z wyszukiwaniem urządzeń.

    Wyszukiwanie polega na próbie skomunikowania się z każdym z możliwych adresów (od 0 do 255). Jeżeli urządzenie po wysłaniu adresu wyśle bit ACK (ściągnie linie SDA w dół) to znaczy, że zostało zaadresowane - jest dostępne na magistrali, a jeśli nie wyśle bitu ACK (linia SDA pozostanie w stanie 1) to znaczy, że urządzenie nie odpowiedziało. Adresy z zerem na końcu służą do zapisu, a z jedynką - do odczytu. Postanowiłem zobaczyć pod analizatorem stanów logicznych co tak naprawdę dzieje sie na magistrali gdy odpytywane są urządzenia:

    Karta ISA do obsługi wyświetlacza HD44780 oraz I2C

    Wysyłam adres 10101001 - nikt się nie zgłasza (ok - bo takiego urządzenia nie ma)
    Wysyłam adres 10101010 - zgłasza się urządzenie (ok - jest to adres to zapisu dla pamięci EEPROM)
    Wysyłam adres 10101011 - zgłasza się urządzenie (ok - jest to adres to odczytu dla pamięci EEPROM).
    Ale następnie linia SDA pozostaje w stanie niskim (!!!). I tu olśnienie - nic dziwnego. Urządzenie I2C po zaadresowaniu do odczytu zaczyna wystawiać swoje dane i dlatego próba adresowania kolejnych urządzeń przez moją karte kończy się konfliktami na magistrali i często przekłamanymi odczytami dalszych adresów.
    Rozwiązaniem tego faktu jest w momencie gdy urządzenie do odczytu się zgłosi, odczyt z niego ośmiu bitów oraz wysłanie bitu STOP. Dzięki temu urządzenie zwolni linię i będzie można odpytywać kolejne adresy!