Elektroda.pl
Elektroda.pl
X
Proszę, dodaj wyjątek www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

LCD Atmega Inicjalizacja

gszyszka 06 Kwi 2005 01:33 6848 10
  • #1 06 Kwi 2005 01:33
    gszyszka
    Poziom 11  

    Posiadam LCD 2x16 (niestety nie jestem pewien co do rodzaju sterownika - na pewno HD44780 lub odpowiednik :) ,
    zakupiony na allegro:
    http://www.allegro.pl/show_item.php?item=46738573
    Wydaje się być sprawnym ponieważ po podłączeniu do zasilania pojawia się linia czarnych kwadracikow (tylko jedna)
    Nie udało mi się jak dotąd go zainicjalizować :(
    Próbowałem juz prawie wszystkiego(różne pdfy i różne czasy opóźnień, lektura elektrody), poświęciłem chyba dwa tygodnie i nic :(
    Efekt taki sam jak po podłączeniu do zasilania tzn czarne kwadraty w górnej lini
    a tutaj kawalek kodu

    Code:
    void LCD_Init(){
    
       //ustawienie portow jako wyjsciowe
       DDRB = 0xFF;
       DDRC = 0xFF;

       //czyscimy porty
       PORTB = 0x00;
       PORTC = 0x00;
       
       //czekamy az ustali sie napiecie
       delayms(500);
       
       
       D5_ON;
       D4_ON;
       EN_ON;
       delayms(1);
       EN_OFF;
       asm("nop");
       asm("nop");
       asm("nop");   
       PORTB = 0x00;
       PORTC = 0x00;

       delayms(50);   
       
       D5_ON;
       D4_ON;
       EN_ON;
       delayms(1);
       EN_OFF;
       asm("nop");
       asm("nop");
       asm("nop");   
       PORTB = 0x00;
       PORTC = 0x00;

       delayms(50);   

       D5_ON;
       D4_ON;
       EN_ON;
       delayms(1);
       EN_OFF;
       asm("nop");
       asm("nop");
       asm("nop");   
       PORTB = 0x00;
       PORTC = 0x00;
       
       delayms(50);   
       
       D5_ON;
       EN_ON;
       delayms(1);
       EN_OFF;
       asm("nop");
       asm("nop");
       asm("nop");   




       PORTB = 0x00;
       PORTC = 0x00;

       delayms(1);   

       D5_ON;
       EN_ON;
       delayms(1);
       EN_OFF;
       asm("nop");
       asm("nop");
       asm("nop");
       PORTB = 0x00;
       PORTC = 0x00;

       delay(1);      
       
       D7_ON;   //dwie linie wyswietlacza
       D6_OFF;   //5X7
       EN_ON;
       delayms(1);
       EN_OFF;
       asm("nop");
       asm("nop");
       asm("nop");
       PORTB = 0x00;
       PORTC = 0x00;
       delayms(1);      

       EN_ON;
       delayms(1);
       EN_OFF;
       asm("nop");
       asm("nop");
       asm("nop");
       PORTB = 0x00;
       PORTC = 0x00;

       delayms(1);      
       
       D7_ON;
       EN_ON;
       delayms(1);
       EN_OFF;
       asm("nop");
       asm("nop");
       asm("nop");
       PORTB = 0x00;
       PORTC = 0x00;

       delayms(1);      
       
       EN_ON;
       delayms(1);
       EN_OFF;
       asm("nop");
       asm("nop");
       asm("nop");
       PORTB = 0x00;
       PORTC = 0x00;

       delayms(1);      
       
       D4_ON;
       EN_ON;
       delayms(1);
       EN_OFF;
       asm("nop");
       asm("nop");
       asm("nop");
       PORTB = 0x00;
       PORTC = 0x00;

       delayms(1);   

       EN_ON;
       delayms(1);
       EN_OFF;
       asm("nop");
       asm("nop");
       asm("nop");
       PORTB = 0x00;
       PORTC = 0x00;

       delayms(1);   

       D6_ON;
       D5_ON;
       D4_ON;
       EN_ON;
       delayms(1);
       EN_OFF;
       asm("nop");
       asm("nop");
       asm("nop");
       PORTB = 0x00;
       PORTC = 0x00;

       delayms(1);      

    Wiem że to częste pytanie ale już się zniecheciłem od ciągłego próbowania bez efektów, wiec jażeli ktoś wskaże błąd to jestem wdzięczny[/url]

    0 10
  • #2 06 Kwi 2005 04:04
    LordBlick
    VIP Zasłużony dla elektroda

    A schemat myszki zjadły... ;)
    Tryb 8 czy 4bit ?
    Czemu wszystki opóźnienia są w milisekundach ? największe potrzebne to 2 ms, a najmniejsze to 0.04 ms. Nadgorliwość też nie zawsze popłaca, po co ciągle "czyścisz porty" ? Po co te 3 x nop, skoro i tak czekasz 1 ms, to ma byc jakies magiczne zaklęcie ? ;)
    Najlepsza jak dla mnie strona o sterowaniu LCD na HD44780 ( po jej przeczytaniu wydłubałem od ręki procedurkę w asm, która wyświetliła "AAAAAAAA" ;) ) :
    http://home.iae.nl/users/pouweha/lcd/lcd0.shtml
    Pozdrawiam, Light-I

    0
  • #3 06 Kwi 2005 11:31
    Artii80
    Poziom 10  

    Ja mam podobny problem i takie same objawy. Tylko w moim przypadku używam kompilatora keil i przykładowych programów z książki K.Kardacha wiec pomyłka jest nie możliwa, wszystkie programy z tej ksiąki były zwykle pewne. Po podłączeniu nie ma nic, no chyba ze podkręcę kontrast wtedy mam rządek czarnych kwadratów. Szukam rozwiązania mojego problemu, najlepiej przykładowych programów. Załączam program, którym steruje wyświetlacz, cw20 z książki Programowanie mikrokontrolerów z serii 8x51 w języku c

    #include <sfr51.h> /* zbiór nagłówkowy adresów rejestrów i bitów */
    sbit Button = P3^2; /* definicja adresu bitu Button */

    #define DATA_LCD P0 /* wyświetlacz podłączony do portu P0 */
    #define DC_LCD P0_4 /* linia D/~C (Data/Control) */
    #define RW_LCD P0_5 /* linia R/~W (Read/Write) */
    #define E_LCD P0_6 /* linia E (Enable) */

    /* Polecenia sterujące wyświetlacza LCD ----------------------------------*/
    #define HOME 0x80 /* ustaw kursor na początek pierwszej linii LCD */
    #define INITDISP 0x28 /* ustaw interfejs wyświetlacza LCD na 4-bity */
    #define HOM2 0xc0 /* ustaw kursor na początek drugiej linii LCD */
    #define LCDON 0x0f /* włącz LCD, włącz kursor, włącz migotanie */
    #define CLEAR 0x01 /* zeruj LCD,
    ustaw kursor na początek pierwszej linii LCD */

    /* Prototypy funkcji obsługi wyświetlacza LCD ----------------------------*/
    void LCD_ctrlWR(char);
    void LCD_dataWR(char);
    void put_message (char *);

    #define LCD_init { LCD_ctrlWR(INITDISP); \
    LCD_ctrlWR(CLEAR); LCD_ctrlWR(LCDON);}

    void main(void) {
    char i=0x20; /* pierwszy wyświetlany znak to odstęp */
    LCD_init; /* inicjalizacja LCD */


    put_message ("LCD DEMO: <<<<press P3.2");

    while(1) {
    while( Button); /* czekanie na wartość 0 na linii P3.2 */
    while(!Button); /* czekanie na wartość 1 na linii P3.3 */

    LCD_ctrlWR( HOM2); /* kolejne znaki ASCII drukowane są na
    początku drugiej linii wyświetlacza */
    LCD_dataWR( i++);
    }
    }

    /* ------------------------ sprawdzenie flagi zajętości wyświetlacza LCD */
    BYTE check_busy (void) {
    BYTE bf;
    DATA_LCD |= 0x0f; /* dane znajdują się na młodszej czwórce portu */
    DC_LCD = 0; /* linia D/~C=0 : odczyt słowa Control (statusu) */
    RW_LCD = 1; /* linia R/~W=0 : odczyt */
    E_LCD = 1;
    bf = DATA_LCD & 0x08; /* najstarszy bit informuje o zajętości LCD */
    E_LCD = 0;
    E_LCD = 1; /* linia Enable E=1: odczyt z wyświetlacza */
    E_LCD = 0; /* linia Enable E=0:koniec odczytu */
    return (bf);
    }



    /*------------------------------------- zapis 4-bitów do wyświetlacza LCD */
    void write_nibble ( BYTE nibble) {
    E_LCD = 0; /* Enable=0 */

    DATA_LCD &= 0xf0; /* pozostaw starszą czwórkę portu danych bez zmian */
    RW_LCD = 0; /* linia zapisu R/~W=0 */
    nibble &= 0x0f; /* tylko 4-młodsze bity będą zapisane */
    DATA_LCD |= nibble; /* wystawienie danych do zapisu */

    E_LCD = 1; /* linia Enable E=1: zapis do wyświetlacza */
    E_LCD = 0; /* linia Enable E=0: koniec zapisu */
    }


    /*------------------- zapis słowa sterującego Control do wyświetlacza LCD */
    void LCD_ctrlWR ( BYTE cmde) {
    while (check_busy() ); /* sprawdzenie zajętości wyświetlacza */
    DC_LCD = 0; /* wybierz rejestr Control LCD */
    write_nibble(cmde >> 4); /* zapis starszej czwórki bajtu Control */
    write_nibble(cmde); /* zapis młodszej czwórki bajtu Control */
    }


    /*---------------------------------- zapis danych Data do wyświetlacza LCD */
    void LCD_dataWR ( BYTE byte) {
    while (check_busy() ); /* sprawdzenie zajętości wyświetlacza */
    DC_LCD = 1; /* wybierz rejestr danych Data LCD */
    write_nibble(byte >> 4); /* zapis starszej czwórki bajtu Control */
    write_nibble(byte); /* zapis młodszej czwórki bajtu Control */
    }

    /*------------ podprogram drukowania ciągu znaków aż do ogranicznika 0x00 */
    void put_message (char *s) {
    while (*s)
    LCD_dataWR( *s++);
    }

    0
  • #4 06 Kwi 2005 11:59
    gmp
    Poziom 19  

    Do autora: twoj program jest bardzo nieczytelny, albo zrob funkcje ktora wysylaj bajta na szyne danych do wyswietlacza, albo napisz PORTX=costam, zwazywszy ze ustawiasz wszystko bitowo (np: D4_ON) a potem zerujesz port
    (PORTC=0;) .
    Co do dlugosci opoznien to sprawdzone mam to na wielu wyswietlaczach roznych producentow i nie ma problemu z za dlugim czassem, gorej gdy jest za krotki. Starcze LCD robiona na orginalnym HD chodzily najednym programie, teraz niestety co producent to jest inna procedura inicjalizacji, choc roznia sie bardzo niewiele. Na ogol roznia sie tylko "dalszymi" bajtami tego co trzba wyslac. No i jeszce nie mialbym pewnosci co do sprawnosci tego wyswietlacza. Poza tym programy na LCD znajdzeisz w necie , a na pewno na avrfreaks. A i jeszce daj definicje swoich makr, bo ja nie wiem czy np: E_ON jest poprawnie.

    0
  • #5 06 Kwi 2005 12:05
    PioTherm
    Poziom 15  

    Częstymi przyczynami wyświetlania kwadracików jest złe podłączenie wyświetlacza do mikrokontrolera. Drugą przyczyną może być to że np w ATMEGA32 defaultowo masz zajęte piny na porcie C dla interfejsu JTAG wskutek czego jak masz podłączony wyświetlacz pod te zajęte piny wyświetla on dziwne znaczki lub właśnie kwadraty.

    0
  • #6 06 Kwi 2005 12:46
    gszyszka
    Poziom 11  

    Co do makr

    Code:
    //definicja polaczen
    
    #define D7_ON sbi(DDRC, PC5);sbi(PORTC, PC5);
    #define D7_OFF sbi(DDRC, PC5);cbi(PORTC, PC5);

    #define D6_ON sbi(DDRC, PC4);sbi(PORTC, PC4);
    #define D6_OFF sbi(DDRC, PC4);cbi(PORTC, PC4);

    #define D5_ON sbi(DDRC, PC3);sbi(PORTC, PC3);
    #define D5_OFF sbi(DDRC, PC3);cbi(PORTC, PC3);

    #define D4_ON sbi(DDRC, PC2);sbi(PORTC, PC2);
    #define D4_OFF sbi(DDRC, PC2);cbi(PORTC, PC2);

    #define EN_ON sbi(DDRB, PB3);sbi(PORTB, PB3);
    #define EN_OFF sbi(DDRB, PB3);cbi(PORTB, PB3);

    #define RS_ON sbi(DDRB, PB1);sbi(PORTB, PB1);
    #define RS_OFF sbi(DDRB, PB1);cbi(PORTB, PB1);


    dodam ze probowalem te inaczej np
    Code:
    //definicja polaczen
    
    #define D7_ON sbi(PORTC, PC5);
    #define D7_OFF cbi(PORTC, PC5);

    #define D6_ON sbi(PORTC, PC4);
    #define D6_OFF cbi(PORTC, PC4);

    #define D5_ON sbi(PORTC, PC3);
    #define D5_OFF cbi(PORTC, PC3);

    #define D4_ON sbi(PORTC, PC2);
    #define D4_OFF cbi(PORTC, PC2);

    #define EN_ON sbi(PORTB, PB3);
    #define EN_OFF cbi(PORTB, PB3);

    #define RS_ON sbi(PORTB, PB1);
    #define RS_OFF cbi(PORTB, PB1);

    co do czytelności to uważalem że tak będzie najlepiej ze względu na podłączenie wyświetlacza w nieklasyczny sposób tzn nie do jednego portu i wysyłanie bajtów na port troche zniekształaca całość

    czy to możliwe że to właśnie PORTC może być odpowiedzialny za taki stan rzeczy??

    0
  • #7 06 Kwi 2005 12:51
    PioTherm
    Poziom 15  

    Dokładnie. Napisałem powyżej że w ATMEDZE32 połowa pinów z portu C jest wykorzystywana domyślnie przez interfejs JTAG.

    Jakiego proca używasz ?

    0
  • #8 06 Kwi 2005 13:08
    gszyszka
    Poziom 11  

    Dokladnie ATmega32 :)
    jestem podpiety z linią danych D4-D7 pod piny PC2-PC5
    z tego co widze to wlasnie te piny sa wykorzystywane przez interfejs JTAG czy czeka mnie przelutowywanie układu???

    0
  • Pomocny post
    #9 06 Kwi 2005 13:31
    Pituś Bajtuś
    Poziom 28  

    Code:
       
    
    MCUCSR |= 0x80;
    MCUCSR |= 0x80;


    Wstaw te dwie instrukcje na początku programu. JTAG zostanie wyłączony będziesz mógł normalnie korzystać z pinów portu C. I to że są dwie identyczne instrukcje to nie przypadek ani pomyłka :) Tak ma być.

    0
  • Pomocny post
    #10 06 Kwi 2005 14:17
    PioTherm
    Poziom 15  

    No to Bingo. Także wyświetlacz masz pewnie sprawny i układ z programem również. Ja wiem tylko jak wyłączyć obsługę interfejsu JTAG
    za pomocą FUSE Bitów w BASCOMIE.
    Niestety na C się nie znam ani na ASMie

    pzdr.
    Piotrunio

    0
  • #11 06 Kwi 2005 16:43
    gszyszka
    Poziom 11  

    Z pewnością to było to ponieważ wyświetlacz zareagował na inicjalizację "zbladnięciem" i pojawieniem sie kawałka drugiej linii. Jeszcze nic nie wyświetlam ale mam nadzieje że to już tylko kwestia czasu:)
    Dzięki wielki sam bym na to w życiu nie wpadł

    0