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

LCD w języku C na płytce tesowej Atmega8 v 1.1

yohi 30 Gru 2009 15:56 1986 5
  • #1 30 Gru 2009 15:56
    yohi
    Poziom 2  

    Witam serdecznie,

    Kupiłem ostatnio płytkę testową Atmega8 v 1.1 ze stronki http://nestor19.webd.pl/sklep/product_info.php?cPath=62&products_id=168
    Wszystkie programy które są dostarczane razem z nią są napisane w Bascomie. Ja chciałbym wyświetlić cokolwiek na wyświetlaczu LCD w języku c i jest problem.

    Czy posiada ktoś ktoś jakąś bibliotekę skonfigurowaną pod tą płytkę?

    Najlepiej Petera Fleury lub Radzia ze stronki http://radzio.dxp.pl/hd44780/
    Próbowałem konfigurować obydwie bez rezultatów.


    Porty wyswietlacza konfigurowane w Bascomie wyglądają tak:

    Config Lcd = 16 * 2
    Config Lcdpin = Pin , Db4 = Portd.5 , Db5 = Portd.6 , Db6 = Portd.7 , Db7 = Portd.4 , E = Portd.3 , Rs = Portd.2


    Dziękuję..

    0 5
  • Relpol
  • #2 30 Gru 2009 16:13
    mirekk36
    Poziom 42  

    yohi napisał:
    Ja chciałbym wyświetlić cokolwiek na wyświetlaczu LCD w języku c i jest problem...


    problemu by nie było gdybyś zaczął naukę programowania w jęzuku C (w potwierdzam że warto się go uczyć) od prostego migania diodą LED i po kolei ładnie uczył się tego języka - żeby po niedługim czasie samemu napisać sobie własną obsługę LCD czy UART itd

    zamiast próbować C od korzystania z jakichś tam pseudo bibliotek z netu.

    Dzięki takiemu podejściu - gwarantuję ci , że szybciej nauczysz się C dla procków ;)

    0
  • Relpol
  • #3 30 Gru 2009 16:57
    yohi
    Poziom 2  

    Właśnie moja nauka zatrzymała się na wyświetlaczu LCD. Mruganie diodami już za mną. Dlatego proszę o pomoc:)

    Skonfigurowałem dwie biblioteki. Dodałem jako załącznik. Jeśli ktoś może to bardzo proszę o sprawdzenie. Pierwsza to biblioteka ze strony http://radzio.dxp.pl/hd44780/hd44780_avr_4-bit_norw_c.htm

    Wygląda tak:




    Code:
    Pkik HD44780.h
    
    //-------------------------------------------------------------------------------------------------
    // Wyświetlacz alfanumeryczny ze sterownikiem HD44780
    // Sterowanie w trybie 4-bitowym bez odczytu flagi zajętości
    // z dowolnym przypisaniem sygnałów sterujących
    // Plik : HD44780.h
    // Mikrokontroler : Atmel AVR
    // Kompilator : avr-gcc
    // Autor : Radosław Kwiecień
    // Źródło : http://radzio.dxp.pl/hd44780/
    // Data : 24.03.2007
    //-------------------------------------------------------------------------------------------------

    #include <avr>
    #include <util>

    //-------------------------------------------------------------------------------------------------
    //
    // Konfiguracja sygnałów sterujących wyświetlaczem.
    // Można zmienić stosownie do potrzeb.
    //
    //-------------------------------------------------------------------------------------------------
    #define LCD_RS_DIR DDRD
    #define LCD_RS_PORT PORTD
    #define LCD_RS (1 << PD2)

    #define LCD_E_DIR DDRD
    #define LCD_E_PORT PORTD
    #define LCD_E (1 << PD3)

    #define LCD_DB4_DIR DDRD
    #define LCD_DB4_PORT PORTD
    #define LCD_DB4 (1 << PD5)

    #define LCD_DB5_DIR DDRD
    #define LCD_DB5_PORT PORTD
    #define LCD_DB5 (1 << PD6)

    #define LCD_DB6_DIR DDRD
    #define LCD_DB6_PORT PORTD
    #define LCD_DB6 (1 << PD7)

    #define LCD_DB7_DIR DDRD
    #define LCD_DB7_PORT PORTD
    #define LCD_DB7 (1 <<PD4>> 4);
    LCD_E_PORT &= ~LCD_E;
    LCD_E_PORT |= LCD_E;
    _LCD_OutNibble(dataToWrite);
    LCD_E_PORT &= ~LCD_E;
    _delay_us(50);
    }



    //-------------------------------------------------------------------------------------------------
    //
    // Funkcja zapisu rozkazu do wyświetlacza
    //
    //-------------------------------------------------------------------------------------------------
    void LCD_WriteCommand(unsigned char commandToWrite)
    {
    LCD_RS_PORT &= ~LCD_RS;
    _LCD_Write(commandToWrite);
    }
    //-------------------------------------------------------------------------------------------------
    //
    // Funkcja zapisu danych do pamięci wyświetlacza




    //
    //-------------------------------------------------------------------------------------------------
    void LCD_WriteData(unsigned char dataToWrite)
    {
    LCD_RS_PORT |= LCD_RS;
    _LCD_Write(dataToWrite);
    }
    //-------------------------------------------------------------------------------------------------
    //
    // Funkcja wyświetlenia napisu na wyswietlaczu.
    //
    //-------------------------------------------------------------------------------------------------
    void LCD_WriteText(char * text)
    {
    while(*text)
    LCD_WriteData(*text++);
    }
    //-------------------------------------------------------------------------------------------------
    //
    // Funkcja ustawienia współrzędnych ekranowych
    //
    //-------------------------------------------------------------------------------------------------
    void LCD_GoTo(unsigned char x, unsigned char y)
    {
    LCD_WriteCommand(HD44780_DDRAM_SET | (x + (0x40 * y)));
    }
    //-------------------------------------------------------------------------------------------------
    //
    // Funkcja czyszczenia ekranu wyświetlacza.
    //
    //-------------------------------------------------------------------------------------------------
    void LCD_Clear(void)
    {
    LCD_WriteCommand(HD44780_CLEAR);
    _delay_ms(2);
    }
    //-------------------------------------------------------------------------------------------------
    //
    // Funkcja przywrócenia początkowych współrzędnych wyświetlacza.
    //
    //-------------------------------------------------------------------------------------------------
    void LCD_Home(void)
    {
    LCD_WriteCommand(HD44780_HOME);
    _delay_ms(2);
    }
    //-------------------------------------------------------------------------------------------------
    //
    // Procedura inicjalizacji kontrolera HD44780.
    //
    //-------------------------------------------------------------------------------------------------
    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_TWO_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
    }

    //-------------------------------------------------------------------------------------------------
    //
    // Koniec pliku HD44780.c
    //
    //-------------------------------------------------------------------------------------------------
    int main(void) //Program główny
    {

    LCD_Initalize(); //Inicjalizacja wyświetlacza

    while (1)
    {
    LCD_GoTo(0,0);
    LCD_WriteText("Hello!"); //Wyświetlenie napisu
    }
    return (0); //Powrót do początku programu
    }


    W tym przykładzie u mnie wyświetlacz sie świeci i jest pusty, a powinien wyświetlić "Helo"


    ------------------------------------------------------------------------------------

    W drugim przykładzie starałem się skonfigurować bibliotekę Petera Fleury. W tym przykładzie wyświetlacz w ogóle nie reaguje.


    Code:

    #ifndef LCD_H
    #define LCD_H
    /*************************************************************************
    Title : C include file for the HD44780U LCD library (lcd.c)
    Author: Peter Fleury <pfleury> http://jump.to/fleury
    File: $Id: lcd.h,v 1.13.2.2 2006/01/30 19:51:33 peter Exp $
    Software: AVR-GCC 3.3
    Hardware: any AVR device, memory mapped mode only for AT90S4414/8515/Mega
    ***************************************************************************/

    /**
    @defgroup pfleury_lcd LCD library
    @code #include <lcd> @endcode

    @brief Basic routines for interfacing a HD44780U-based text LCD display

    Originally based on Volker Oth's LCD library,
    changed lcd_init(), added additional constants for lcd_command(),
    added 4-bit I/O mode, improved and optimized code.

    Library can be operated in memory mapped mode (LCD_IO_MODE=0) or in
    4-bit IO port mode (LCD_IO_MODE=1). 8-bit IO port mode not supported.

    Memory mapped mode compatible with Kanda STK200, but supports also
    generation of R/W signal through A8 address line.

    @author Peter Fleury pfleury(malpa)gmx.ch http://jump.to/fleury

    @see The chapter <a>Interfacing a HD44780 Based LCD to an AVR</a>
    on my home page.

    */

    /*@{*/

    #if (__GNUC__ * 100 + __GNUC_MINOR__) < 303
    #error "This library requires AVR-GCC 3.3 or later, update to newer AVR-GCC compiler !"
    #endif

    #include <inttypes>
    #include <avr>

    /**
    * @name Definitions for MCU Clock Frequency
    * Adapt the MCU clock frequency in Hz to your target.
    */
    #define XTAL 4000000 /**< clock frequency in Hz, used to calculate delay timer */


    /**
    * @name Definition for LCD controller type
    * Use 0 for HD44780 controller, change to 1 for displays with KS0073 controller.
    */
    #define LCD_CONTROLLER_KS0073 0 /**< Use 0 for HD44780 controller, 1 for KS0073 controller */

    /**
    * @name Definitions for Display Size
    * Change these definitions to adapt setting to your display
    */
    #define LCD_LINES 2 /**< number of visible lines of the display */
    #define LCD_DISP_LENGTH 16 /**< visibles characters per line of the display */
    #define LCD_LINE_LENGTH 0x40 /**< internal line length of the display */
    #define LCD_START_LINE1 0x00 /**< DDRAM address of first char of line 1 */
    #define LCD_START_LINE2 0x40 /**< DDRAM address of first char of line 2 */
    #define LCD_START_LINE3 0x14 /**< DDRAM address of first char of line 3 */
    #define LCD_START_LINE4 0x54 /**< DDRAM address of first char of line 4 */
    #define LCD_WRAP_LINES 0 /**< 0: no wrap, 1: wrap at end of visibile line */


    #define LCD_IO_MODE 1 /**< 0: memory mapped mode, 1: IO port mode */
    #if LCD_IO_MODE
    /**
    * @name Definitions for 4-bit IO mode
    * Change LCD_PORT if you want to use a different port for the LCD pins.
    *
    * The four LCD data lines and the three control lines RS, RW, E can be on the
    * same port or on different ports.
    * Change LCD_RS_PORT, LCD_RW_PORT, LCD_E_PORT if you want the control lines on
    * different ports.
    *
    * Normally the four data lines should be mapped to bit 0..3 on one port, but it
    * is possible to connect these data lines in different order or even on different
    * ports by adapting the LCD_DATAx_PORT and LCD_DATAx_PIN definitions.
    *
    */
    #define LCD_PORT PORTD /**< port for the LCD lines */
    #define LCD_DATA0_PORT LCD_PORT /**< port for 4bit data bit 0 */
    #define LCD_DATA1_PORT LCD_PORT /**< port for 4bit data bit 1 */
    #define LCD_DATA2_PORT LCD_PORT /**< port for 4bit data bit 2 */
    #define LCD_DATA3_PORT LCD_PORT /**< port for 4bit data bit 3 */
    #define LCD_DATA0_PIN 5 /**< pin for 4bit data bit 0 */
    #define LCD_DATA1_PIN 6 /**< pin for 4bit data bit 1 */
    #define LCD_DATA2_PIN 7 /**< pin for 4bit data bit 2 */
    #define LCD_DATA3_PIN 4 /**< pin for 4bit data bit 3 */
    #define LCD_RS_PORT LCD_PORT /**< port for RS line */
    #define LCD_RS_PIN 2 /**< pin for RS line */
    #define LCD_RW_PORT LCD_PORT /**< port for RW line */
    #define LCD_RW_PIN 0 /**< pin for RW line */
    #define LCD_E_PORT LCD_PORT /**< port for Enable line */
    #define LCD_E_PIN 3 /**<pin> cursor) ? */
    #define LCD_MOVE_RIGHT 2 /* DB2: move right (0-> left) ? */
    #define LCD_FUNCTION 5 /* DB5: function set */
    #define LCD_FUNCTION_8BIT 4 /* DB4: set 8BIT mode (0->4BIT mode) */
    #define LCD_FUNCTION_2LINES 3 /* DB3: two lines (0->one line) */
    #define LCD_FUNCTION_10DOTS 2 /* DB2: 5x10 font (0->5x7 font) */
    #define LCD_CGRAM 6 /* DB6: set CG RAM address */
    #define LCD_DDRAM 7 /* DB7: set DD RAM address */
    #define LCD_BUSY 7 /* DB7: LCD is busy */

    /* set entry mode: display shift on/off, dec/inc cursor move direction */
    #define LCD_ENTRY_DEC 0x04 /* display shift off, dec cursor move dir */
    #define LCD_ENTRY_DEC_SHIFT 0x05 /* display shift on, dec cursor move dir */
    #define LCD_ENTRY_INC_ 0x06 /* display shift off, inc cursor move dir */
    #define LCD_ENTRY_INC_SHIFT 0x07 /* display shift on, inc cursor move dir */

    /* display on/off, cursor on/off, blinking char at cursor position */
    #define LCD_DISP_OFF 0x08 /* display off */
    #define LCD_DISP_ON 0x0C /* display on, cursor off */
    #define LCD_DISP_ON_BLINK 0x0D /* display on, cursor off, blink char */
    #define LCD_DISP_ON_CURSOR 0x0E /* display on, cursor on */
    #define LCD_DISP_ON_CURSOR_BLINK 0x0F /* display on, cursor on, blink char */

    /* move cursor/shift display */
    #define LCD_MOVE_CURSOR_LEFT 0x10 /* move cursor left (decrement) */
    #define LCD_MOVE_CURSOR_RIGHT 0x14 /* move cursor right (increment) */
    #define LCD_MOVE_DISP_LEFT 0x18 /* shift display left */
    #define LCD_MOVE_DISP_RIGHT 0x1C /* shift display right */

    /* function set: set interface data length and number of display lines */
    #define LCD_FUNCTION_4BIT_1LINE 0x20 /* 4-bit interface, single line, 5x7 dots */
    #define LCD_FUNCTION_4BIT_2LINES 0x28 /* 4-bit interface, dual line, 5x7 dots */
    #define LCD_FUNCTION_8BIT_1LINE 0x30 /* 8-bit interface, single line, 5x7 dots */
    #define LCD_FUNCTION_8BIT_2LINES 0x38 /* 8-bit interface, dual line, 5x7 dots */


    #define LCD_MODE_DEFAULT ((1<<LCD_ENTRY_MODE) | (1<<LCD_ENTRY_INC) )



    /**
    * @name Functions
    */


    /**
    @brief Initialize display and select type of cursor
    @param dispAttr \b LCD_DISP_OFF display off\n
    \b LCD_DISP_ON display on, cursor off\n
    \b LCD_DISP_ON_CURSOR display on, cursor on\n
    \b LCD_DISP_ON_CURSOR_BLINK display on, cursor on flashing
    @return none
    */
    extern void lcd_init(uint8_t dispAttr);


    /**
    @brief Clear display and set cursor to home position
    @param void
    @return none
    */
    extern void lcd_clrscr(void);


    /**
    @brief Set cursor to home position
    @param void
    @return none
    */
    extern void lcd_home(void);


    /**
    @brief Set cursor to specified position

    @param x horizontal position\n (0: left most position)
    @param y vertical position\n (0: first line)
    @return none
    */
    extern void lcd_gotoxy(uint8_t x, uint8_t y);


    /**
    @brief Display character at current cursor position
    @param c character to be displayed
    @return none
    */
    extern void lcd_putc(char c);


    /**
    @brief Display string without auto linefeed
    @param s string to be displayed
    @return none
    */
    extern void lcd_puts(const char *s);


    /**
    @brief Display string from program memory without auto linefeed
    @param s string from program memory be be displayed
    @return none
    @see lcd_puts_P
    */
    extern void lcd_puts_p(const char *progmem_s);


    /**
    @brief Send LCD controller instruction command
    @param cmd instruction to send to LCD controller, see HD44780 data sheet
    @return none
    */
    extern void lcd_command(uint8_t cmd);


    /**
    @brief Send data byte to LCD controller

    Similar to lcd_putc(), but without interpreting LF
    @param data byte to send to LCD controller, see HD44780 data sheet
    @return none
    */
    extern void lcd_data(uint8_t data);


    /**
    @brief macros for automatically storing string constant in program memory
    */
    #define lcd_puts_P(__s) lcd_puts_p(PSTR(__s))

    /*@}*/
    #endif //LCD_H


    oraz plik główny


    /****************************************************************************
    Title : HD44780U LCD library
    Author: Peter Fleury <pfleury@gmx.ch> http://jump.to/fleury
    File: $Id: lcd.c,v 1.14.2.1 2006/01/29 12:16:41 peter Exp $
    Software: AVR-GCC 3.3
    Target: any AVR device, memory mapped mode only for AT90S4414/8515/Mega

    DESCRIPTION
    Basic routines for interfacing a HD44780U-based text lcd display

    Originally based on Volker Oth's lcd library,
    changed lcd_init(), added additional constants for lcd_command(),
    added 4-bit I/O mode, improved and optimized code.

    Library can be operated in memory mapped mode (LCD_IO_MODE=0) or in
    4-bit IO port mode (LCD_IO_MODE=1). 8-bit IO port mode not supported.

    Memory mapped mode compatible with Kanda STK200, but supports also
    generation of R/W signal through A8 address line.

    USAGE
    See the C include lcd.h file for a description of each function

    *****************************************************************************/
    #include <inttypes.h>
    #include <avr/io.h>
    #include <avr/pgmspace.h>
    #include "lcd.h"



    /*
    ** constants/macros
    */
    #define DDR(x) (*(&x - 1)) /* address of data direction register of port x */
    #if defined(__AVR_ATmega64__) || defined(__AVR_ATmega128__)
    /* on ATmega64/128 PINF is on port 0x00 and not 0x60 */
    #define PIN(x) ( &PORTF==&(x) ? _SFR_IO8(0x00) : (*(&x - 2)) )
    #else
    #define PIN(x) (*(&x - 2)) /* address of input register of port x */
    #endif


    #if LCD_IO_MODE
    #define lcd_e_delay() __asm__ __volatile__( "rjmp 1f\n 1:" );
    #define lcd_e_high() LCD_E_PORT |= _BV(LCD_E_PIN);
    #define lcd_e_low() LCD_E_PORT &= ~_BV(LCD_E_PIN);
    #define lcd_e_toggle() toggle_e()
    #define lcd_rw_high() LCD_RW_PORT |= _BV(LCD_RW_PIN)
    #define lcd_rw_low() LCD_RW_PORT &= ~_BV(LCD_RW_PIN)
    #define lcd_rs_high() LCD_RS_PORT |= _BV(LCD_RS_PIN)
    #define lcd_rs_low() LCD_RS_PORT &= ~_BV(LCD_RS_PIN)
    #endif

    #if LCD_IO_MODE
    #if LCD_LINES==1
    #define LCD_FUNCTION_DEFAULT LCD_FUNCTION_4BIT_1LINE
    #else
    #define LCD_FUNCTION_DEFAULT LCD_FUNCTION_4BIT_2LINES
    #endif
    #else
    #if LCD_LINES==1
    #define LCD_FUNCTION_DEFAULT LCD_FUNCTION_8BIT_1LINE
    #else
    #define LCD_FUNCTION_DEFAULT LCD_FUNCTION_8BIT_2LINES
    #endif
    #endif

    #if LCD_CONTROLLER_KS0073
    #if LCD_LINES==4

    #define KS0073_EXTENDED_FUNCTION_REGISTER_ON 0x24 /* |0|010|0100 4-bit mode extension-bit RE = 1 */
    #define KS0073_EXTENDED_FUNCTION_REGISTER_OFF 0x20 /* |0|000|1001 4 lines mode */
    #define KS0073_4LINES_MODE 0x09 /* |0|001|0000 4-bit mode, extension-bit RE = 0 */

    #endif
    #endif

    /*
    ** function prototypes
    */
    #if LCD_IO_MODE
    static void toggle_e(void);
    #endif

    /*
    ** local functions
    */



    /*************************************************************************
    delay loop for small accurate delays: 16-bit counter, 4 cycles/loop
    *************************************************************************/
    static inline void _delayFourCycles(unsigned int __count)
    {
    if ( __count == 0 )
    __asm__ __volatile__( "rjmp 1f\n 1:" ); // 2 cycles
    else
    __asm__ __volatile__ (
    "1: sbiw %0,1" "\n\t"
    "brne 1b" // 4 cycles/loop
    : "=w" (__count)
    : "0" (__count)
    );
    }


    /*************************************************************************
    delay for a minimum of <us> microseconds
    the number of loops is calculated at compile-time from MCU clock frequency
    *************************************************************************/
    #define delay(us) _delayFourCycles( ( ( 1*(XTAL/4000) )*us)/1000 )


    #if LCD_IO_MODE
    /* toggle Enable Pin to initiate write */
    static void toggle_e(void)
    {
    lcd_e_high();
    lcd_e_delay();
    lcd_e_low();
    }
    #endif


    /*************************************************************************
    Low-level function to write byte to LCD controller
    Input: data byte to write to LCD
    rs 1: write data
    0: write instruction
    Returns: none
    *************************************************************************/
    #if LCD_IO_MODE
    static void lcd_write(uint8_t data,uint8_t rs)
    {
    unsigned char dataBits ;


    if (rs) { /* write data (RS=1, RW=0) */
    lcd_rs_high();
    } else { /* write instruction (RS=0, RW=0) */
    lcd_rs_low();
    }
    lcd_rw_low();

    if ( ( &LCD_DATA0_PORT == &LCD_DATA1_PORT) && ( &LCD_DATA1_PORT == &LCD_DATA2_PORT ) && ( &LCD_DATA2_PORT == &LCD_DATA3_PORT )
    && (LCD_DATA0_PIN == 0) && (LCD_DATA1_PIN == 1) && (LCD_DATA2_PIN == 2) && (LCD_DATA3_PIN == 3) )
    {
    /* configure data pins as output */
    DDR(LCD_DATA0_PORT) |= 0x0F;

    /* output high nibble first */
    dataBits = LCD_DATA0_PORT & 0xF0;
    LCD_DATA0_PORT = dataBits |((data>>4)&0x0F);
    lcd_e_toggle();

    /* output low nibble */
    LCD_DATA0_PORT = dataBits | (data&0x0F);
    lcd_e_toggle();

    /* all data pins high (inactive) */
    LCD_DATA0_PORT = dataBits | 0x0F;
    }
    else
    {
    /* configure data pins as output */
    DDR(LCD_DATA0_PORT) |= _BV(LCD_DATA0_PIN);
    DDR(LCD_DATA1_PORT) |= _BV(LCD_DATA1_PIN);
    DDR(LCD_DATA2_PORT) |= _BV(LCD_DATA2_PIN);
    DDR(LCD_DATA3_PORT) |= _BV(LCD_DATA3_PIN);

    /* output high nibble first */
    LCD_DATA3_PORT &= ~_BV(LCD_DATA3_PIN);
    LCD_DATA2_PORT &= ~_BV(LCD_DATA2_PIN);
    LCD_DATA1_PORT &= ~_BV(LCD_DATA1_PIN);
    LCD_DATA0_PORT &= ~_BV(LCD_DATA0_PIN);
    if(data & 0x80) LCD_DATA3_PORT |= _BV(LCD_DATA3_PIN);
    if(data & 0x40) LCD_DATA2_PORT |= _BV(LCD_DATA2_PIN);
    if(data & 0x20) LCD_DATA1_PORT |= _BV(LCD_DATA1_PIN);
    if(data & 0x10) LCD_DATA0_PORT |= _BV(LCD_DATA0_PIN);
    lcd_e_toggle();

    /* output low nibble */
    LCD_DATA3_PORT &= ~_BV(LCD_DATA3_PIN);
    LCD_DATA2_PORT &= ~_BV(LCD_DATA2_PIN);
    LCD_DATA1_PORT &= ~_BV(LCD_DATA1_PIN);
    LCD_DATA0_PORT &= ~_BV(LCD_DATA0_PIN);
    if(data & 0x08) LCD_DATA3_PORT |= _BV(LCD_DATA3_PIN);
    if(data & 0x04) LCD_DATA2_PORT |= _BV(LCD_DATA2_PIN);
    if(data & 0x02) LCD_DATA1_PORT |= _BV(LCD_DATA1_PIN);
    if(data & 0x01) LCD_DATA0_PORT |= _BV(LCD_DATA0_PIN);
    lcd_e_toggle();

    /* all data pins high (inactive) */
    LCD_DATA0_PORT |= _BV(LCD_DATA0_PIN);
    LCD_DATA1_PORT |= _BV(LCD_DATA1_PIN);
    LCD_DATA2_PORT |= _BV(LCD_DATA2_PIN);
    LCD_DATA3_PORT |= _BV(LCD_DATA3_PIN);
    }
    }
    #else
    #define lcd_write(d,rs) if (rs) *(volatile uint8_t*)(LCD_IO_DATA) = d; else *(volatile uint8_t*)(LCD_IO_FUNCTION) = d;
    /* rs==0 -> write instruction to LCD_IO_FUNCTION */
    /* rs==1 -> write data to LCD_IO_DATA */
    #endif


    /*************************************************************************
    Low-level function to read byte from LCD controller
    Input: rs 1: read data
    0: read busy flag / address counter
    Returns: byte read from LCD controller
    *************************************************************************/
    #if LCD_IO_MODE
    static uint8_t lcd_read(uint8_t rs)
    {
    uint8_t data;


    if (rs)
    lcd_rs_high(); /* RS=1: read data */
    else
    lcd_rs_low(); /* RS=0: read busy flag */
    lcd_rw_high(); /* RW=1 read mode */

    if ( ( &LCD_DATA0_PORT == &LCD_DATA1_PORT) && ( &LCD_DATA1_PORT == &LCD_DATA2_PORT ) && ( &LCD_DATA2_PORT == &LCD_DATA3_PORT )
    && ( LCD_DATA0_PIN == 0 )&& (LCD_DATA1_PIN == 1) && (LCD_DATA2_PIN == 2) && (LCD_DATA3_PIN == 3) )
    {
    DDR(LCD_DATA0_PORT) &= 0xF0; /* configure data pins as input */

    lcd_e_high();
    lcd_e_delay();
    data = PIN(LCD_DATA0_PORT) << 4; /* read high nibble first */
    lcd_e_low();

    lcd_e_delay(); /* Enable 500ns low */

    lcd_e_high();
    lcd_e_delay();
    data |= PIN(LCD_DATA0_PORT)&0x0F; /* read low nibble */
    lcd_e_low();
    }
    else
    {
    /* configure data pins as input */
    DDR(LCD_DATA0_PORT) &= ~_BV(LCD_DATA0_PIN);
    DDR(LCD_DATA1_PORT) &= ~_BV(LCD_DATA1_PIN);
    DDR(LCD_DATA2_PORT) &= ~_BV(LCD_DATA2_PIN);
    DDR(LCD_DATA3_PORT) &= ~_BV(LCD_DATA3_PIN);

    /* read high nibble first */
    lcd_e_high();
    lcd_e_delay();
    data = 0;
    if ( PIN(LCD_DATA0_PORT) & _BV(LCD_DATA0_PIN) ) data |= 0x10;
    if ( PIN(LCD_DATA1_PORT) & _BV(LCD_DATA1_PIN) ) data |= 0x20;
    if ( PIN(LCD_DATA2_PORT) & _BV(LCD_DATA2_PIN) ) data |= 0x40;
    if ( PIN(LCD_DATA3_PORT) & _BV(LCD_DATA3_PIN) ) data |= 0x80;
    lcd_e_low();

    lcd_e_delay(); /* Enable 500ns low */

    /* read low nibble */
    lcd_e_high();
    lcd_e_delay();
    if ( PIN(LCD_DATA0_PORT) & _BV(LCD_DATA0_PIN) ) data |= 0x01;
    if ( PIN(LCD_DATA1_PORT) & _BV(LCD_DATA1_PIN) ) data |= 0x02;
    if ( PIN(LCD_DATA2_PORT) & _BV(LCD_DATA2_PIN) ) data |= 0x04;
    if ( PIN(LCD_DATA3_PORT) & _BV(LCD_DATA3_PIN) ) data |= 0x08;
    lcd_e_low();
    }
    return data;
    }
    #else
    #define lcd_read(rs) (rs) ? *(volatile uint8_t*)(LCD_IO_DATA+LCD_IO_READ) : *(volatile uint8_t*)(LCD_IO_FUNCTION+LCD_IO_READ)
    /* rs==0 -> read instruction from LCD_IO_FUNCTION */
    /* rs==1 -> read data from LCD_IO_DATA */
    #endif


    /*************************************************************************
    loops while lcd is busy, returns address counter
    *************************************************************************/
    static uint8_t lcd_waitbusy(void)

    {
    register uint8_t c;

    /* wait until busy flag is cleared */
    while ( (c=lcd_read(0)) & (1<<LCD_BUSY)) {}

    /* the address counter is updated 4us after the busy flag is cleared */
    delay(2);

    /* now read the address counter */
    return (lcd_read(0)); // return address counter

    }/* lcd_waitbusy */


    /*************************************************************************
    Move cursor to the start of next line or to the first line if the cursor
    is already on the last line.
    *************************************************************************/
    static inline void lcd_newline(uint8_t pos)
    {
    register uint8_t addressCounter;


    #if LCD_LINES==1
    addressCounter = 0;
    #endif
    #if LCD_LINES==2
    if ( pos < (LCD_START_LINE2) )
    addressCounter = LCD_START_LINE2;
    else
    addressCounter = LCD_START_LINE1;
    #endif
    #if LCD_LINES==4
    #if KS0073_4LINES_MODE
    if ( pos < LCD_START_LINE2 )
    addressCounter = LCD_START_LINE2;
    else if ( (pos >= LCD_START_LINE2) && (pos < LCD_START_LINE3) )
    addressCounter = LCD_START_LINE3;
    else if ( (pos >= LCD_START_LINE3) && (pos < LCD_START_LINE4) )
    addressCounter = LCD_START_LINE4;
    else
    addressCounter = LCD_START_LINE1;
    #else
    if ( pos < LCD_START_LINE3 )
    addressCounter = LCD_START_LINE2;
    else if ( (pos >= LCD_START_LINE2) && (pos < LCD_START_LINE4) )
    addressCounter = LCD_START_LINE3;
    else if ( (pos >= LCD_START_LINE3) && (pos < LCD_START_LINE2) )
    addressCounter = LCD_START_LINE4;
    else
    addressCounter = LCD_START_LINE1;
    #endif
    #endif
    lcd_command((1<<LCD_DDRAM)+addressCounter);

    }/* lcd_newline */


    /*
    ** PUBLIC FUNCTIONS
    */

    /*************************************************************************
    Send LCD controller instruction command
    Input: instruction to send to LCD controller, see HD44780 data sheet
    Returns: none
    *************************************************************************/
    void lcd_command(uint8_t cmd)
    {
    lcd_waitbusy();
    lcd_write(cmd,0);
    }


    /*************************************************************************
    Send data byte to LCD controller
    Input: data to send to LCD controller, see HD44780 data sheet
    Returns: none
    *************************************************************************/
    void lcd_data(uint8_t data)
    {
    lcd_waitbusy();
    lcd_write(data,1);
    }



    /*************************************************************************
    Set cursor to specified position
    Input: x horizontal position (0: left most position)
    y vertical position (0: first line)
    Returns: none
    *************************************************************************/
    void lcd_gotoxy(uint8_t x, uint8_t y)
    {
    #if LCD_LINES==1
    lcd_command((1<<LCD_DDRAM)+LCD_START_LINE1+x);
    #endif
    #if LCD_LINES==2
    if ( y==0 )
    lcd_command((1<<LCD_DDRAM)+LCD_START_LINE1+x);
    else
    lcd_command((1<<LCD_DDRAM)+LCD_START_LINE2+x);
    #endif
    #if LCD_LINES==4
    if ( y==0 )
    lcd_command((1<<LCD_DDRAM)+LCD_START_LINE1+x);
    else if ( y==1)
    lcd_command((1<<LCD_DDRAM)+LCD_START_LINE2+x);
    else if ( y==2)
    lcd_command((1<<LCD_DDRAM)+LCD_START_LINE3+x);
    else /* y==3 */
    lcd_command((1<<LCD_DDRAM)+LCD_START_LINE4+x);
    #endif

    }/* lcd_gotoxy */


    /*************************************************************************
    *************************************************************************/
    int lcd_getxy(void)
    {
    return lcd_waitbusy();
    }


    /*************************************************************************
    Clear display and set cursor to home position
    *************************************************************************/
    void lcd_clrscr(void)
    {
    lcd_command(1<<LCD_CLR);
    }


    /*************************************************************************
    Set cursor to home position
    *************************************************************************/
    void lcd_home(void)
    {
    lcd_command(1<<LCD_HOME);
    }


    /*************************************************************************
    Display character at current cursor position
    Input: character to be displayed
    Returns: none
    *************************************************************************/
    void lcd_putc(char c)
    {
    uint8_t pos;


    pos = lcd_waitbusy(); // read busy-flag and address counter
    if (c=='\n')
    {
    lcd_newline(pos);
    }
    else
    {
    #if LCD_WRAP_LINES==1
    #if LCD_LINES==1
    if ( pos == LCD_START_LINE1+LCD_DISP_LENGTH ) {
    lcd_write((1<<LCD_DDRAM)+LCD_START_LINE1,0);
    }
    #elif LCD_LINES==2
    if ( pos == LCD_START_LINE1+LCD_DISP_LENGTH ) {
    lcd_write((1<<LCD_DDRAM)+LCD_START_LINE2,0);
    }else if ( pos == LCD_START_LINE2+LCD_DISP_LENGTH ){
    lcd_write((1<<LCD_DDRAM)+LCD_START_LINE1,0);
    }
    #elif LCD_LINES==4
    if ( pos == LCD_START_LINE1+LCD_DISP_LENGTH ) {
    lcd_write((1<<LCD_DDRAM)+LCD_START_LINE2,0);
    }else if ( pos == LCD_START_LINE2+LCD_DISP_LENGTH ) {
    lcd_write((1<<LCD_DDRAM)+LCD_START_LINE3,0);
    }else if ( pos == LCD_START_LINE3+LCD_DISP_LENGTH ) {
    lcd_write((1<<LCD_DDRAM)+LCD_START_LINE4,0);
    }else if ( pos == LCD_START_LINE4+LCD_DISP_LENGTH ) {
    lcd_write((1<<LCD_DDRAM)+LCD_START_LINE1,0);
    }
    #endif
    lcd_waitbusy();
    #endif
    lcd_write(c, 1);
    }

    }/* lcd_putc */


    /*************************************************************************
    Display string without auto linefeed
    Input: string to be displayed
    Returns: none
    *************************************************************************/
    void lcd_puts(const char *s)
    /* print string on lcd (no auto linefeed) */
    {
    register char c;

    while ( (c = *s++) ) {
    lcd_putc(c);
    }

    }/* lcd_puts */


    /*************************************************************************
    Display string from program memory without auto linefeed
    Input: string from program memory be be displayed
    Returns: none
    *************************************************************************/
    void lcd_puts_p(const char *progmem_s)
    /* print string from program memory on lcd (no auto linefeed) */
    {
    register char c;

    while ( (c = pgm_read_byte(progmem_s++)) ) {
    lcd_putc(c);
    }

    }/* lcd_puts_p */


    /*************************************************************************
    Initialize display and select type of cursor
    Input: dispAttr LCD_DISP_OFF display off
    LCD_DISP_ON display on, cursor off
    LCD_DISP_ON_CURSOR display on, cursor on
    LCD_DISP_CURSOR_BLINK display on, cursor on flashing
    Returns: none
    *************************************************************************/
    void lcd_init(uint8_t dispAttr)
    {
    #if LCD_IO_MODE
    /*
    * Initialize LCD to 4 bit I/O mode
    */

    if ( ( &LCD_DATA0_PORT == &LCD_DATA1_PORT) && ( &LCD_DATA1_PORT == &LCD_DATA2_PORT ) && ( &LCD_DATA2_PORT == &LCD_DATA3_PORT )
    && ( &LCD_RS_PORT == &LCD_DATA0_PORT) && ( &LCD_RW_PORT == &LCD_DATA0_PORT) && (&LCD_E_PORT == &LCD_DATA0_PORT)
    && (LCD_DATA0_PIN == 0 ) && (LCD_DATA1_PIN == 1) && (LCD_DATA2_PIN == 2) && (LCD_DATA3_PIN == 3)
    && (LCD_RS_PIN == 4 ) && (LCD_RW_PIN == 5) && (LCD_E_PIN == 6 ) )
    {
    /* configure all port bits as output (all LCD lines on same port) */
    DDR(LCD_DATA0_PORT) |= 0x7F;
    }
    else if ( ( &LCD_DATA0_PORT == &LCD_DATA1_PORT) && ( &LCD_DATA1_PORT == &LCD_DATA2_PORT ) && ( &LCD_DATA2_PORT == &LCD_DATA3_PORT )
    && (LCD_DATA0_PIN == 0 ) && (LCD_DATA1_PIN == 1) && (LCD_DATA2_PIN == 2) && (LCD_DATA3_PIN == 3) )
    {
    /* configure all port bits as output (all LCD data lines on same port, but control lines on different ports) */
    DDR(LCD_DATA0_PORT) |= 0x0F;
    DDR(LCD_RS_PORT) |= _BV(LCD_RS_PIN);
    DDR(LCD_RW_PORT) |= _BV(LCD_RW_PIN);
    DDR(LCD_E_PORT) |= _BV(LCD_E_PIN);
    }
    else
    {
    /* configure all port bits as output (LCD data and control lines on different ports */
    DDR(LCD_RS_PORT) |= _BV(LCD_RS_PIN);
    DDR(LCD_RW_PORT) |= _BV(LCD_RW_PIN);
    DDR(LCD_E_PORT) |= _BV(LCD_E_PIN);
    DDR(LCD_DATA0_PORT) |= _BV(LCD_DATA0_PIN);
    DDR(LCD_DATA1_PORT) |= _BV(LCD_DATA1_PIN);
    DDR(LCD_DATA2_PORT) |= _BV(LCD_DATA2_PIN);
    DDR(LCD_DATA3_PORT) |= _BV(LCD_DATA3_PIN);
    }
    delay(16000); /* wait 16ms or more after power-on */

    /* initial write to lcd is 8bit */
    LCD_DATA1_PORT |= _BV(LCD_DATA1_PIN); // _BV(LCD_FUNCTION)>>4;
    LCD_DATA0_PORT |= _BV(LCD_DATA0_PIN); // _BV(LCD_FUNCTION_8BIT)>>4;
    lcd_e_toggle();
    delay(4992); /* delay, busy flag can't be checked here */

    /* repeat last command */
    lcd_e_toggle();
    delay(64); /* delay, busy flag can't be checked here */

    /* repeat last command a third time */
    lcd_e_toggle();
    delay(64); /* delay, busy flag can't be checked here */

    /* now configure for 4bit mode */
    LCD_DATA0_PORT &= ~_BV(LCD_DATA0_PIN); // LCD_FUNCTION_4BIT_1LINE>>4
    lcd_e_toggle();
    delay(64); /* some displays need this additional delay */

    /* from now the LCD only accepts 4 bit I/O, we can use lcd_command() */
    #else
    /*
    * Initialize LCD to 8 bit memory mapped mode
    */

    /* enable external SRAM (memory mapped lcd) and one wait state */
    MCUCR = _BV(SRE) | _BV(SRW);

    /* reset LCD */
    delay(16000); /* wait 16ms after power-on */
    lcd_write(LCD_FUNCTION_8BIT_1LINE,0); /* function set: 8bit interface */
    delay(4992); /* wait 5ms */
    lcd_write(LCD_FUNCTION_8BIT_1LINE,0); /* function set: 8bit interface */
    delay(64); /* wait 64us */
    lcd_write(LCD_FUNCTION_8BIT_1LINE,0); /* function set: 8bit interface */
    delay(64); /* wait 64us */
    #endif

    #if KS0073_4LINES_MODE
    /* Display with KS0073 controller requires special commands for enabling 4 line mode */
    lcd_command(KS0073_EXTENDED_FUNCTION_REGISTER_ON);
    lcd_command(KS0073_4LINES_MODE);
    lcd_command(KS0073_EXTENDED_FUNCTION_REGISTER_OFF);
    #else
    lcd_command(LCD_FUNCTION_DEFAULT); /* function set: display lines */
    #endif
    lcd_command(LCD_DISP_OFF); /* display off */
    lcd_clrscr(); /* display clear */
    lcd_command(LCD_MODE_DEFAULT); /* set entry mode */
    lcd_command(dispAttr); /* display/cursor control */

    }/* lcd_init */
    void main(){
    lcd_init ;
    lcd_clrscr;
    while(1){
    lcd_gotoxy(0,0);
    lcd_putc("a");
    }
    }

    0
  • #4 30 Gru 2009 17:18
    Samuraj
    Poziom 35  

    Nauka C nie polega na kopiowaniu długaśnych bibliotek z sieci. Sprawdzałeś w jaki one sposób działają i czym się różnią.
    Wiesz w jaki sposób i na jakich pinach masz podpięty wyświetlacz do mikrokontorlera.
    Wiesz czy i na jakim kwarcu on pracuje ?
    Bez odpowiedzi na te pytania nie starczy Ci życia na kopiowaniu bibliotek z internetu.

    0
  • #5 30 Gru 2009 17:26
    mirekk36
    Poziom 42  

    Samuraj napisał:
    Nauka C nie polega na kopiowaniu długaśnych bibliotek z sieci. Sprawdzałeś w jaki one sposób działają i czym się różnią.
    Wiesz w jaki sposób i na jakich pinach masz podpięty wyświetlacz do mikrokontorlera.
    Wiesz czy i na jakim kwarcu on pracuje ?
    Bez odpowiedzi na te pytania nie starczy Ci życia na kopiowaniu bibliotek z internetu.


    hyhyhy święta racja !

    a ja dodam tylko, że nie znajdziesz nikogo na elektrodzie czy w necie, kto się weźmie za twoje mega listingi i będzie zgadywał dlaczego one akurat u ciebie nie działają - i nie dlatego że ktoś nie chce czy że jest nieuprzejmy a dlatego tylko, że to nie ma najmniejszego sensu. I zamiast zaprzać się że już znasz C skoro nauczyłeś się migać diodą LED - to poczytaj sobie o operatorach, wskaźnikach, strukturach, uniach - naucz się tego wszystkiego używać w praktyce i to przy miganiu nie jedną a wieloma diodami LED - to więcej ci się rozjaśni....

    Proponuję ci poszukaj sobie noty PDF do dowolnego wyświetlacza LCD - zapoznaj się dokładnie jak on działa i co trzeba zrobić krok po kroku zeby go oprogramować w C. Już same próby więcej ci wyjaśnią niż te wklejanie dziwnych bibliotek

    0
  • #6 08 Sty 2010 00:29
    jaros85
    Poziom 20  

    Może na samym początku sprawdź czy działa inicjalizacja LCD.
    Po podłączeniu zasilana (tylko zasilania) powinna pierwsza linia wyświetlać same kwadraty. Jeżeli nie ustaw kontrast.
    Jeżeli podłączyłeś wszystkie piny prawidłowo i po zaprogramowaniu uC na wyświetlaczu nic nie widać tzn. że zadziałała inicjalizacja i wtedy już każdy tekst się na pewno wyświetli.
    Po trzecie pierwszy wyświetlany tekst nie musi być poprzedzony funkcją LCD_GoTo(0,0); tak samo nie musi być w pętli while(1).

    Wystarczy tylko:

    Code:
    int main(void) //Program główny
    
    {
    LCD_Initalize();
    LCD_WriteText("Hello!");
    }

    i wyświetli się napis Hello!

    Sądzę że w twoim przypadku błąd tkwi w połączeniach LCD z uC a nie w samym kodzie.

    Ale jak pisali moi poprzednicy przeskok od mrugającej diody do obsługi LCD to trochę za szybko.
    Pozdrawiam i życzę powodzenia w programowaniu uC w C. :D

    0