Skocz do zawartości

Przeszukaj forum

Pokazywanie wyników dla tagów 'cmos'.

  • Szukaj wg tagów

    Wpisz tagi, oddzielając przecinkami.
  • Szukaj wg autora

Typ zawartości


Kategorie forum

  • Elektronika i programowanie
    • Elektronika
    • Arduino i ESP
    • Mikrokontrolery
    • Raspberry Pi
    • Inne komputery jednopłytkowe
    • Układy programowalne
    • Programowanie
    • Zasilanie
  • Artykuły, projekty, DIY
    • Artykuły redakcji (blog)
    • Artykuły użytkowników
    • Projekty - DIY
    • Projekty - DIY roboty
    • Projekty - DIY (mini)
    • Projekty - DIY (początkujący)
    • Projekty - DIY w budowie (worklogi)
    • Wiadomości
  • Pozostałe
    • Oprogramowanie CAD
    • Druk 3D
    • Napędy
    • Mechanika
    • Zawody/Konkursy/Wydarzenia
    • Sprzedam/Kupię/Zamienię/Praca
    • Inne
  • Ogólne
    • Ogłoszenia organizacyjne
    • Dyskusje o FORBOT.pl
    • Na luzie

Kategorie

  • Quizy o elektronice
  • Quizy do kursu elektroniki I
  • Quizy do kursu elektroniki II
  • Quizy do kursów Arduino
  • Quizy do kursu STM32L4
  • Quizy do pozostałych kursów

Szukaj wyników w...

Znajdź wyniki, które zawierają...


Data utworzenia

  • Rozpocznij

    Koniec


Ostatnia aktualizacja

  • Rozpocznij

    Koniec


Filtruj po ilości...

Data dołączenia

  • Rozpocznij

    Koniec


Grupa


Imię


Strona


TempX

