Main Content

Circuitos_1
Circuitos_2

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.

Circuitos_3_LCDpins

O HD44780 é um módulo que expõe os seguintes pinos:

PinoNomeDescrição
1VSSEnergia (GND)
2VCCEnergia (+5V)
3VEEAjuste de Contraste
4RS0 = input de instruções, 1 = input de dados
5R/W0 = Escrever para o módulo, 1 - Ler do módulo
6ENSinal de Enable
7D0Data bus line 0 (LSB)
8D1Data bus line 1
9D2Data bus line 2
10D3Data bus line 3
11D4Data bus line 4
12D5Data bus line 5
13D6Data bus line 6
14D7Data bus line 7 (MSB)
15ALED Backlight +
16KLED Backlight -

Para enviar dados ou comandos para o módulo é necessário seguir os seguintes passos:

  1. Colocar o Enable a HIGH
  2. Colocar o RS e os D0-D7 com os valores pretendidos
  3. 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:

A2A1A0Endereço I2C
LLL0x20
LLH0x21
LHL0x22
LHH0x23
HLL0x24
HLH0x25
HHL0x26
HHH0x27

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

Circuitos_3_Schematics

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

Circuitos_4_Pinout

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.