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

[Atmega48][C][AVR studio] problem z wyświetlaczem LCD

qscgu 28 Lip 2010 17:17 2862 17
REKLAMA
  • #1 8340164
    qscgu
    Poziom 34  
    Witam.

    Mój kod wzięty z tej strony:
    http://radzio.dxp.pl/hd44780/hd44780_avr_4-bit_norw_c.htm

    Połączenie jest identyczne jak na tamtym schemacie.

    Skonfigurowałem sobię atmegę tak:

    #define LCD_RS_DIR		DDRD
    #define LCD_RS_PORT 	PORTD
    #define LCD_RS			(1 << PD6)
    
    #define LCD_E_DIR		DDRD
    #define LCD_E_PORT		PORTD
    #define LCD_E			(1 << PD5)
    
    #define LCD_DB4_DIR		DDRD
    #define LCD_DB4_PORT	PORTD
    #define LCD_DB4			(1 << PD3)
    
    #define LCD_DB5_DIR		DDRD
    #define LCD_DB5_PORT	PORTD
    #define LCD_DB5			(1 << PD2)
    
    #define LCD_DB6_DIR		DDRD
    #define LCD_DB6_PORT	PORTD
    #define LCD_DB6			(1 << PD1)
    
    #define LCD_DB7_DIR		DDRD
    #define LCD_DB7_PORT	PORTD
    #define LCD_DB7			(1 << PD0)


    Odpowiedni procesor ustawiłem dlatego powinno się dobrze zadeklarować DDRD.

    mam podpięte od PD0 - PD3 szyna danych oraz PD5 do Enable i PD6 do RS. RW jest do masy.

    Po włączeniu zapala się prawa część wyświetlacza na czarno czyli kontrast ustawiony dobrze.

    Moj program testowy wygląda tak:

    #include <avr/io.h>
    //#include "def.h"
    //#include "D:\Archiwum\AVR\hd44780_4bit_norw\HD44780.h"
    #include "D:\Archiwum\AVR\hd44780_4bit_norw\HD44780.c"
    
    int main(void)
    { 
    	LCD_Initalize();
      	LCD_WriteText("Test");
      
        for(;;)
        {
    		
        }
        return(0);
    }
    


    Ale zamiast całego tekstu wyświetla się tylko 8 pierwszych liter.

    Używam zasilania od zasilacza komputerowego, przy procesorze mam 2 kondensatory 100nF dokładniej pomiedzy VCC a masą oraz pomiędzy AREF i masą.

    Co robię nie tak? Może mój program jest zły? Opóźnienia za małe?
    Atmega jest nowa, raz zaprogramowana więc nie sądzę żeby była walnięta.

    EDIT:

    Tutaj jeszcze funkcja init:

    void LCD_Initalize(void)
    {
    unsigned char i;
    LCD_DB4_DIR |= LCD_DB4; // Konfiguracja kierunku pracy wyprowadzeń
    LCD_DB5_DIR |= LCD_DB5; //
    LCD_DB6_DIR |= LCD_DB6; //
    LCD_DB7_DIR |= LCD_DB7; //
    LCD_E_DIR 	|= LCD_E;   //
    LCD_RS_DIR 	|= LCD_RS;  //
    _delay_ms(15); // oczekiwanie na ustalibizowanie się napiecia zasilajacego
    LCD_RS_PORT &= ~LCD_RS; // wyzerowanie linii RS
    LCD_E_PORT &= ~LCD_E;  // wyzerowanie linii E
    
    for(i = 0; i < 3; i++) // trzykrotne powtórzenie bloku instrukcji
      {
      LCD_E_PORT |= LCD_E; //  E = 1
      _LCD_OutNibble(0x03); // tryb 8-bitowy
      LCD_E_PORT &= ~LCD_E; // E = 0
      _delay_ms(5); // czekaj 5ms
      }
    
    LCD_E_PORT |= LCD_E; // E = 1
    _LCD_OutNibble(0x02); // tryb 4-bitowy
    LCD_E_PORT &= ~LCD_E; // E = 0
    
    _delay_ms(1); // czekaj 1ms 
    LCD_WriteCommand(HD44780_FUNCTION_SET | HD44780_FONT5x7 | HD44780_ONE_LINE | HD44780_4_BIT); // interfejs 4-bity, 2-linie, znak 5x7
    LCD_WriteCommand(HD44780_DISPLAY_ONOFF | HD44780_DISPLAY_OFF); // wyłączenie wyswietlacza
    LCD_WriteCommand(HD44780_CLEAR); // czyszczenie zawartosći pamieci DDRAM
    _delay_ms(2);
    LCD_WriteCommand(HD44780_ENTRY_MODE | HD44780_EM_SHIFT_CURSOR | HD44780_EM_INCREMENT);// inkrementaja adresu i przesuwanie kursora
    LCD_WriteCommand(HD44780_DISPLAY_ONOFF | HD44780_DISPLAY_ON | HD44780_CURSOR_OFF | HD44780_CURSOR_NOBLINK); // włącz LCD, bez kursora i mrugania
    }
  • REKLAMA
  • #2 8340230
    memek
    Poziom 17  
    Spróbuj wstawić opóźnienie przed i za inicjalizacją.
  • #3 8340385
    tadzik85
    Poziom 38  
    jaki to wyświetlacz ile linii i ile wierszy?
  • #4 8340429
    qscgu
    Poziom 34  
    BSC1A16DRY
    http://www.us-electronics.com/files/LCDs.pdf

    Wiem już chyba o co chodzi, ale nie wiem jak to naprawić.

    tutaj:
    http://www.edw.com.pl/pdf/k09/25_10.pdf

    Znalazłem informację:

    Cytat:
    Istnieją modele wyświetlaczy 1x16 znaków np. Hitachi typ
    LM020, w którym pomimo 1 linii wyświetlającej 16 znaków
    przyporządkowanie poszczególnych matryc na panelu LCD do
    adresów w DD RAM jest nieco inne:

    Dla tego modelu LCD podczas inicjalizacji powinna być wpi−
    sana instrukcja „Function set” z bitem N=1, czyli praca w try−
    bie 2−liniowym, inaczej aktywna będzie tylko połowa (8 znaków)
    wyświetlacza.


    I faktycznie dla tego wyświetlacza jest inaczej
    nie 01-10
    tylko
    80 81 82 83 84 85 86 87 C0 C1 C2 C3 C4 C5 C6 C7

    Tylko jak to teraz skonfigurować?
  • #5 8340491
    janbernat
    Poziom 38  
    
    LCD_WriteCommand(HD44780_FUNCTION_SET | HD44780_FONT5x7 | HD44780_ONE_LINE | HD44780_4_BIT); // interfejs 4-bity, 2-linie, znak 5x7 
    

    HD44780_ONE_LINE może zmień na HD44780_TWO_LINE
  • #6 8340499
    qscgu
    Poziom 34  
    Samo to nie działa bo na samym początku miałem ustawione HD44780_TWO_LINE
    i też nie działało. Dopiero potem zmieniłem na ONE LINE
  • REKLAMA
  • Pomocny post
    #7 8340540
    janbernat
    Poziom 38  
    W programie radzia jest tak:
    #define HD44780_FUNCTION_SET 0x20
    Ale na co tu zmienić- to już w dokumentacji wyświetlacza.
  • #8 8340555
    tadzik85
    Poziom 38  
    qscgu napisał:


    I faktycznie dla tego wyświetlacza jest inaczej
    nie 01-10
    tylko
    80 81 82 83 84 85 86 87 C0 C1 C2 C3 C4 C5 C6 C7

    Tylko jak to teraz skonfigurować?


    Albo wyświetlasz to w trybie 2 liniowym albo spora modyfikacja biblioteki cię czeka.
  • REKLAMA
  • #9 8340587
    qscgu
    Poziom 34  
    Panowie problem rozwiązany

    wystarczyło zacząć pisać w dolnej linijce

    
    	LCD_Initalize();
      	LCD_WriteText("  Pawel ");
    	_delay_ms(2);
      	LCD_GoTo(0,1);
    	_delay_ms(2);
    	LCD_WriteText("Test  ");
    


    Tylko nie podobają mi się te opóźnienia, da się coś z tym zrobić? Tzn nie testowałem jeszcze czy bez nich działa ale czy będzie czy raczej nie?
  • #10 8340664
    janbernat
    Poziom 38  
    Najpierw je zmniejsz do us a potem spróbuj bez.
    P.S.
    Od razu je wywal- u mnie chodzi bez.
    P.S.2
    Ale mam wersję ze sprawdzaniem zajętości wyświetlacza.
  • #11 8340826
    qscgu
    Poziom 34  
    Działa bez, sprawdziłem też sam, a ja mam wersję bez sprawdzania zajętości.
  • #12 8340961
    gaskoin
    Poziom 38  
    qscgu napisał:


    Moj program testowy wygląda tak:

    #include <avr/io.h>
    //#include "def.h"
    //#include "D:\Archiwum\AVR\hd44780_4bit_norw\HD44780.h"
    #include "D:\Archiwum\AVR\hd44780_4bit_norw\HD44780.c"
    
    int main(void)
    { 
    	LCD_Initalize();
      	LCD_WriteText("Test");
      
        for(;;)
        {
    		
        }
        return(0);
    }
    


    Ale zamiast całego tekstu wyświetla się tylko 8 pierwszych liter.



    8 pierwszych liter napisu "Test" ?? :D
  • REKLAMA
  • #13 8341046
    qscgu
    Poziom 34  
    Tam był inny napis ale nie kopiowałem już bo nic by to nie zmieniło.
  • #14 8341124
    gaskoin
    Poziom 38  
    jeżeli masz wyświetlacz 8x2 to nie ma się co dziwić. Jakbyś zerknął w dokumentację sterownika do wyświetlacza, to widać, że jest on przeznaczony dla wyświetlaczy do 40x4 (czy coś koło tego). W jednej linii adresy komórek sąsiednich są od siebie różne o 1. Dlatego wpisując tekst dłuższy niż 8 znaków, znaki te "wyświetlały się" poza obszarem twojego LCD w pierwszej linijce. Żeby przenieść napisy niżej trzeba to po prostu zrobić przez goto.

    Jakbyś napisał wcześniej dokładny tekst i napisał jaki masz wyświetlacz to by było nieco prościej Ci pomóc
  • #16 8341161
    qscgu
    Poziom 34  
    Nie zawsze tak jest, poczytaj pdfa którego wyżej zamieściłem.
  • #17 8341194
    gaskoin
    Poziom 38  
    
    L1 80 81 82 83 84 85 86 87 88 89 8A 8B 8C 8D 8E 8F
    L2 C0 C1 C2 C3 C4 C5 C6 C7 C8 C9 CA CB CC CD CE CF
    


    tu jest dokładnie tak jak powiedziałem, w drugim pdfie adresy są podobnie, druga linijka ma się nijak do pierwszej, więc chyba nie zrozumiałeś o co mi chodziło

    wpisując LCD_TEXT("to jest napis") zapisujesz go w pierwszej linii, w pamięci się mieści, na ekranie już nie bo masz tylko 8 znaków
  • #18 8341354
    qscgu
    Poziom 34  
    Nie, przeczytaj dobrze:

    Dla przykładu struktura pamięci 16−znakowego wyświetlacza
    (1x16) ma postać:
    
    01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16
    00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
    


    Co sugerowałoby że cała linijka jest po kolei, a nie tak że następne 8 znaków jest przesunięte o 0x40 w stosunku do pierwszych 8 znaków.
    tak sie składa że w funkcja goto wykonuje 0x80 | x+ y*0x40
    a więc gdy y = 1 to wychodzi 0x80 | 0x40 co daje nam 0xC0

    stąd się zorientowałem jak zapisać dalszą część.
REKLAMA