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

[ATmega32] ATmega32 i LCD WC1602A - nieprawidłowe wyświetlanie tekstu po starcie

GrysikWRC 10 Maj 2013 19:28 2412 12
REKLAMA
  • #1 12292637
    GrysikWRC
    Poziom 10  
    Cześć, mam problem z obsługą LCD modułu uruchomieniowego ATMEGA v.2 firmy gotronik. LCD to wc1602a, programuję ATmege32 przez usbasp+avrdude. Kod którego używam, to niewiele zmodyfikowane demo LCD ze strony propoxa.

    Problem polega na tym, że po uruchomieniu nie wyświetla się tekst, po odpięciu przewodu z PD1 (linia E LCD), chwilowym połączeniu z PD2 (linia D4 LCD) i ponownym połączeniu pojawiają się krzaki oraz oczekiwany tekst.
    Co mogę robić źle?

    Command line AVRduda:
    "E:\AVRDude\avrdude\avrdude.exe" -p m32 -c usbasp -P com1 -U flash:w:"C:\Users\9rYs1k\Documents\Atmel Studio\LCDtest\LCDtest\Debug\LCDtest.hex":a -U lfuse:w:E1 -U hfuse:w:99 -F

    W załącznikach klasy i nagłówki mojego projektu, poniżej link do filmu z działania.

    Przepraszam, jeśli to banalne pytanie, ale już którąś godzinę się z tym męczę.
    :arrow: film z działania
  • REKLAMA
  • #2 12292742
    tehaceole

    Poziom 28  
    A fuse bity dla odpowiedniego taktowania poprawnie masz ustawione? Zerkni tutaj - może coś Cię zainspiruje.
  • REKLAMA
  • #3 12292901
    GrysikWRC
    Poziom 10  
    No właśnie tu się uderzę w pierś, nie do końca wiem jak to powinienem ustawić. Skorzystałem z kalkulatora i ustawiłem wg. niego dla wew. kwarcu 1MHz z resztą wartości domyślnych, a także dla zew. 16MHz (zmieniając F_CPU w projekcie), po tym co posłałeś zmieniłem jeszcze resztę bitów tak jak opisane w "Konwencja zmian..." na tej stronie, tyle że dla wew. 1MHz, ale mój problem pozostaje...

    [edit]
    może żeby było jasno - próbowałem l:21 h:c7, l:e1 h:99, l:ff h:99

    Ok, zauważyłem jeszcze jedno ciekawe działanie - wyjęcie i ponowne włożenie wyświetlacza często powoduje prawidłowe wyświetlanie pierwszej linii (sterowanej w pętli while(1)). Kwestia wyświetlacza? Błędy w funkcji LCDinit?

    [edit]
    Ok, temat prawie zakończony - prawdopodobnie tak jak myślałem problemem jest inicjacja wyświetlacza, jest on na sterowniku KS0066U. Ma ktoś gotową taką funkcję i mógłby podesłać?
  • Pomocny post
    #4 12294196
    tehaceole

    Poziom 28  
    KS0066U jest kompatybilny z HD44780.
    Jeżeli korzystasz z opracowań które podałem to muszą one działać w 100%.
    Co do inicjalizacji: kiedyś miałęm z jakimiś LCD problem dla kwarców większych niż 11MHz. Wtedy sprowadziło się to do modyfikacji kodów obsługi LCD o wprowadzenie wymuszonych opóźnień (define "Szybkosc") co jednak jest bardzo nieeleganckie. Zamiast tego w przykładzie 15 jest kod korzystający z odczytu flagi zajętości wyświetlacza.

    Weź też pod uwagę fakt, że możesz mieć zwyczajnie uszkodzony wyświetlacz. Kilka lat temu sam się na coś takiego naciąłem. Po prawie tygodniu walki w akcie wielkiej desperacji zakupiłem nowy LCD i... o dziwo ruszyło od kopa:) heheeh
    Jeszcze jedno: moje przykłady są dla Atmega16, więc uważaj z wgrywaniem fusów do innych procków... :)
  • REKLAMA
  • #5 12294268
    excray
    Poziom 41  
    Twoja inicjalizacja LCD to jakiś horror. Kwiatki takie jak to:
    LDP|=0<<LCD_D7|0<<LCD_D6|1<<LCD_D5|1<<LCD_D4;
    Co niby ma robić 0<<LCD_D7 szczególnie w połączeniu z tym: LDP|=?
    Rozpisałeś inicjalizację na bity aby w funkcji "LCDsendCommand" kopnąć tą uniwersalność "z buta w twarz" takimi liniami jak LDP=((cmd>>2)&0b00111100);
  • #6 12294405
    GrysikWRC
    Poziom 10  
    @tehaceole
    Zauważyłem, że dla mega16 :) , dlatego wprowadziłem Twoje fuse bity do kalkulatora, sprawdziłem ustawienie i przeliczyłem dla mega32, wyszło tak samo. Sprawdzę jeszcze Twoje kody, może ruszą poprawnie. Z tego co wyczytałem inicjalizacja KS0066U jest troszkę inna (http://www.actron.de/de/data/FAQ/ks0066u.pdf), jeśli nie ruszy z Twoich kodów spróbuję napisać LCDinit na nowo.

    @excray
    Biblioteka nie moja, to przykładowe aplikacje dla płytki EVBavr05 Propoxa. Faktycznie niektóre rzeczy pisane nonsensownie jak sam zauważyłeś... ale nie będę pisać wszystkiego na nowo dopóki coś działa jak powinno.
  • #7 12294425
    excray
    Poziom 41  
    GrysikWRC napisał:
    Biblioteka nie moja, to przykładowe aplikacje dla płytki EVBavr05 Propoxa. Faktycznie niektóre rzeczy pisane nonsensownie jak sam zauważyłeś... ale nie będę pisać wszystkiego na nowo dopóki coś działa jak powinno.

    No właśnie nie działa jak sam raczyłeś zauważyć zakładając temat. Porty są źle ustawiane. Ten kod jest zły.
  • #8 12294484
    GrysikWRC
    Poziom 10  
    Na płytce EVBavr05 działał, tam miałem Atmege16 i inny wyświetlacz (pewnie HD44780). A to, że kilka ustawień portów jak te "|= 0<<" nie będzie działać to jeszcze nie znaczy, że są źle ustawione - to jest po prostu niepotrzebne. Nie wiem po co ktoś to pisał, żeby stan portu wyglądał przejrzyściej? Ja bym opisał takie rzeczy w komentarzu. Z tego co widzę to wtedy kiedy należy ustawiać zera jest używane normalnie "&=0<<" albo "&=~(1<<".
  • REKLAMA
  • #9 12294495
    excray
    Poziom 41  
    Alma mater! Nie chodzi nawet o te nieszczęsne 0<<x tylko o to że robisz OR na porcie. Po 2-3 takich operacjach masz wszystkie bity ustawione i nic więcej się nie zmienia. Chcesz to walcz z fusami. Zostaniesz męczennikiem tego wyświetlacza.
  • #10 12294502
    BlueDraco
    Specjalista - Mikrokontrolery
    A po co w ogóle te operatory logiczne przy inicjowaniu portów? Nie można po ludzku napisać np.:

    DDRA = 0b01100111;

    Albo:

    DDRB = 1 << PB3 | 1 << PB2 | 1 << PB0;

    Pojedzncya instrukcja ustawi ci DDR POPRAWNIE, w odróżnieniu od gimnasytyki z |= i &=
  • #11 12294513
    excray
    Poziom 41  
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    Poczytaj komentarze do linii, przemyśl.
  • #12 12294610
    GrysikWRC
    Poziom 10  
    @tehaceole
    Dzięki za rozwiązanie problemu! Użyłem Twojej biblioteki do LCD z wymuszeniem opóźnień (ustawiłem parametr szybkosc na 2) i wyświetlacz działa poprawnie.

    @excray
    Nie przesadzaj z męczennikiem wyświetlacza, przyznaję, kod do d.
    Ale nie do końca rozumiem Twój tok myślenia...
    Dlaczego
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod
    skoro jedynka z ORem jest tylko dla D5 i D4. Powinno być 0b00110000. Przecież 2 linie wyżej
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod
    odwołuje się do kierunku portu, a jeszcze dwie mamy LCP i LDP = 0x00. Więc jeśli dobrze myślę 0x00 | 0b00110000 = 0b00110000
  • #13 12294965
    tehaceole

    Poziom 28  
    GrysikWRC napisał:
    @tehaceole
    Dzięki za rozwiązanie problemu! Użyłem Twojej biblioteki do LCD z wymuszeniem opóźnień (ustawiłem parametr szybkosc na 2) i wyświetlacz działa poprawnie.
    Jak już pisałem: to rozwiązanie z opóźnieniami jest cholernie nieeleganckie. Zerknij na przykład z wykorzystaniem pinu RW.
    Ostatecznie można pozostać przy obsłudze z tym kodem, jednak z zastosowaniem buforowanego wyświetlania - dzięki temu to "waskie"gardło jakie powstaje przy zapisie do LCD staje się wtedy pomijalne. Oczywiście przy założeniu, że resztę kodu też staramy się napisać nieblokująco.

    Cieszę się, że Ci to ruszyło. Miłej dalszej zabawy :)
REKLAMA