Znaleziono 1 wynik

  1. Słowem wstępu, trzeba przyznać że tytuł artykułu sam w sobie jest dość kontrowersyjny. Dlaczego autorowi przyszło na myśl chwalić się najgorszą kartą graficzną na świecie, i to jeszcze drugą? Już spieszę z odpowiedzią: jest to moduł większego projektu, który jest dla mnie - autora - swego rodzaju wyzwaniem, dla czytelników - ciekawostką. A sprawa rozchodzi się o komputer ośmiobitowy. Jak zatem mogłaby wyglądać najgorsza karta graficzna? GeForce GT 210? Nie, pewnie jakiś radeon. Może zintegrowana grafika? W dobie XXI wieku już mało kto pamięta karty jeszcze starsze - stosowano niegdyś karty na szynach ISA, jak Trident TVGA-9000i (którego akurat posiadam). Karty te generowały obraz w rozdzielczości 640x480px, a przynajmniej przy trybie tekstowym. Przy trybie tekstowym, czyli karta generowała tylko i wyłącznie znaki, czasem tylko jednego koloru - lecz miała wtedy "fizycznie" największą rozdzielczość. Tryb graficzny umożliwiał kontrolę obrazu co do piksela i zmieniać nawet jego kolor, lecz wymagało to większej ilości zużycia RAMu - stąd tryby graficzne często były niższej rozdzielczości. Nie są to jednak karty najgorsze. Zainspirowany filmem Bena Eatera o jego "najgorszej karcie graficznej", postanowiłem samodzielnie zrobić takową kartę. Przyda się ona do zbudowania komputera ośmiobitowego, który już wcześniej zacząłem realizować, a że jeszcze przyszły mi płytki do rozlutu i były wakacje, był to całkiem dobry pomysł. Jak zatem prezentuje się karta? Źle. Na pewno teraz nasuwa się mnóstwo pytań czytelnikowi - więc już spieszę z opisem całości. Proces tworzenia karty zacząłem od postawienia założeń - na pewno nie chcę używać układów mocniejszych od Z80 (dla przykładu atmega 328p jest 16x mocniejsza od Z80), ponieważ nie ma to sensu - przerost formy nad treścią. Nie potrzebuję także trybu graficznego, chcę tylko terminal - więc tryb tekstowy mi wystarczy. Obraz chcę wyświetlać na monitorze kineskopowym (docelowo), więc chcę generować sygnał VGA. Kolor by się przydał, lecz priorytetem jest samo wyświetlanie znaków. Tak więc wiedziałem co chcę zrobić, musiałem się zastanowić jak. Najsampierw - zobaczyłem jaki sygnał należy generować. Tak więc, sygnał VGA to głównie 5 sygnałów - cyfrowa linia synchronizacji poziomej i pionowej, oraz 3 analogowe dla kolorów: czerwony, zielony i niebieski. Sygnał ten był opracowywany dla monitorów CRT, który obraz był generowany przez działko elektronowe, i sygnały cyfrowe tym działkiem sterują. Działko to pluje linię (display), po czym potrzebuje jeszcze chwili czasu (front porch), po czym - można powiedzieć - "synchronizuje się" z sygnałem (sync pulse), i wraca na początek linii (back porch). Całkiem podobnie jest dla linii synchronizacji pionowej. Kolory, jak już wcześniej wspomniałem, są sygnałem analogowym. Oznacza to, że im większe napięcie damy na ten sygnał, tym kolor będzie mocniejszy, a przy użyciu 3 sygnałów R, G i B - można te kolory łączyć. Jeżeli obraz nie jest wyświetlany, linie te powinny być podciągnięte do masy układu. I to w skrócie byłoby tyle - jeszcze rzut oka na czasy poszczególnych etapów sygnałów: Jak widać, aby uzyskać obraz 800x600 pikseli trzeba całość taktować aż czterdziestoma megahercami. Bramki logiczne, a i też niektóre mikrokontrolery nawet nie obsługują takich dużych częstotliwości - więc zdecydowałem się obniżyć ten zegar do 20MHz, co pozwoli uzyskać obraz 400x300 pikseli. Czasy zostają te same - lecz liczba pikseli się zmieni, co będzie bardzo ważną informacją w dalszej części artykułu. Wracając do układu Bena Eatera: on te czasy generował przy użyciu trzech liczników 4bit, potem porównywał konkretną liczbę z tych liczników, aby następnie sterować przerzutnikiem R/S dla linii synchronizacji. Ja uznałem "ale czemu tak komplikować sobie życie", zastosowałem jeden licznik binarny 12bit, a liczby porównywałem tylko logicznymi "jedynkami". Tak zatem wyglądają pierwsze dwa arkusze schematów: Pierwszy arkusz pokazuje kwestię zasilania, oraz złącz (karta będzie karmiona pięcioma woltami z zasilacza). Na złączu 40pin zaś znajdziemy ośmiobitową szynę danych, szesnastobitową szynę adresów, sygnały do wybierania jednego z 8 urządzeń, oraz piny WR i RD, odpowiadajace za operację zapisu i odczytu na wybranym urządzeniu. Złącze to łatwo można zdobyć z starych nagrywarek na szynie IDE, tasiemkę też - którą akurat kupiłem i skróciłem. Następny arkusz pokazuje licznik poziomy. Sam zegar na początku zrealizowałem przez układ 74HC14, z kwarcem 20MHz. Działał tylko po przyłożeniu palca (lub parówki) do styków kwarcu. Zamiast tego, generator sygnału 20MHz napędza licznik, który zlicza kolejno liczby w postaci binarnej. Liczby te sprawdzają bramki NAND, które interesują konkretnie 4 liczby: 400, 420, 484 i 528. Liczby te wziąłem z powyższej tabelki - a konkretnie po pierwszych 400 pikselach ustawiamy przerzutnik RS, dla wew. sygnału do wyświetlania pikseli. Sygnał HBLANK jest aktywny wtedy, kiedy nie powinny być wyświetlane żadne piksele. Następnie przy 420 pikselach ustawiamy kolejny przerzutnik, tym razem dla sygnału synchronizacji linii. Po 64 pikselach licznik ten jest resetowany, a przy 528 pikselu resetowany jest przerzutnik do wyświetlania pikseli, oraz resetowany sam licznik - następuje nowa linia, co jest też sygnałem taktującym dla zegara pionowego (sygnał jest przepuszczany przez bramkę NOT, ponieważ linia resetu i zegara jest aktywna w stanie wysokim). Tutaj też dość ważna informacja: na liczbę binarną składają się zarówno zera, jak i jedynki. Dlaczego zatem porównuję same jedynki? Każdy inny sygnał (który powinien być zerem) musiałbym podpiąć do bramki przez NOT, co by skutecznie powieliło ilość użytych układów. Porównywanie samych jedynek umożliwiło ominięcie tego, lecz "wybrana" liczba będzie występowała kilka razy. Nie ma to znaczenia i tak, ponieważ przerzutnik i tak został już ustawiony/zresetowany, a licznik jest potem resetowany. Tutaj jednak popełniłem kilka błędów. Do samej noty licznika (a nie samego pinoutu) zajrzałem duuużo później, gdzie przeczytałem, że liczniki te obsługują do 12MHz i to przy zasilaniu 15V (!) - tłumaczyło to wiele anomalii, lecz co ciekawe - zastosowanie liczników tych samych, lecz w wersji SMD zniwelowało wszelkie te anomalie. A że nie miałem pod ręką przejściówek z SO16 na DIP16, zrobiłem te śmieszne pajączki które widać na zdjęciu. Ważne że działa. Jest też jeszcze jeden błąd, który i ja popełniłem, i pan Eater popełnił: w informatyce zawsze się liczy od zera. Myślę że po wytłumaczeniu poprzedniego licznika, tutaj nie będzie niespodzianek. Jednak z racji tego, że na sygnał taktujący dostajemy 37.(87)kHz (zgodnie z tabelką), szukamy także pikseli podanych w tabelce: 600, 601, 605, 628. Technicznie rzecz biorąc pozwalałoby to na wyświetlanie obrazu 400x600px, lecz! Taka rozdzielczość byłaby troszkę niestandardowa, a litery byłyby mocno spłaszczone - przez co nieczytelne. Tak zaprojektowany i złożony układ prezentował się następująco: Generował on tylko i wyłącznie kolorowy ekran, lecz to już było coś. Problem zaczął w kwestii RAMu i ROMu. Zaczynając od RAMu, uznałem, że najlepiej będzie dodać licznik ósemkowy, który w połączeniu z bramkami AND, będzie po kolei sprawdzał każdy bit występujący na szynie danych pamięci ROM. W praktyce efekty okazały się co najmniej marne: Powinien się tutaj wyświetlać jeden znak, wykrzyknik, a dostałem... to. Potem spróbowałem czegoś podobnego lecz zamiast licznika ósemkowego - demultiplekser 74LS138. Bezskutecznie. Postanowiłem więc "wbudować" ten element karty do samej pamięci, marnując ją przy tym ogromnie: ponieważ obraz jest pobierany bezpośrednio z ROMu, wykorzystując przy tym jeden bit. A jest to pamięć ośmiobitowa. Tak więc zastosowany układ M27C1001, który jest pamięcią UV EPROM o pojemności 1Mbit, okazał się pomieścić "tylko" 4 tablice znaków po 255 znaków. A wygląda to tak: Linie adresu A0-A7 to wybór znaku, A8-A11 wybór linii, A12-A14 wybór kolumny, A15 - discord light theme, A16 - CP438, o którym mowa za chwilę. Pamięć samą w sobie zaprogramowałem wcześniej zrobionym i przerobionym programatorem, i mogę jeszcze powiedzieć, że mimo wersji o czasie odczytu do 100ns, wszystko działa sprawnie (a powinien być niższy od 50ns). Nawiązując jeszcze do samego wykonania płytki: przy projektowaniu schematu, nie wiedziałem do końca czy on zadziała. Dlatego nie trawiłem żadnych płytek, lecz całość wykonałem na płytkach prototypowych. Zasilanie doprowadzam górą, kynarami; sygnały zaś doprowadzam drutem 0.12mm z silniczka, który już się prawie skończył... Wracając: akurat się tak złożyło, że znak będzie duży na 8x16 (2³ x 2⁴) pikseli, co przy ekranie 400x300 pozwoli na wyświetlanie 50x18 znaków, nawet nieźle jak na gołe bramki logiczne. Po podpięciu pamięci RAM obraz wyglądał tak: Są to losowe znaki, co wynika z tego że pamięć RAM przy włączeniu zawiera losowe dane. A, nie powiedziałem jeszcze o samej tablicy znaków. Mocno inspirując się klasyczną, dosową czcionką, tak wygląda cała tablica znaków: Wykorzystując dodatkowy bit adresu pamięci EPROM, pozwoliłem sobie na zapis nowej tablicy znaków: CP438, gdzie standardowe znaki alfabetu są zastąpione przez Standardowy Alfabet Galaktyczny. Następnie w Processingu zrobiłem prosty program konwertujący piksele obrazu w tablicę zmiennych typu byte, jak docelowo miały być zapisywane znaki, a następnie tablicę tę skopiowałem do programatora. Niestety, nie opracowałem jeszcze zapisu z komputera, lecz na pewno będę musiał prędzej czy później zrobić - na chwilę obecną, programy muszą być mniejsze od pamięci samej atmegi. Więc skoro pamięć RAM i ROM już działała, to czego do szczęścia jeszcze trzeba? Ano, potrzebujemy coś zapisać do tej karty! I tutaj zaczęły się prawdziwe schody. Problem polega w tym, że pamięć RAM jest ciągle odczytywana przez timery. Przerwanie ich będzie skutkowało też przerwaniem wyświetlania obrazu. No i niestety, ale tak jest, ponieważ nie mam pomysłu jak inaczej wymyślić zapis. Tak więc, do odcinania timerów od RAMu służą tutaj bufory trójstanowe - 74HC245 i 244 (takie miałem pod ręką). Ale, zwykłe linie adresów i danych też trzeba było odciąć - więc musiałem zastosować tutaj 8 układów po 16 nóżek, więc lutownicą się namachałem. Na moje szczęście, powyższy schemat zadziałał za pierwszym razem. Jednak przez rozbieg, pomiędzy pamięć ROM i RAM dałem także bufor - jeżeli wstawiłbym tam zatrzask, to w najszczęśliwszym wypadku (zapis krótszy niż 0.4us) nie byłoby nic widać. Jednak zatrzask skutecznie by pozwolil zredukować liczbę anomalii, ale mimo wszystko tragedii nie ma przy zastosowaniu "zwykłego" bufora. Jak widać, proces zapisu jest aktywowany tylko, kiedy i linia zapisu i linia wyboru urządzenia są w stanie niskim - jest to realizowane bramką OR. Tak więc bufory są, wszystko jest, ale... kartę trzeba było jakoś sprawdzić. Jako, że płytkę z samym Z80 będę lutował później, na razie zapis przeprowadza Arduino MEGA (jeszcze raz: ono służy TYLKO do testowania karty, nie do generowania obrazu!), i karta działa zadziwiająco dobrze: Obraz jest monochromatyczny; zastosowanie palety kolorów byłoby ciekawym wyzwaniem. Kolor wybiera się przełącznikiem DIP przy złączu VGA. Ciekawa rzecz też była kiedy na początku źle zapisałem pamięć, na odwrót... Niestety, występuje także kilka anomalii. Lewy brzeg ekranu jest okupowany przez zgliczowane piksele, przez które najlepiej cały obraz jest przesunąć o znak w prawo. Pamięć ROM także wypaliłem w niezbyt komfortowych dla niej warunkach, więc piksele nie są do końca dobrze wypalone. Ciekawą anomalią są też te paski z tyłu, które występują tak trochę sinusoidalnie? Są stałe, rezystory pulldown i pullup nic nie dają... ale jeżeli sygnał koloru prześle przez płytkę stykową, linie magicznie znikają! Kiedy dostanę porządny oscyloskop (obecnie mam przystawkę hanteka, która mierzy tylko w kHz), głębiej to zbadam. Wiem też, że karta jest mocno wrażliwa na zakłócenia, np. z kabla USB czy oscyloskopu. Cały kod i obliczenia (dokumentację) udostępnię dopiero kiedy je sobie uporządkuję, bo kod arduino jest bardzo nieoptymalny, a obliczenia rozsiane po notesie... jak to pozbieram, wyślę na GitHuba, a całość opiszę po angielsku. EDIT: link do githuba Tak czy siak; karta jest gotowa, i może pracować razem z Z80, lub jako osobny moduł dla takiego Arduino (jak wiemy z poprzedniej konstrukcji, atmega nie do końca sobie radzi z VGA...) Wniosek: zostawić stare układy TTL, kupić płytkę z FPGA i się uczyć z forbotowego kursu. discord light theme
×
×
  • Utwórz nowe...

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.