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

Atmega8 + LCD 4bit. Podłączenie wyświetlacza, nota katalogowa.

Konsul 20 Mar 2006 12:06 5615 10
  • #1 2435972
    Konsul
    Poziom 23  
    Posty: 772
    Pomógł: 37
    Ocena: 20
    Kupiłem wyświetlacz zgodny z HD44780. Są na nim następujące informacje SSCM16ULGY-03 2K04-50. Niestety nie mogę znaleźć żadnej noty katalogowej z opisem wyprowadzeń szukając po tych oznaczeniach. Nie wiem jak go podłączyć a nie chce go popsuć. Znalazłem tylko opis komunikacji do innego LCD ale wydaje mi się, że on akurat jest dla wszystkich taki sam skoro jest ten standard HD44780. Z jednej strony LCD jest 2x7 styków a z drugiej 2 od katody i anody czyli pewnie chodzi o podświetlenie. Druga sprawa to ten tryb 4 bitowy. Rozumiem, że jeśli go używam to wysyłam 2x po 4bity przy przesyłaniu bajtu. Nie rozumiem natomiast jak mam włączyć ten tryb skoro do jego włączenia musze przesłać cały bajt. Myślałem, że tryb 4bit jest dla oszczędzenia wyprowadzeń w uC ale żeby go włączyć musze chyba działać w trybie 8bitowym bo jak mam wysłać do LCD informacje o trybie 4bit przesyłając dane 2x4bit skoro jestem jeszcze w trybie 8bi :). Troche zamotałem ale napewno rozumiecie o co mi chodzi.
  • #2 2436069
    Zaquadnik
    Poziom 27  
    Posty: 998
    Pomógł: 103
    Ocena: 25
    Tryb 4-ro bitowy włączasz przesyłając komendę 4-ro bitową do LCD, także wcale nie musisz mieć tych 8 linii danych ;) Jak będę miał możliwość, to wkleję Ci kod :]
    Pozdrawiam

    Oto i obiecany kod :]
    
    .include "m16def.inc"
    
    .equ RS = PB4
    .equ E = PB3
    .equ DB4 = PB2
    .equ DB5 = PB1
    .equ DB6 = PB0
    .equ DB7 = PA0
    
    ;tutaj beda procedury niezbedne do obslugi LCD
    
    ;================================
    LCDInit:
    		push R18
    		push R16
    		cbi PORTB,RS
    		cbi PORTB,E
    		call SendDrei
    		call DlugaPauza         ;opoznienie okolo 5ms
    		call SendDrei
    		call KrotkaPauza
    		call SendDrei
    		call KrotkaPauza
    		call SendZwei
    		call KrotkaPauza
    		ldi R16,0x28
    		call Send2nibbles		
    		call KrotkaPauza
    		ldi R16,0x06
    		call Send2nibbles
    		call KrotkaPauza
    		ldi R16,0x0C
    		call Send2nibbles
    		call KrotkaPauza
    		ldi R16,0x03
    		call Send2nibbles
    		call KrotkaPauza
    		sbi PORTB,RS
    		pop R16
    		pop R18
    		ret
    ;================================
    
    ;================================
    LCDclear:
    		push R16
    		push R18
    		cbi PORTB,RS
    		ldi R16,0x01
    		call Send2nibbles
    		call DlugaPauza
    		sbi PORTB,RS
    		pop R18
    		pop R16
    		ret
    ;================================
    
    ;================================
    LCDhome:
    		push R16
    		push R18
    		cbi PORTB,RS
    		ldi R16,0x02
    		call Send2nibbles
    		call DlugaPauza
    		sbi PORTB,RS
    		pop R18
    		pop R16
    		ret
    ;================================
    
    ;================================
    LCDnextLine:
    		push R16
    		push R18
    		cbi PORTB,RS
    		ldi R16,0xC0
    		call Send2nibbles
    		call KrotkaPauza
    		sbi PORTB,RS
    		pop R18
    		pop R16
    		ret
    ;================================
    		
    ;================================
    LCDznak:
    		push R18
    		sbi PORTB,RS
    		call Send2nibbles
    		call KrotkaPauza
    		cbi PORTB,RS
    		pop R18
    		ret
    ;================================
    
    ;================================
    LCDshiftLeft:
    		push R16
    		push R18
    		cbi PORTB,RS
    		ldi R16,0x18
    		call Send2nibbles
    		call KrotkaPauza
    		sbi PORTB,RS
    		pop R18
    		pop R16
    		ret
    ;================================
    	
    ;================================
    LCDshiftRight:
    		push R16
    		push R18
    		cbi PORTB,RS
    		ldi R16,0x1C
    		call Send2nibbles
    		call KrotkaPauza           ;opoznienie okolo 250us
    		sbi PORTB,RS               ;(nie pamietam dokladnie)
    		pop R18                       ;mozesz sobie obliczyc
    		pop R16                       ;kwarc mam 16 MHz
    		ret
    ;================================
    
    ;================================
    Send2nibbles:
    		push R17
    		push R19
    		ldi R17,0x00
    		cbi PORTB,E
    		cbi PORTB,DB4
    		cbi PORTB,DB5
    		cbi PORTB,DB6
    		cbi PORTA,DB7
    		bst R16,7
    		bld R17,0
    		ldi R19,0x00
    		in R19,PORTA
    		or R17,R19
    		out PORTA,R17
    		ldi R17,0x00
    		bst R16,6
    		bld R17,0
    		bst R16,5
    		bld R17,1
    		bst R16,4
    		bld R17,2
    		ldi R19,0x00
    		in R19,PORTB				
    		or R17,R19
    		out PORTB,R17
    		sbi PORTB,E
    		ldi R18,0x03
    		call Pauza
    		cbi PORTB,E
    
    		cbi PORTB,DB4
    		cbi PORTB,DB5
    		cbi PORTB,DB6
    		cbi PORTA,DB7
    
    		bst R16,3
    		bld R17,0
    		ldi R19,0x00
    		in R19,PORTA
    		or R17,R19
    		out PORTA,R17
    		ldi R17,0x00
    		bst R16,2
    		bld R17,0
    		bst R16,1
    		bld R17,1
    		bst R16,0
    		bld R17,2
    		ldi R19,0x00
    		in R19,PORTB
    		or R17,R19
    		out PORTB,R17
    		sbi PORTB,E
    		ldi R18,0x03
    		call Pauza
    		cbi PORTB,E
    		pop R19
    		pop R17
    		ret
    ;================================
    
    
    ;================================
    SendDrei:
    		push R18
    		cbi PORTB,DB6
    		cbi PORTA,DB7
    		sbi PORTB,DB4
    		sbi PORTB,DB5
    		sbi PORTB,E
    		ldi R18,0x03
    		call Pauza
    		cbi PORTB,E
    		pop R18
    		ret
    ;================================
    
    
    ;================================
    SendZwei:
    		push R18
    		cbi PORTB,DB6
    		cbi PORTA,DB7
    		cbi PORTB,DB4
    		sbi PORTB,DB5
    		sbi PORTB,E
    		ldi R18,0x03
    		call Pauza                    ;opoznienie jakies 200us
    		cbi PORTB,E
    		pop R18
    		ret
    ;================================
    
    ;================================
    DlugaPauza:
    		push R19
    		push R20
    		ldi R20,0x6E
    	Etap2:
    		ldi R19,0xFF
    	Etap1:
    		dec R19
    		brne Etap1
    		dec R20
    		brne Etap2
    		pop R20
    		pop R19
    		ret
    ;=================================
    
    ;=================================
    KrotkaPauza:
    		push R18
    		ldi R18,0xFF
    		call Pauza
    		ldi R18,0xFF
    		call Pauza
    		pop R18
    		ret
    ;=================================
    
    ;=================================
    Pauza:
    		nop
    		nop
    		nop
    		dec R18
    		brne Pauza
    		ret
    ;=================================
    
    
    

    Pozdrawiam :)
  • #3 2436776
    Konsul
    Poziom 23  
    Posty: 772
    Pomógł: 37
    Ocena: 20
    Dziwne bo z tego co przeczytalem w nocie wynikało, że trzeba przesłać co najmniej 5 czy nawet 6. Niestety pisze w c więc ten kod jest dla mnie tak średnio zrozumiały. To czego teraz potrzebuje to dobra nota katalogowa do tego LCD bo bez niej nie jestem w stanie nawet go podłączyć Niestety nie moge jej znaleźć :(.
  • #4 2437368
    M. S.
    Poziom 34  
    Posty: 2107
    Pomógł: 259
    Ocena: 680
    Może tu http://mikrokontrolery.net/index.htm znajdziesz odpowiedz. Jest tam program w "C" do sterowania LCD. 14 wyprowadzeń to standard (+2 podświetlenie). W tym programie 4 starsze bity wyświetlacza (11, 12, 13, 14-najstarszy) podłącza się do 4 starszych bitów wybranego portu. E(6) do bitu 3 i RS(4) do bitu 2. Pierwsze wyprowadzenie LCD - masa, drugie Vcc, trzecie kontrast - ok. 10k do Vcc i 470ohm do masy, piąte do masy.
    Inicjowanie wyświetlacza odbywa się za każdym uruchomieniem. Wg twojej teorii musiałby stale być podpięty do 8 bitów, a tak nie jest. Wygląda na to, że standardowo jest ustawiony na 4 bity.
  • #5 2450710
    Konsul
    Poziom 23  
    Posty: 772
    Pomógł: 37
    Ocena: 20
    Niestety nie moge odpalić tego wyswietlacza. WGrałem program ze strony mikrokontrolery i niestety wyświetlacz jest martwy. Połączenia sprawdzałem kilka razy. Jeśli uC jest nie podłączony to działa tylko podświetlanie. Po podłączeniu uC do wyświetlacza podświetlanie gaśnie. Wydaje mi się, że podczas programowania w pewnym momencie coś tam mignęło, wiec wyświetlacz jest w stanie coś wyświetlić. Powinien być dobry bo kupiłem nowy. Opis znalazłem co prawda nie do tego modelu ale tej samej firmy i z podobnymi wyprowadzeniami. Zresztą opis pinów w każdym jest taki sam. Zmienia się jedynie ich rozmieszczenie.
  • #6 2450910
    elektryk
    Poziom 42  
    Posty: 11029
    Pomógł: 439
    Ocena: 240
    Konsul napisał:
    Myślałem, że tryb 4bit jest dla oszczędzenia wyprowadzeń w uC ale żeby go włączyć musze chyba działać w trybie 8bitowym bo jak mam wysłać do LCD informacje o trybie 4bit przesyłając dane 2x4bit skoro jestem jeszcze w trybie 8bi :).
    Bo służy do oszczędzania pinów ;) Jak popatrzysz na rozkaz przełączający w tryb 4bitowy to jego młodsze 4 bity (te które są niepodłaczone) nie są istotne dla przełączenia w sam tryb, więc wyświetlacz można przełączyć w tryb 4 bitowy, a potem już tylko w tym trybie operować. Do tego wydaje mi się że układ HD44870 ma jakieś rezystory polaryzujące na wyjściach, więc piny niepodłączone mają jakiś wybrany stan logiczny (nie pamiętam czy 1 czy 0).
  • #7 2467004
    Konsul
    Poziom 23  
    Posty: 772
    Pomógł: 37
    Ocena: 20
    Kurcze męcze się z tym wyświetlaczem i nic :(. Podłączałem go już pod port B i D i zero reakcji. Jedynie przy odłączaniu go gdy zasilanie jest włączone zapalają się jakieś pola na nim, więc kontrast itp jest dobrze ustawiony ale zero komunikacji. Może podrzucicie mi jakiegoś gotowego hexa, który na pewno działa. Coś mi sie zdaje, że wyświetlacz jest niesprawny ale w sumie nowy kupilem.
  • #8 2467874
    maly35
    Poziom 14  
    Posty: 91
    Pomógł: 6
    Ocena: 2
    Oto moj kod wyswietlacz sterowanego 4-bitowo. Atmega16 taktowana 16MHz zewnętrzny oscylator. LCD podpięty pod port D (PD1...PD6). Jest tam też trochę niepotrzebnych funkcji ale nie przejmuj się (skompiluj, zgraj, odpal). Na LCD powinno się wyświetlić button1. U mnie działa na 100%


    #define F_CPU 16000000
    #include <avr/io.h>
    #include <stdlib.h>
    #include <avr/interrupt.h>
    #include <avr/signal.h>
    #include <avr/pgmspace.h>
    
    #define DDR_DB4 DDRD
    #define PORT_DB4 PORTD
    #define DB4 PD3
    
    #define DDR_DB5 DDRD
    #define PORT_DB5 PORTD
    #define DB5 PD4
    
    #define DDR_DB6 DDRD
    #define PORT_DB6 PORTD
    #define DB6 PD5
    
    #define DDR_DB7 DDRD
    #define PORT_DB7 PORTD
    #define DB7 PD6
    
    
    #define DDR_RS DDRD
    #define PORT_RS PORTD
    #define RS PD1
    
    #define DDR_E DDRD
    #define PORT_E PORTD
    #define E PD2
    
    #define DDR_B1 DDRC
    #define PORT_B1 PORTC
    #define B1 PC0
    
    #define DDR_B2 DDRC
    #define PORT_B2 PORTC
    #define B2 PC1
    
    #define DDR_B3 DDRC
    #define PORT_B3 PORTC
    #define B3 PC2
    
    #define DDR_B4 DDRC
    #define PORT_B4 PORTC
    #define B4 PC3
    
    #define SET_B1 PORT_B1 |= _BV(B1)
    #define CLR_B1 PORT_B1 &= ~_BV(B1)
    
    #define SET_B2 PORT_B2 |= _BV(B2)
    #define CLR_B2 PORT_B2 &= ~_BV(B2)
    
    #define SET_B3 PORT_B3 |= _BV(B3)
    #define CLR_B3 PORT_B3 &= ~_BV(B3)
    
    #define SET_B4 PORT_B4 |= _BV(B4)
    #define CLR_B4 PORT_B4 &= ~_BV(B4)
    
    #define SET_DB4 PORT_DB4 |= _BV(DB4)
    #define CLR_DB4 PORT_DB4 &= ~_BV(DB4)
    
    #define SET_DB5 PORT_DB5 |= _BV(DB5)
    #define CLR_DB5 PORT_DB5 &= ~_BV(DB5)
    
    #define SET_DB6 PORT_DB6 |= _BV(DB6)
    #define CLR_DB6 PORT_DB6 &= ~_BV(DB6)
    
    #define SET_DB7 PORT_DB7 |= _BV(DB7)
    #define CLR_DB7 PORT_DB7 &= ~_BV(DB7)
    
    #define SET_E PORT_E |= _BV(E)
    #define CLR_E PORT_E &= ~_BV(E)
    
    #define SET_RS PORT_RS |= _BV(RS)
    #define CLR_RS PORT_RS &= ~_BV(RS)
    
    #define LCD_X 16
    #define LCD_Y 2
    
    #define nap "button1"
    #define nap1 "button2"
    #define pusto "Wcisnij przycisk"
    
    char P1, P2, stan;
    
    void _delay_loop_2(uint16_t __count)
    {
    __asm__ volatile (
    "1: sbiw %0,1" "\n\t"
    "brne 1b"
    : "=w" (__count)
    : "0" (__count)
    );
    }
    
    
    static __inline__ void
    _delay_ms(double __ms)
    {
    uint16_t __ticks;
    double __tmp = ((F_CPU) / 4e3) * __ms;
    if (__tmp < 1.0)
    __ticks = 1;
    else if (__tmp > 65535)
    __ticks = 0;
    else
    __ticks = (uint16_t)__tmp;
    _delay_loop_2(__ticks);
    }
    
    
    
    
    void out_nibble(char x)
    {
    CLR_DB4;
    CLR_DB5;
    CLR_DB6;
    CLR_DB7;
    if(x & _BV(0)) SET_DB4;
    if(x & _BV(1)) SET_DB5;
    if(x & _BV(2)) SET_DB6;
    if(x & _BV(3)) SET_DB7;
    }
    
    
    void write_to_lcd(char x)
    {
    SET_E;
    out_nibble(x >> 4);
    CLR_E;
    SET_E;
    out_nibble(x);
    CLR_E;
    _delay_ms(1);
    }
    
    void write_command(char x)
    {
    CLR_RS;
    write_to_lcd(x);
    }
    
    void write_char(char x)
    {
    SET_RS;
    write_to_lcd(x);
    }
    
    void write_text(char * s)
    {
    while(*s)
    {
    write_char(*s);
    s++;
    }
    }
    
    void lcd_init(void)
    {
    DDR_DB4 |= _BV(DB4);
    DDR_DB5 |= _BV(DB5);
    DDR_DB6 |= _BV(DB6);
    DDR_DB7 |= _BV(DB7);
    DDR_E |= _BV(E);
    DDR_RS |= _BV(RS);
    
    _delay_ms(15);
    CLR_E;
    CLR_RS;
    char i;
    for(i = 0; i < 3; i++)
    {
    SET_E;
    out_nibble(0x03);
    CLR_E;
    _delay_ms(5);
    }
    SET_E;
    out_nibble(0x02);
    CLR_E;
    _delay_ms(1);
    write_command(0x28); // interfejs 4-bity, 2-linie, znak 5x7
    write_command(0x08); // wyłącz LCD, kursor i miganie
    write_command(0x01); // czyść LCD
    write_command(0x06); // bez przesuwania w prawo
    write_command(0x0C); // włącz LCD, bez kursora i mrugania
    }
    
    
    void LCD_xy(uint8_t x, uint8_t y)
    {
    switch(y)
    {
    case 1: y=0x40; break;
    case 2: y=0x14; break;
    }
    write_command(0x80+y+x);
    }
    
    void LCD_clr(void)
    {
    write_command(0x01);
    _delay_ms(1);
    LCD_xy(0,0);
    } 
    
    void Button_konf(void)
    {
    
       DDRC|=((1<<PC1)|(1<<PC2));
       PORTC|=((1<<PC1)|(1<<PC2));
    }
    
    void czytaj_we (void)                 
    {
       if(bit_is_clear(PINC,0)) 
       {
       P1=1;
       P2=0;
       }else P1=0;
       if(bit_is_clear(PINC,0)) 
       {
       P2=1;
       P1=0;
       }else P2=0;
    } 
    
    void odczyt_klaw(void)
    {
    	Button_konf();
    	stan=1;
    	P1=0;
    	P2=0;
    	while(1)
    	{
    		czytaj_we();
    		if (P1==1) write_text(nap);
    		else write_text(pusto);
    		if (P2==1) write_text(nap1);
    		else write_text(pusto);
    	}
    
    
    }
    
    main(void)
    {
    	lcd_init();
    	write_text(nap);
    	
    	
    	
    }
    


    Jeżeli nie działa to albo masz źle podłączony LCD albo programator jest padnięty.
  • #9 2476415
    elav
    Poziom 11  
    Posty: 25
    Pomógł: 1
    Oto dokumentacja LCD SSC2M16ULGY-03 wszystko pasuje pomimo troche innego modelu (na Taiwanie tak mają).
    Życzę powodzenia. Jak zadziała to zamieść kod.
    Załączniki:
    • LMC-SSC2A16-03.pdf (360.21 KB) Musisz być zalogowany, aby pobrać ten załącznik.
  • #10 2479071
    Konsul
    Poziom 23  
    Posty: 772
    Pomógł: 37
    Ocena: 20
    Mam tą dokumentacje. Niestety niewiele mi ona pomogła bo w zasadzie jest ona standardowa tak jak w innych wyświetlaczach. Mój niestety dalej nie działa. Pewnie jest jednak uszkodzony.
  • #11 4901113
    jankocyk21
    Poziom 10  
    Posty: 17
    witam, a ja mam troszke inny problem, nie wiem gdzie podłaczyc dodatkowe nózki, vss, vdd, e, rs, r/w, v0

    Dodano po 1 [minuty]:

    witam, a ja mam troszke inny problem, nie wiem gdzie podłaczyc dodatkowe nózki, vss, vdd, e, rs, r/w, v0

Podsumowanie tematu

✨ Dyskusja dotyczy podłączenia i obsługi wyświetlacza LCD zgodnego ze standardem HD44780 w trybie 4-bitowym z mikrokontrolerem Atmega8. Użytkownik posiada wyświetlacz oznaczony SSCM16ULGY-03 2K04-50, jednak nie może znaleźć dedykowanej noty katalogowej opisującej wyprowadzenia. Wskazano, że standard HD44780 jest powszechny i wyprowadzenia są zwykle takie same, z 14 pinami (2x7) oraz dodatkowymi pinami do podświetlenia (anoda i katoda). Tryb 4-bitowy pozwala na oszczędność linii danych, przesyłając bajt w dwóch częściach po 4 bity, a przełączenie do tego trybu odbywa się poprzez wysłanie odpowiedniej komendy, która nie wymaga pełnych 8 linii danych. Podano przykładowy kod inicjalizacji i sterowania LCD w asemblerze oraz w języku C dla Atmegi16, z przypisaniem pinów portów mikrokontrolera do linii LCD. Użytkownik zgłasza problemy z działaniem wyświetlacza – brak reakcji na podłączenie, podświetlenie gaśnie po podłączeniu mikrokontrolera, co może wskazywać na uszkodzenie modułu. Zaproponowano poszukiwanie dokumentacji na stronach mikrokontrolery.net oraz udostępniono dokumentację podobnego modelu SSC2M16ULGY-03, która jest zgodna ze standardem HD44780. Wskazano również typowe podłączenie pinów: masa, Vcc, kontrast (V0) z potencjometrem, linie sterujące RS, E, R/W oraz linie danych DB4-DB7. Problemem pozostaje brak działania wyświetlacza mimo poprawnego podłączenia i stosowania standardowych procedur inicjalizacji i komunikacji w trybie 4-bitowym.
Wygenerowane przez model językowy.
REKLAMA