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

[atmega162][C] Inicjalizacja i obsługa LCD.

galsan 27 Paź 2008 19:56 2093 7
REKLAMA
  • #1 5673780
    galsan
    Poziom 12  
    Witam,

    wiem że dużo już w tym temacie, ale nie moge znaleźć rozwiązania swojego problemu...

    Chyba nawet nie wychodzi mi poprawna inicjalizacja, ponieważ po niej na lcd mam wciąż tylko 2 wypełnione pixelami linie..


    
    #include <avr/io.h>
    #include <util/delay.h>
    #include <my_defs.h>
    
    
    #define LCD_E 	3
    #define LCD_RS 	2
    //#define LCD_RW
    #define LCD_4 	4
    #define LCD_5 	5
    #define LCD_6 	6
    #define LCD_7 	7
    
    #define LCD PORTA
    #define LCD_DIR DDRA
    
    // dec		128	64	32	16	8	4	2	1
    //
    // PORTA:	7	6	5	4	3	2	1	0
    //			|	|	|	|	|	|	|	|
    // LCD:		7	6	5	4	RS	E	-	-
    
    void del_us(uint32_t t_us)		// Lekko ponad mikro sec
    {
    	uint32_t t;
    	// dla 10 MHz cykl = 0,1 us
    	// dla 4 MHz cykl = 0,25 us
    	for(t = 0; t < t_us; t++);		//  13 cykli
    
    }
    
    void send_instr(uint8_t data, uint32_t time_us)
    {
    	//data = data << 2;	// Wyjścia LCD zaczynają się od pinu PB2
    	LCD = data;
    	del_us(1);				// minimalny czas 140 ns do ustalenia stanów
    	set_bit(LCD, LCD_E);	// włącz zbocze strobujące
    	del_us(1);				// czas trwania sygnału E min 450 ns oraz
    	clr_bit(LCD, LCD_E);	// zapis danych
    	del_us(1);				// min 20 ns na podtrzymanie po opadnięciu zbocza E
    	del_us(time_us);		// czas na wykonanie instrukcji
    }
    	
    
    void lcd_init()
    {
    	del_us(1);				// min 15ns na inicjalizacje LCD
    	LCD_DIR = 255;
    	for(uint8_t i = 0; i < 3; i++)
    		send_instr(48, 4100);
    	send_instr(32, 40);		// interfejs 4-bitowy
    	
    	send_instr(32, 1);		// set function
    	send_instr(128,40);		// 2 linie, matryca 5x7
    
    	send_instr(0, 1);
    	send_instr(128,40);		// tryb: wyłącz wyśw., kursor, miganie
    
    	send_instr(0, 1);		// clear
    	send_instr(16, 1640);
    
    	send_instr(0, 1);		// tryb wprowadzania
    	send_instr(96, 40);
    
    	send_instr(0, 1);		// włącz z mryganiem
    	send_instr(240, 40);		
    }
    
    int main()
    {
    	lcd_init();
    }
    


    Sterowanie ma być 4-bitowe, wyswietlacz 16x2
    Mikrokontroler to atmega162

    wie ktoś co jest nie tak? ja już nie wiem.....

    pozdrawiam

    Poprawiłem tytuł:
    https://www.elektroda.pl/rtvforum/topic1015361.html
    [c_p]
  • REKLAMA
  • #2 5673895
    rsikon
    Poziom 26  
    Wiele sie nie znam ale uzywam czegos takiego dla atmega16/32.

    poniższy plik (zalacznik lcd.h) ma lezec w ...Winavr\avr\include

    a ponizej przykładowy kod programu .

    Moze i sa lekkie niedociagniecia ale dziala :)



    
    
    
    #include <LCD.h>		// 	obsługa LCD z 
    				//	F_CPU 8000000UL
    				// 	<util/delay.h>
     				//	<avr/io.h>
    				//	<stdlib.h>
    
    
    
    int main(void)                        // program główny
    {
    LCD_init();
    LCD_clr();
    
    while(1)
    {
    LCD_xy(9,0); 
    write_text("test");
    
    }
    }
    
    
    Załączniki:
  • REKLAMA
  • #3 5677894
    galsan
    Poziom 12  
    Dzięki za kod.. Twój program działa.. Ale i tak szlag mnie trafia bo nie wiem do cholery co robię źle w swoim kodzie.. teraz troche go zmieniłem.. Poprawiłem błedy.. Wydaje mi się, że chociaż inicjalizacja powinna być poprawna.. a tu nic.. włączam go i zachowuje się różnie.. albo wyświetla jeden pasek w górnej linii albo jak resetuje go to coś zacznie mrygać albo jakiś znaczek się doda... no nie wiem.. Jeśli miałby ktoś chęci i zajrzał w ten mój kod i powiedział co nie tak to byłbym wdzięczny!


    
    #include <avr/io.h>
    #include <util/delay.h>
    #include <my_defs.h>
    
    
    #define LCD_E 	3
    #define LCD_RS 	2
    //#define LCD_RW
    #define LCD_4 	4
    #define LCD_5 	5
    #define LCD_6 	6
    #define LCD_7 	7
    
    #define LCD PORTA
    #define LCD_DIR DDRA
    
    #define instr	0
    #define text  	1
    
    // dec		128	64	32	16	8	4	2	1
    //
    // PORTA:	7	6	5	4	3	2	1	0
    //			|	|	|	|	|	|	|	|
    // LCD:		7	6	5	4	E	RS	-	-
    
    void del_us(uint32_t t_us)		// Lekko ponad mikro sec
    {
    	uint32_t t;
    	// dla 10 MHz cykl = 0,1 us
    	// dla 4 MHz cykl = 0,25 us
    	for(t = 0; t < t_us; t++);		//  13 cykli
    
    }
    
    void send_instr(uint8_t data, uint32_t time_us, uint8_t choice)
    {
    	uint8_t mask;
    
    	switch(choice)
    	{
    		case instr:
    			clr_bit(LCD, LCD_RS);	// RS = 0 dla instrukcji
    			mask = data & 0xF0;		// maskowanie 4 starszych bitów
    			LCD = mask;
    			del_us(1);				// minimalny czas 140 ns do ustalenia stanów
    			set_bit(LCD, LCD_E);	// włącz zbocze strobujące
    			del_us(1);				// czas trwania sygnału E min 450 ns oraz
    			clr_bit(LCD, LCD_E);	// zapis młodszej części bajtu
    			del_us(1);				// min 20 ns na podtrzymanie po opadnięciu zbocza E
    			data = data << 4;		// starsza część bajtu (na młodszej zera)
    			LCD = data;
    			del_us(1);
    			set_bit(LCD, LCD_E);
    			del_us(1);
    			clr_bit(LCD, LCD_E);
    			del_us(time_us);		// czas na wykonanie instrukcji
    		break;
    		
    		case text:
    		break;
    	}
    }		
    
    	
    
    void lcd_init()
    {
    	del_us(150000);				// min 15ms na inicjalizacje LCD
    	LCD_DIR = 255;
    	for(uint8_t i = 0; i < 3; i++)
    	{		
    		LCD = 3;
    		del_us(1);
    		set_bit(LCD, LCD_E);
    		del_us(1);
    		clr_bit(LCD, LCD_E);
    		del_us(5000);
    	}
    	
    	LCD = 2; del_us(1);	
    	set_bit(LCD, LCD_E);
    	del_us(1);
    	clr_bit(LCD, LCD_E);
    	del_us(4100);	
    	
    send_instr(0x28, 1000, instr);		// 4 bity, 2 linie, matryca 5x7
    
    send_instr(0x08,1000, instr);		// tryb: wyłącz wyśw., kursor, miganie
    
    send_instr(0x01, 1740, instr);		// czyść wyświetlacz
    
    send_instr(0x06, 1000, instr);		// bez przesuwania zawartości ekranu
    	
    send_instr(0x0C, 1000, instr);		// włącz wyśw. z mruganiem
    	
    }
    
    int main()
    {
    	lcd_init();
    }
    
  • #5 5678040
    galsan
    Poziom 12  
    Popatrzyłem, pomyślałem... ... i nic nie wymyśliłem nowego.. nie wiem czy sugerujesz coś niewłaściwego z czasami.. Dokumentacja co prawda podaje że po pierwszym LCD = 3 powinno być ponad 4,1 ms po następnym natomiast 100 us, po następnym nie pokazuje jaki to ma być czas, a po LCD = 2 również nie wskazuje jak długi ma to być czas...

    nie wiem... olśnij mnie....

    Dodano po 2 [minuty]:

    Szczególnie że wydaje mi się, że "zbyt długi" odcinek zwłoki nie wprowadzi błędów co najwyżej spowolni trochę pracę.. ale lepszy dłuższy niż zbyt krótki chyba... (?)
  • REKLAMA
  • #6 5678084
    zumek
    Poziom 39  
    galsan napisał:
    Popatrzyłem, pomyślałem... ... i nic nie wymyśliłem

    To kiepsko :(
    
       LCD=3; //ustaw bity nr. 0 i 1 w PORTA
    

    Linie LCD D7-D4 , masz na PORTA bity 7-4.

    Jasne :?:

    Piotrek
  • #7 5678137
    galsan
    Poziom 12  
    ! JAAAAAAAAAAAa ale ze mnie IDIOTAAAAA............................ ja pierniczeeeee..... tak to jest jak bezmyślnie się coś z dokumentacji przepisze... Dzięki!

    Dodano po 15 [minuty]:

    Ale i tak coś mam nie tak jeszcze.. Zmieniłem stosownie tamte instrukcje na LCD = 48, a potem LCD = 32, żeby mieć tak jak w dokumentacji wpierw sygnały na DB4 i DB5, a potem tylko na DB5... no bo chyba tak ma być prawda? No i coś kurcze dalej nie tego.. Nie wyswietla się migający kursor, a nawet dalej ta linijka.. :(
  • REKLAMA
  • #8 5678518
    zumek
    Poziom 39  
    galsan napisał:
    .. Nie wyswietla się migający kursor, a nawet dalej ta linijka.. :(

    A niby dlaczego , kursor miałby się wyświetlać :?:
    
    send_instr(0x0C, 1000, instr);      // włącz wyśw. z mruganiem 
    

    Powyższa instrukcja , to tylko "Display On" , a bity C i B masz wyzerowane.
    Display on/off control 0 0 0 0 1 D C B
    Popraw.
    W main() , brakuje mi na końcu jakiejś pustej pętli.
    Maskuj bity , których nie powinieneś modyfikować.
    LCD=( (LCD & 0x0F) | (dane & 0xF0) ); //high
    LCD=( (LCD & 0x0F) | (dane << 4) );//low
    


    Piotrek
REKLAMA