Witam. Po mrugający ledach i wyświetlaczach 7 segmentowych postanowiłem pobawić się LCD. Ze strony http://radzio.dxp.pl/hd44780/ ściągnąłem biblioteki w wersji 4 bit. Wyświetlacz to: http://www.artronic.pl/o_produkcie.php?id=576?
Połączenia:
DB4 - PB1
DB5 - PDO
DB6 - PB2
DB7 - PD1
RS - PD3
E - PD2
R/W - PD4.
Bibliotekę zmodyfikowałem następująco:
Natomiast plik główny:
Wkleiłem na wszelki wypadek wszystko. Niestety na wyświetlaczu nic nie widać.
Czy po zasileniu (nawet bez mikro) taki wyświetlacz powinien się "zaświecić"? Bo już nie wiem czy może LCD już zabity czy to programowo jest źle. Wszystko jest zasilone z USB (atmega i wyświetlacz - może nie wyrabia?).
Połączenia:
DB4 - PB1
DB5 - PDO
DB6 - PB2
DB7 - PD1
RS - PD3
E - PD2
R/W - PD4.
Bibliotekę zmodyfikowałem następująco:
#include <avr/io.h>
#include <util/delay.h>
//-------------------------------------------------------------------------------------------------
//
// 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_PIN PIND
#define LCD_RS (1 << PD3)
#define LCD_RW_DIR DDRD
#define LCD_RW_PORT PORTD
#define LCD_RW_PIN PIND
#define LCD_RW (1 << PD4)
#define LCD_E_DIR DDRD
#define LCD_E_PORT PORTD
#define LCD_E_PIN PIND
#define LCD_E (1 << PD2)
#define LCD_DB4_DIR DDRB
#define LCD_DB4_PORT PORTB
#define LCD_DB4_PIN PINB
#define LCD_DB4 (1 << PB1)
#define LCD_DB5_DIR DDRD
#define LCD_DB5_PORT PORTD
#define LCD_DB5_PIN PIND
#define LCD_DB5 (1 << PD0)
#define LCD_DB6_DIR DDRB
#define LCD_DB6_PORT PORTB
#define LCD_DB6_PIN PINB
#define LCD_DB6 (1 << PB2)
#define LCD_DB7_DIR DDRD
#define LCD_DB7_PORT PORTD
#define LCD_DB7_PIN PIND
#define LCD_DB7 (1 << PD1)
//-------------------------------------------------------------------------------------------------
//
// Instrukcje kontrolera Hitachi HD44780
//
//-------------------------------------------------------------------------------------------------
#define HD44780_CLEAR 0x01
#define HD44780_HOME 0x02
#define HD44780_ENTRY_MODE 0x04
#define HD44780_EM_SHIFT_CURSOR 0
#define HD44780_EM_SHIFT_DISPLAY 1
#define HD44780_EM_DECREMENT 0
#define HD44780_EM_INCREMENT 2
#define HD44780_DISPLAY_ONOFF 0x08
#define HD44780_DISPLAY_OFF 0
#define HD44780_DISPLAY_ON 4
#define HD44780_CURSOR_OFF 0
#define HD44780_CURSOR_ON 2
#define HD44780_CURSOR_NOBLINK 0
#define HD44780_CURSOR_BLINK 1
#define HD44780_DISPLAY_CURSOR_SHIFT 0x10
#define HD44780_SHIFT_CURSOR 0
#define HD44780_SHIFT_DISPLAY 8
#define HD44780_SHIFT_LEFT 0
#define HD44780_SHIFT_RIGHT 4
#define HD44780_FUNCTION_SET 0x20
#define HD44780_FONT5x7 0
#define HD44780_FONT5x10 4
#define HD44780_ONE_LINE 0
#define HD44780_TWO_LINE 8
#define HD44780_4_BIT 0
#define HD44780_8_BIT 16
#define HD44780_CGRAM_SET 0x40
#define HD44780_DDRAM_SET 0x80
//-------------------------------------------------------------------------------------------------
//
// Deklaracje funkcji
//
//-------------------------------------------------------------------------------------------------
void LCD_WriteCommand(unsigned char);
unsigned char LCD_ReadStatus(void);
void LCD_WriteData(unsigned char);
unsigned char LCD_ReadData(void);
void LCD_WriteText(char *);
void LCD_GoTo(unsigned char, unsigned char);
void LCD_Clear(void);
void LCD_Home(void);
void LCD_Initalize(void);
Natomiast plik główny:
#include <avr/io.h>
#include <util/delay.h>
#include <moje/HD44780.h>
void _LCD_OutNibble(unsigned char nibbleToWrite)
{
if(nibbleToWrite & 0x01)
LCD_DB4_PORT |= LCD_DB4;
else
LCD_DB4_PORT &= ~LCD_DB4;
if(nibbleToWrite & 0x02)
LCD_DB5_PORT |= LCD_DB5;
else
LCD_DB5_PORT &= ~LCD_DB5;
if(nibbleToWrite & 0x04)
LCD_DB6_PORT |= LCD_DB6;
else
LCD_DB6_PORT &= ~LCD_DB6;
if(nibbleToWrite & 0x08)
LCD_DB7_PORT |= LCD_DB7;
else
LCD_DB7_PORT &= ~LCD_DB7;
}
//-------------------------------------------------------------------------------------------------
//
// Funkcja wystawiająca półbajt na magistralę danych
//
//-------------------------------------------------------------------------------------------------
unsigned char _LCD_InNibble(void)
{
unsigned char tmp = 0;
if(LCD_DB4_PIN & LCD_DB4)
tmp |= (1 << 0);
if(LCD_DB5_PIN & LCD_DB5)
tmp |= (1 << 1);
if(LCD_DB6_PIN & LCD_DB6)
tmp |= (1 << 2);
if(LCD_DB7_PIN & LCD_DB7)
tmp |= (1 << 3);
return tmp;
}
//-------------------------------------------------------------------------------------------------
//
// Funkcja zapisu bajtu do wyświetacza (bez rozróżnienia instrukcja/dane).
//
//-------------------------------------------------------------------------------------------------
void _LCD_Write(unsigned char dataToWrite)
{
LCD_DB4_DIR |= LCD_DB4;
LCD_DB5_DIR |= LCD_DB5;
LCD_DB6_DIR |= LCD_DB6;
LCD_DB7_DIR |= LCD_DB7;
LCD_RW_PORT &= ~LCD_RW;
LCD_E_PORT |= LCD_E;
_LCD_OutNibble(dataToWrite >> 4);
LCD_E_PORT &= ~LCD_E;
LCD_E_PORT |= LCD_E;
_LCD_OutNibble(dataToWrite);
LCD_E_PORT &= ~LCD_E;
while(LCD_ReadStatus()&0x80);
}
//-------------------------------------------------------------------------------------------------
//
// Funkcja odczytu bajtu z wyświetacza (bez rozróżnienia instrukcja/dane).
//
//-------------------------------------------------------------------------------------------------
unsigned char _LCD_Read(void)
{
unsigned char tmp = 0;
LCD_DB4_DIR &= ~LCD_DB4;
LCD_DB5_DIR &= ~LCD_DB5;
LCD_DB6_DIR &= ~LCD_DB6;
LCD_DB7_DIR &= ~LCD_DB7;
LCD_RW_PORT |= LCD_RW;
LCD_E_PORT |= LCD_E;
tmp |= (_LCD_InNibble() << 4);
LCD_E_PORT &= ~LCD_E;
LCD_E_PORT |= LCD_E;
tmp |= _LCD_InNibble();
LCD_E_PORT &= ~LCD_E;
return tmp;
}
//-------------------------------------------------------------------------------------------------
//
// Funkcja zapisu rozkazu do wyświetlacza
//
//-------------------------------------------------------------------------------------------------
void LCD_WriteCommand(unsigned char commandToWrite)
{
LCD_RS_PORT &= ~LCD_RS;
_LCD_Write(commandToWrite);
}
//-------------------------------------------------------------------------------------------------
//
// Funkcja odczytu bajtu statusowego
//
//-------------------------------------------------------------------------------------------------
unsigned char LCD_ReadStatus(void)
{
LCD_RS_PORT &= ~LCD_RS;
return _LCD_Read();
}
//-------------------------------------------------------------------------------------------------
//
// Funkcja zapisu danych do pamięci wyświetlacza
//
//-------------------------------------------------------------------------------------------------
void LCD_WriteData(unsigned char dataToWrite)
{
LCD_RS_PORT |= LCD_RS;
_LCD_Write(dataToWrite);
}
//-------------------------------------------------------------------------------------------------
//
// Funkcja odczytu danych z pamięci wyświetlacza
//
//-------------------------------------------------------------------------------------------------
unsigned char LCD_ReadData(void)
{
LCD_RS_PORT |= LCD_RS;
return _LCD_Read();
}
//-------------------------------------------------------------------------------------------------
//
// 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; //
LCD_RW_DIR |= LCD_RW; //
_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
LCD_RW_PORT &= ~LCD_RW;
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
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
}
int main(void)
{
LCD_Initalize();
while(1)
{
LCD_WriteText("lalalal");
}
}Wkleiłem na wszelki wypadek wszystko. Niestety na wyświetlaczu nic nie widać.
Czy po zasileniu (nawet bez mikro) taki wyświetlacz powinien się "zaświecić"? Bo już nie wiem czy może LCD już zabity czy to programowo jest źle. Wszystko jest zasilone z USB (atmega i wyświetlacz - może nie wyrabia?).