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

AVR i wyświetlacz LCD nie chcą się dogadać

arek944 26 Mar 2011 23:52 2265 12
REKLAMA
  • #1 9327125
    arek944
    Poziom 11  
    Witam serdecznie
    Mam pewien problem z wyświetlaczem LCD, otóż nie chce on w ogóle ze mną gadać. I chciałbym wiedzieć co jest nie tak, i jak ewentualnie roziązać problem? Poniższy program jest zaczerpnięty z Biblii Dolińskiego z niewielkimi zmianami kosmetycznymi.
    Jeśli taka informacja okaże się pomocna, to korzystam z programatora STK500 i oprogramowania AVR Studio 4.16.638.

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    Gdzie, po wywpołaniu funkcji odmierzany czas podaje się w us:
    LCD_Wait(45000); //czekaj 45ms

    ... Przynajmniej z punktu widzenia logiki powinno działać, a jednak okazuje się, że wyświetlacz po prostu nie chce nic wyświetlać - czasami pojawia się standardowy bład inicjalizacji (16 pól w 1szym wierszu) lub wyświetlacz jest po prostu czysty... Proszę o jakieś wskazówki, idee, cokolwiek, bo mnie się już wyczerpały pomysły...
  • REKLAMA
  • #2 9327260
    michalko12
    Specjalista - Mikrokontrolery
    W funkcji PORT_config() masz

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    Z tego powodu w funkcji LCD_INIT() brakuje

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    Kod: C / C++
    Zaloguj się, aby zobaczyć kod
  • #3 9327779
    arek944
    Poziom 11  
    No niestety, zamiana ta nie sprawiła, że wyświetlacz przemówił.. dalej jest to samo :(
  • REKLAMA
  • REKLAMA
  • #5 9327934
    arek944
    Poziom 11  
    Jeśli w funkcji PORT_config() jest
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    to na wyświetlaczu świeci się16 pełnych pól 1szej linii, zaś gdy przerobię na
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    to wyświetlacz robi się czysty...
    Może ktoś korzysta po prostu z jakiejś działającej biblioteki, ew ma kawałek kodu z obsługą LCD1602 i mógłby się podzielić?
  • REKLAMA
  • Pomocny post
    #6 9328016
    pablo19_1f
    Poziom 11  
    Tutaj masz moją wersję obsługi wyświetlacza:

    
    /*
     * LCD.c
     *
     * Created: 2011-03-18 16:27:56
     *  Author: Czech
     */ 
    
    #include <avr/io.h>
    
    #define set_e PORTB|=(1<<1)
    #define clr_e (PORTB&=~(1<<1))
    
    #define set_rs PORTB|=1
    #define clr_rs (PORTB&=~1)
    
    
    void wait_ms(int x) //odczekuje okolo x*1ms
    {
    	unsigned char b;
    	for(;x>0;x--)
    			for(b=0;b<100;b++);
    				__asm("nop");
    	
    }
    
    void send_to_lcd(void) //przesyla rozkazy/dane do LCD
    {
    	wait_ms(1);
    	set_e;
    	wait_ms(1);
    	clr_e;
    }
    
    void clr_lcd(void)
    {
    	PORTA=0;
    	send_to_lcd();
    	PORTA=1;
    	send_to_lcd();
    }
    		
    
    void lcd_init(void)
    {
    	PORTB=0;
    	PORTA=3;
    	wait_ms(20);
    	send_to_lcd();
    	wait_ms(5);
    	send_to_lcd();
    	send_to_lcd();
    	PORTA&=~1;
    	send_to_lcd();
    	send_to_lcd();
    	PORTA<<=2;
    	send_to_lcd();
    	PORTA=0;
    	send_to_lcd();
    	PORTA=8;
    	send_to_lcd();
    	PORTA=0;
    	send_to_lcd();
    	PORTA=1;
    	send_to_lcd();
    	PORTA=0;
    	send_to_lcd();
    	PORTA=6;
    	send_to_lcd();
    	PORTA=0;
    	send_to_lcd();
    	PORTA=0b00001100;
    	send_to_lcd();
    	
    }
    	
    void send_char(char a)
    {
    	wait_ms(1);
    	set_rs;
    	PORTA=a>>4;
    	send_to_lcd();
    	PORTA=a;
    	send_to_lcd();
    	clr_rs;
    }
    
    void send_string(char * x)
    {
    	while(*x)
    	{
    		send_char(*x);
    		x++;
    	}	
    }
    
    int main(void)
    {
    	DDRA=0xff;
    	DDRB=0xff;
    	lcd_init();
    	send_string("Witaj!");
    	while(1)
        {
    				 
        }
    }
    


    Połączenie uC->LCD:

    PA0->D4
    PA1->D5
    PA2->D6
    PA3->D7

    PB0->RS
    PB1->E


    Może odstępy czasowe nie są najmniejsze z możliwych, ale działa ;)
  • Pomocny post
    #7 9328038
    michalko12
    Specjalista - Mikrokontrolery
    Tego typu konstrukcje są błędne:

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    powinno być:

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod
  • #8 9328458
    arek944
    Poziom 11  
    Cytat:
    Tego typu konstrukcje są błędne:

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    Szczerze się przyznam, że tego nie wiedziałem, lub też się nie zastanawiałem głębiej nad tym, ale pewien przełom jest, otóż załadowałem funkcję LCD_Wait(); do prostej aplikacji mającej zamrugać ledami PORTC...
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    ...i się okazało, że zarówno pierwsza, jak i druga wersja funkcji są o kant d ;)
    Natomiast _delay_ms(); daje bardzo stabilne działanie (w odniesieniu do zegarka wskazówkowego) obarczone niewielkim błedem.
    Spróbuję przerobić ten zapis wartości do LCD_PORT wg zaleceń michalko12, a jak to nie pomoże, to LCD_Wait(); zastąpię _delay_ms(); :D

    Dodano po 44 [minuty]:

    DZIAŁA!! :D

    Oto co zostało wspólnymi siłami stworzone:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    AVR i wyświetlacz LCD nie chcą się dogadać

    Sposób podłączenia:
    LCD_E --> PA0
    LCD_RS --> PA1
    LCD_DB4 --> PA4
    LCD_DB5 --> PA5
    LCD_DB6 --> PA6
    LCD_DB7 --> PA7
  • #9 9343499
    arek944
    Poziom 11  
    Mam jeszcze jedno zagadnienie, o które chciałbym spytać. Otóż, czy możliwe jest wyświetlanie znaków polskich na LCD bezpośrednio w taki sposób:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    Czy trzeba napisać signal, a potem w miejsce literki l nanieść poprawkę wpisując ł? O ile dobrze się doczytałem, najpierw ab cokolwiek napisać po polsku, należy stworzyć w programie tablicę zawierającą odpowiednio przygotowane kody danej literki i umieścić je w CGRAM wyświetlacza?
  • #10 9343777
    mirekk36
    Poziom 42  
    arek944 napisał:
    Mam jeszcze jedno zagadnienie, o które chciałbym spytać. Otóż, czy możliwe jest wyświetlanie znaków polskich na LCD bezpośrednio w taki sposób:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod
    ?


    Jest możliwe i to bez najmniejszego problemu. Co więcej można zrobić nawet dynamiczne ładowanie polskich ogonków do CGRAM w trakcie samego wyświetlania licząc na to, że za jednym razem na LCD nie pojawi się więcej niż 8 różnych takich znaków ;)

    Trzeba tylko zrobić sobie przemapowanie kodów znaków nadlatujących do LCD. Czyli samemu obsłużyć np kody Win1250 z komputera lub inny używany u ciebie standard.
  • #11 9344227
    arek944
    Poziom 11  
    Cytat:
    Trzeba tylko zrobić sobie przemapowanie kodów znaków nadlatujących do LCD.

    OK, brzmi ciekawie, tylko jak się do tego dobrać? :D
    Dynamiczne ładowanie polskich znaków nie jest problemem, bo to już mam ogarnięte w osobnej funkcji, którą de facto należy wywołać po inicjalizacji wyświetlacza, podając w jej argumentach, który znak będę aktualnie ładowany i na które miejsce do CGRAM.
  • #12 9344333
    mirekk36
    Poziom 42  
    Nie nie, dynamiczne ładowanie polskich ogonków to znaczy np, że:

    1. w funkcji, która wysyła pojedynczy znak na LCD sprawdzasz czy jego kod jest w zakresie np WIN1250?

    2. jeśli jest w zakresie to sprawdzasz jaka to dokładnie polska literka i dopiero w tedy ładujesz ją do CGRAM

    wtedy jeśli ci literka ł z twojego wyrazu sygnał, to załadujesz jej obraz do CGRAM i poślesz ten kod do DDRAM LCD ;)
  • #13 10095578
    arek944
    Poziom 11  
    Zapomniałem zamknąć tego tematu :D w każdym razie wszystko działa i raz jeszcze dziękuję wszystkim za pomoc
REKLAMA