Os circuitos hoje apresentados permitem o controlo por parte de um micro-controlador de um display LCD que tem um chip muito comum - o HD44780 ou um que seja compatível com este.
Existem diversos formatos para este LCD, no entanto o mais utilizado é o de 16x2 (16 colunas com 2 linhas). Também existem diversas cores para os LCDs.
Tratando-se de um display LCD que recebe a informação que irá apresentar em formato série, este usa um número bastante significativo de pinos de um micro-controlador.
O HD44780 é um módulo que expõe os seguintes pinos:
Pino | Nome | Descrição |
---|---|---|
1 | VSS | Energia (GND) |
2 | VCC | Energia (+5V) |
3 | VEE | Ajuste de Contraste |
4 | RS | 0 = input de instruções, 1 = input de dados |
5 | R/W | 0 = Escrever para o módulo, 1 - Ler do módulo |
6 | EN | Sinal de Enable |
7 | D0 | Data bus line 0 (LSB) |
8 | D1 | Data bus line 1 |
9 | D2 | Data bus line 2 |
10 | D3 | Data bus line 3 |
11 | D4 | Data bus line 4 |
12 | D5 | Data bus line 5 |
13 | D6 | Data bus line 6 |
14 | D7 | Data bus line 7 (MSB) |
15 | A | LED Backlight + |
16 | K | LED Backlight - |
Para enviar dados ou comandos para o módulo é necessário seguir os seguintes passos:
- Colocar o Enable a HIGH
- Colocar o RS e os D0-D7 com os valores pretendidos
- Colocar o Enable a LOW
É necessário assegurar que existe um timing de cerca de 37 usec entre as operações descritas.
O módulo tem dois modos de operação:
- modo de 8-bits
- modo de 4-bits
O primeiro usa os 8 pinos de dados e o segundo apenas 4 deles (D4 a D7).
Nos circuitos apresentados iremos usar o modo 4-bit usando 6 pinos (4 pinos para os dados, mais um para o Enable e outro para o Tipo de instrução). Desta forma poupam-se 4 pinos (do D0 ao D3 não são usados) e os dados são enviados em dois passos (dois nibbles).
O HD44780 suporta um conjunto de comandos que estão documentados no seu datasheet, no entanto e como iremos usar uma biblioteca não é necessário conhecer em detalhe estes comandos.
Para diminuir o número de pinos usados iremos implementar a comunicação via I2C ou TWI. O Segundo circuito apresentado tem um Integrado - o PCF8574 - que implementa a interface I2C e que permite o envio de comandos para o HD44780 por essa via. Este usa apenas 2 pinos do protocolo I2C (SDA, SCL) mais os 5V e GND.
Neste circuito iremos usar 6 dos 8 pinos que o PCF8574 nos disponibiliza. Os mesmos 6 que foram necessários no primeiro circuito.
Quando estamos a usar um Integrado I2C ele permite que lhe seja configurado o endereço por pinos. O PCF8574 tem 3 pinos para esse efeito A0 a A2.
Estes devem ser ligados ao GND ou aos 5V (com um pull-up) para se configurar o endereço pretendido. No nosso caso foram todos ligados a GND. Ficando o integrado com o endereço 0x20.
Combinações de Pinos:
A2 | A1 | A0 | Endereço I2C |
---|---|---|---|
L | L | L | 0x20 |
L | L | H | 0x21 |
L | H | L | 0x22 |
L | H | H | 0x23 |
H | L | L | 0x24 |
H | L | H | 0x25 |
H | H | L | 0x26 |
H | H | H | 0x27 |
Conforme é apresentado no site da Malpartida, o desempenho do interface I2C é muito inferior a ter o HD44780 diretamente ligado ao AVR, mas quando se pretende apenas apresentar informação a poupança de pinos pode ser necessária.
Esquemático
Componentes (BOM)
Circuito 1:
- 1x LCD (DS1)
- 1x Resistência de 330 Ohms (R1)
- 1x Resistência Variável de 10K (RV1)
Circuito 2:
- 1x LCD (DS2)
- 1x Resistência de 330 Ohms (R2)
- 1x Resistência Variável de 10K (RV2)
- 1x PCF8574 (U1)
Pin-out dos IC
sketch para correr no CSEduino/Arduino
O código apresentado usa uma biblioteca externa que pode ser descarregada neste link, ou localmente neste link e que tem que ser instalada através do Arduino IDE.
Esta biblioteca substitui a biblioteca do Arduino incluindo suporte para a comunicação I2C entre outras coisas.
Código para a ligação de 4-bit série:
#include <Wire.h>
#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
// Creat a set of new characters
byte smiley[8] = {
0b00000,
0b00000,
0b01010,
0b00000,
0b00000,
0b10001,
0b01110,
0b00000
};
byte armsUp[8] = {
0b00100,
0b01010,
0b00100,
0b10101,
0b01110,
0b00100,
0b00100,
0b01010
};
byte frownie[8] = {
0b00000,
0b00000,
0b01010,
0b00000,
0b00000,
0b00000,
0b01110,
0b10001
};
void setup()
{
lcd.begin(16,2); // initialize the lcd
lcd.createChar (0, smiley); // load character to the LCD
lcd.createChar (1, armsUp); // load character to the LCD
lcd.createChar (2, frownie); // load character to the LCD
lcd.home (); // go home
lcd.print("Hello, CSEduino ");
lcd.setCursor ( 0, 1 ); // go to the next line
lcd.print (" FORUM - fm ");
}
void loop()
{
// Do a little animation by writing to the same location
lcd.setCursor ( 14, 1 );
lcd.print (char(2));
delay (200);
lcd.setCursor ( 14, 1 );
lcd.print ( char(0));
delay (200);
}
//Sketch uses 4,048 bytes (12%) of program storage space. Maximum is 32,256 bytes.
// Global variables use 327 bytes (15%) of dynamic memory, leaving 1,721 bytes for local variables. Maximum is 2,048 bytes.
Código para a ligação 4-bit sobre I2C:
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#define BACKLIGHT_PIN 13
LiquidCrystal_I2C lcd(0x20, BACKLIGHT_PIN, POSITIVE); // Set the LCD I2C address
// Creat a set of new characters
const uint8_t charBitmap[][8] = {
{ 0xc, 0x12, 0x12, 0xc, 0, 0, 0, 0 },
{ 0x6, 0x9, 0x9, 0x6, 0, 0, 0, 0 },
{ 0x0, 0x6, 0x9, 0x9, 0x6, 0, 0, 0x0 },
{ 0x0, 0xc, 0x12, 0x12, 0xc, 0, 0, 0x0 },
{ 0x0, 0x0, 0xc, 0x12, 0x12, 0xc, 0, 0x0 },
{ 0x0, 0x0, 0x6, 0x9, 0x9, 0x6, 0, 0x0 },
{ 0x0, 0x0, 0x0, 0x6, 0x9, 0x9, 0x6, 0x0 },
{ 0x0, 0x0, 0x0, 0xc, 0x12, 0x12, 0xc, 0x0 }
};
void setup()
{
int charBitmapSize = (sizeof(charBitmap ) / sizeof (charBitmap[0]));
// Switch on the backlight
pinMode ( BACKLIGHT_PIN, OUTPUT );
digitalWrite ( BACKLIGHT_PIN, HIGH );
lcd.begin(16,2); // initialize the lcd
for ( int i = 0; i < charBitmapSize; i++ )
{
lcd.createChar ( i, (uint8_t *)charBitmap[i] );
}
lcd.home (); // go home
lcd.print("Hello, Altlab");
lcd.setCursor ( 0, 1 ); // go to the next line
lcd.print("CSEduino LCD i2C");
delay ( 10000 );
}
void loop()
{
lcd.home ();
// Do a little animation by writing to the same location
for ( int i = 0; i < 2; i++ )
{
for ( int j = 0; j < 16; j++ )
{
lcd.print (char(random(7)));
}
lcd.setCursor ( 0, 1 );
}
delay (200);
}
// Sketch uses 4,784 bytes (14%) of program storage space. Maximum is 32,256 bytes.
// Global variables use 374 bytes (18%) of dynamic memory, leaving 1,674 bytes for local variables. Maximum is 2,048 bytes.