logo elektroda
logo elektroda
X
logo elektroda
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

Obrazek na TV - program w C bez asemblera

xamrex 07 Sty 2012 13:57 2923 19
  • #1 10361595
    xamrex
    Poziom 28  
    Witam,
    Postanowiłem sobie napisać program w C, który wyświetla na ekranie TV jakiś obrazek..

    Chciałbym do tego użyć języka C, beż użycia asm,którego w ogóle nie znam.
    Tutaj można zdobyć trochę wiedzy:
    Link i Link

    No i napisałem sobie taki prowizoryczny na początek kod(bez timerów itp)
    !!Uwaga poprany i działający kod jest TUTAJ !!
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    Obraz ma mieć 41 na 31 pixeli..

    Generalnie zasada działania jest taka, że program pobiera z tabeli dane,
    i jeśli pobierze 1 to ustawa pixel szary, jeśli 2 to biały, jeśli 0 to czarny.
    A jeśli będzie to 3, to znaczy, że właśnie skończyła się cała linia, i należy wysłać impuls synch poziomej.

    Niby wszystko ładnie i cacy, ale napotkałem się na problem,którego nie potrafię przyskoczyć (pewnie dlatego, że źle się za ro biorę)

    Załóżmy, że
    1)pierwszą linię procesor obrabia w 63.5us (czyli poprawnie bo tyle ma dokładnie być)
    2)Drugą obrobi w ten sam czas (63.5),
    3)Trzecią obrobi w czas dłuższy(mi wyszło prawie o 3us)
    // obrabia ją dłużej bo jest warunek
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    Więc musi program sprawdzić kolejny warunek i wszystko wykonuje się dłużej..

    Czy da się jakoś nad tym 'zapanować' aby każda linia była wykonywana w tym samym czasie?

    Jak sobie z tym poradzić??

    P.S program ma wyświetlać napis TAMA w ramce na ekranie TV
  • #2 10361619
    mickpr
    Poziom 39  
    zmień
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    na tabelkę którą indeksował będziez zmienną, i z niej pobierał wartość
    Dla twojego przykładu:

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod
    ...
    i wartość masz z wyrażenia
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod
  • #3 10361655
    xamrex
    Poziom 28  
    No ale jak tak..
    Przecież
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    I nie mogę wsadzić do tabeli czegoś takiego:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    Co równa się temu
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    Dodano po 1 [minuty]:

    A już wiem jak to zrobić :))
    Dzięki za pomysł:)
    // Dla przyszłych pokoleń pierwsze 2 linie i 3 końcowe linie powinno zostać takie jak są
    KONIECZNIE na ostatnim miejscu w każdej linii musi znajdować się 0, (wyjątkiem jest ostatnia linia)

    Zrobiłem to tak:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    Mam nadzieję, że o to ci chodziło
  • #4 10362204
    tmf
    VIP Zasłużony dla elektroda
    W C nie da się zrobić rzeczy, które są krytyczne czasowo. Z tego prostego powodu, że prawie nie masz kontroli nad tym jak kompilator wygeneruje kod. To co chcesz zrobić robi się właśnie na timerach, dzięki temu impulsy synchronizacji są w ściśle określonych miejscach, a jest to niezywkle ważne gdyż TV jest prostym układem analogowym i nie ma za wielkich możliwości dostosowania się do zmian, w efekcie obraz będzie pływał. Z przyczyn praktycznych wygodniej jest tez rozpocząć zabawę nie od TV lecz od zwykłego monitora komputerowego z wejściem VGA. Masz tam nie tylko rozdzielone składowe koloru, ale także osobno podaje się impulsy V i HSYNC. Monitor też ma o wiele większe zdolności adaptacyjne do otrzymanego sygnału. Jak już ci zadziała na monitorze to do TV droga prosta.
  • #5 10362348
    mickpr
    Poziom 39  
    xamrex napisał:

    Mam nadzieję, że o to ci chodziło


    Bardziej mi chodziło o pomysł, nie o merytorykę i konkretną implementację.
    Pomysł uniezależnienie wykonywania od instrukcji "if".
    Przechodziłem podobne katusze w assemblerach, gdzie musiałem swego czasu wyliczać takty zegara z uwzględnieniem skoków warunkowych.

    Jak wspomniał kolega 'tmf' - tworzenie takich rzeczy w C - jest trochę karkołomnym, dużo zależy od kompilatora i opcji kompilacji.
    W assemblerze mógłbyś sam zadbać o takty (jeśli już tak chcesz uniknąć timerów).

    Aha - jeszcze jedno:
    Zauważ, że jeśli przyjdzie ci potem ochota na dołożenie ewentualnego przerwania - wszystko zaczyna się sypać. Chyba, że wyłączysz przerwania.
  • #6 10363086
    xamrex
    Poziom 28  
    tmf napisał:
    Z przyczyn praktycznych wygodniej jest tez rozpocząć zabawę nie od TV lecz od zwykłego monitora komputerowego z wejściem VGA.


    Ja w sumie zabrałem się od TV, bo jest (przynajmniej wg mnie) dużo łatwiej o dokumentację odnośnie sygnału PAL
    np.
    http://www.cesr.ncsu.edu/agdean/stiglitz/STIGLitz_Extended.htm
    http://www.eyetap.org/ece385/lab5.htm
    http://www.javiervalcarce.eu/wiki/TV_Video_Signal_Generator_with_Arduino
    http://instruct1.cit.cornell.edu/courses/ee476/video/
    http://www.atmel.com/dyn/resources/prod_documents/mega163_3_04.pdf
    http://instruct1.cit.cornell.edu/courses/ee476/video/index.html
    http://www.maxim-ic.com/app-notes/index.mvp/id/734
    http://www.serasidis.gr/circuits/colour_bar_gen/colour_bar_gen.htm
    http://www.kolumbus.fi/pami1/video/pal_ntsc.html
    http://www.rickard.gunee.com/projects/video/pic/howto.php
    http://www.retroleum.co.uk/electronics-articles/pal-tv-timing-and-voltages/
    A jak generować sygnał VGA, to znalazłem jedynie coś konkrentego tutaj
    Link
    Ale ta strona jakoś do mnie nie przemawia;/

    Jeśli ktoś znalazł jakieś konkretne informacje odnośnie sygnału VGA(budowa ramki itp)
    to bardzo proszę o linki :)

    P.S jutro dam znać, czy mi zadziałał ten kod na TV :)
  • #7 10365562
    xamrex
    Poziom 28  
    Kod, który podałem działa wyśmienicie;))
    Jak widać jest możliwość napisania tego pod C;) Oczywiście wspomagałem się debuggerem :)
  • #8 10367218
    pancio
    Poziom 16  
    a możesz pokazać jak to wygląda na tv?
  • #9 10369534
    xamrex
    Poziom 28  
    kod z animacją ( może działać niestabilnie)
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    No i filmik (nie zdjęcie), bo to "animacja" będzie ;)




    P.S akurat taki miałem TV :) Proszę się nie śmiać ;P
  • #10 10373738
    darres1
    Poziom 13  
    Witaj,
    Czy wystarczy tylko te trzy oporniczki, według tego schematu:

    Obrazek na TV - program w C bez asemblera

    żeby to zadziałało, podłączyłem to do atmegi8, na wewnętrznym kwarcu 8Mhz, wgrałem hexa i nie działa, jakiś schemacik by się przydał.
  • #11 10374008
    xamrex
    Poziom 28  
    Aha, no tak,
    Sorki,

    Ja używałem 2 rezystorów (3ci nie jest konieczny u mnie, ale nie wiem jak jest w rzeczywistości, chociaż większosć ludiz, pisze, że też wystarczą dwa)
    Ten trzeci jest w odbiorniku TV.

    Prędkość to 16MHz, więc na 8 Mhz nie dasz rady wyświetlić niczego;/

    Jak nie chcesz nic kombinować z kodem to do pinu PD0 podpinasz 470om
    a do pinu PD1 1k,
    Ale sądzę że również może być konfiguracja 1k i 300om
    Tylko pamiętaj o kwarcu 16Mhz
  • #12 10378437
    darres1
    Poziom 13  
    Witam,
    czyli dokładnie tak samo jak w tej grze Snake -> https://www.elektroda.pl/rtvforum/topic2176292.html
    ta gra działa na moim zestawie poprawnie, a z twoimi kodami są problemy:
    wersja ostatnia uruchamia się na sekundę, potem migają czarno białe paski
    a z pierwszym kodem, jest prawie dobrze, ale w napisie "TAMA", a raczej w poszczególnych blokach są lekkie skrzywienia, może byś wrzucił hexa, to bym wiedział gdzie szukać przyczyny.
  • #13 10378881
    xamrex
    Poziom 28  
    Tak, ta animacja, może działać niestabilnie, bo już rozjeżdżają się czasy...
    Nie chce mi się tego poprawiać..
    Jeśli miałbym ci coś poradzić to spróbuj tak:
    Znajdx to:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    I spróbuj zamienić na;
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    Teraz powinna bardzo szybko animacja ruszać tylko 'ustami'

    Daj znać, czy działa,, czy może dalej lipa

    Dodano po 2 [minuty]:

    darres1 napisał:
    napisie "TAMA", a raczej w poszczególnych blokach są lekkie skrzywienia, może byś wrzucił hexa, to bym wiedział gdzie szukać przyczyny.


    Ja akurat mam tak,że ucina mi prawą stronę..
    Ale tak jak pisałem chciałem tylko podchwycić idee, i nie chce tego robić do porządku..
    Ucina dlatego, że część wychodzi z ekranu z prawej i z lewej storny, a że nie jest to jednakowa ilość, to mi ucięło..
    Można by to oczywiście skorygować, ale dużo w tym pracy i nie widzę sensu.
  • #14 10383218
    darres1
    Poziom 13  
    Dzięki, ale niestety lipa, ważne jednak że pierwszy kodzik działa ładnie i mogę sobie już coś tam pokombinować,
    jak będę miał chwilę czasu, to może jakiś programik na PC-ta zrobię do generowania tablic,
    skompilowałem kod z tej strony i też jest ok -> http://www.javiervalcarce.eu/wiki/TV_Video_Signal_Generator_with_Arduino

    Dodano po 35 [minuty]:

    Już działa animacja :-), zmieniłem opóźnienie w funkcji:

    void sync_pulse()
    {
    LEVEL_BLACK;
    _delay_us(1.1);
    LEVEL_SYNC;
    _delay_us(4.4);
    LEVEL_BLACK;
    _delay_us(4.6); //--------tutaj było 5.6
    }
  • #15 10384597
    silvvester
    Poziom 25  
    xamrex napisał:
    Kod, który podałem działa wyśmienicie;))
    Jak widać jest możliwość napisania tego pod C;) Oczywiście wspomagałem się debuggerem :)


    Na stronach atmela jest sporo o pisaniu w C. Na avr-y w C można napisać kod odpowiadający temu w ASM. Bo avr-y zaprojektowano pod CCCCCCCCCCCC !!!!!!!!!
  • #16 10389968
    tmf
    VIP Zasłużony dla elektroda
    silvvester napisał:
    xamrex napisał:
    Kod, który podałem działa wyśmienicie;))
    Jak widać jest możliwość napisania tego pod C;) Oczywiście wspomagałem się debuggerem :)


    Na stronach atmela jest sporo o pisaniu w C. Na avr-y w C można napisać kod odpowiadający temu w ASM. Bo avr-y zaprojektowano pod CCCCCCCCCCCC !!!!!!!!!


    Tak, sporo, całe dwie noty, w dodatku poświęcone raczej optymalizacji.
    Się kolega marketingu naczytał, AVRy są tak zaprojektowane pod C jak każdy inny procesor. O tym wspaniałym dopasowaniu dobitnie może świadczyć brak rejestru indeksowego stosu, niepełna funkcjonalność rejestru X, czy brak instrukcji odtwarzającej ramkę stosu. Właściwie jedynym ułatwieniem dla kompilatora C jest w miarę ortogonalna lista instrukcji.

    Xamrex: to co stworzyłeś z C ma już niewiele wspólnego, spróbuj powyższy kod skompilować pod dowolnym innym kompilatorem C - powodzenia. Ba, ściągnij sobie inną wersję avr-gcc, skompiluj i zobacz efekty. Już rozumiesz, co miałem na myśli pisząc, że C się do tego nie nadaje?
    Kolejna sprawa - masz prościutki programi, praktycznie ręcznie dobrałeś timingi (czym się to więc różni od napisania tego od razu w assemblerze), a i tak napotykasz problemy. Tak jak pisałem, do generacji trzeba maksymalnie wykorzystać sprzęt, np. timery do generowania synchronizacji i ich przerwania do generowania linii. To ma niewielkie znaczenie w programie bez interakcji, który wyświetla statyczny obrazek, ale próbuj teraz do swojego dzieła dodać cokolwiek, np. jakąś interakcję z użytkownikiem, albo chociażby np. wyświetlanie temperatury na ekranie. Zobaczysz jaka kaszana powstanie.
  • #17 10390045
    JarekC
    Poziom 32  
    Witam,

    Do wyświetlania informacji na monitorze VGA lepiej zaprząc CPLD/FPGA niż procesor.
    Generowanie obrazu pochłania większą część mocy obliczeniowej uP.
    Wykorzystanie przerwań trochę pomoże ale może mieć skutki uboczne w postaci
    lekkiego drżenia linii (wynika to z tego iż w zależności jaka instrukcja jest wykonywana
    w momencie zgłoszenia obługa przerwania będzie mieć rózne opóźnienia)
    Cytat:
    If an interrupt occurs during execution of a multi-cycle instruction, this instruction is completed
    before the interrupt is served.


    Osobiście przy projektach z wykorzystaniem monitora korzystam z karty TeleVGA.
    Przykład jej wykorzystania w jednym z moich układów można znaleźć w dziale "DIY konstrukcje".
    https://www.elektroda.pl/rtvforum/topic1839236.html#10120357

    Pozdrawiam
    JarekC
  • #18 10390249
    tmf
    VIP Zasłużony dla elektroda
    JarekC: nie jest tak źle :) Drżenia nie będzie, bo najdłuższe instrukcje na AVR trwają 2 cykle zegara, przy 20MHz daje nam to 100ns. Przesunięcie synchronizacji o te 50ns będzie niezauważalne. Oczywiście CPLD lub FPGA to rozwiązanie fajne, ale skomplikowane. Nie z powodu użycia samego CPLD, tylko on wymaga także zewnętrznej pamięci video, która też painna być dwuportowa, lub też dostęp procesora do niej musi być realizowany przez CPLD. Kupa połączeń i komplikacja. FPGA mają wbudowaną pamięć, ale wymagają zewnętrznego FLASHa do bootowania, lub też mają piekielne obudowy typu tqfp144.
    Zawsze też można zastosować rozwiązanie proste i tanie - dedykowany procesor generujący obraz. Zresztą przy możliwościach współczesnych procesorów, nawet 8-bitowych generacja obrazu zostawia spore rezerwy. Zobacz np. Uzebox, a tam jest przecież stary AVR, co by było gryby mieli 32MHz XMEGę, lub ARM?
  • #20 10390606
    tmf
    VIP Zasłużony dla elektroda
    Oczywiście masz rację, dla EGA czy VGA w takim podstawowym trybie AVR odpada. Chociaż też nie do końca - można wykorzystać SPI lub UART, wtedy za jednym wpisem generujesz 8 pixeli i dot clock rzędu 16 MHz, a nawet 25 (dla XMEGA) jest realny. Oczywiście będzie to sztuka dla sztuki i obraz mono lub z paroma koloramy jeśli się wykorzysta np. 3 kanały SPI.
REKLAMA