Fork me on GitHub

Microcontrolandos

O Blog está passando por uma fase de mudanças. Todos os posts estão sendo atualizados, códigos, links e imagens estão sendo arrumados. Conteúdos novos ainda estão por vir.

PIC: LCD com 74HC595

Compartilhe:



Neste post mostrarei uma maneira de ligar um display de LCD a microcontroladores PIC que possuem poucos pinos de IO, como é o caso do PIC12F675.

Utilizando um registrador de deslocamento (Shift Register), o 74HC595, funcionando como um expansor de portas I/O, é possível utilizar apenas 3 pinos do microcontrolador, ao invés de 6 pinos.

Para o PIC12F675 é recomendável usar seu clock interno (INTOSC Oscillator: I/O function on GP4/OSC2/CLKOUT pin, I/O function on GP5/OSC1/CLKIN). Assim sobram mais pinos para serem usados como entrada analógica, ligar um botão ou um LED.


Download


LCD595.zip

Código


/*
LCD595 - LCD com 74HC595.
Autor: Tiago Melo
Blog: Microcontrolandos
Compilador: MikroC PRO PIC
Bibliotecas: Lcd_Constants, Conversions, C_String
*/
// Pinos ligados do 74HC595 ligados ao PIC.
sbit LCD595_Data at GP2_bit;
sbit LCD595_Clock at GP1_bit;
sbit LCD595_Latch at GP4_bit;
sbit LCD595_Data_Direction at TRISIO2_bit;
sbit LCD595_Clock_Direction at TRISIO1_bit;
sbit LCD595_Latch_Direction at TRISIO4_bit;
#define LCD595_Data(b) LCD595_Chr_CP(b)
static void LCD595_Send_Bit(char value) {
LCD595_Data = value;
// Pulso de clock desloca e carrega o bit no 74HC595.
LCD595_Clock = 1;
Delay_us(1);
LCD595_Clock = 0;
}
// Envia 4 bits dos dados + o pino RS.
static void LCD595_Send(char nibble) {
char i, k, aux = nibble;
LCD595_Clock = 0;
// Enviar duas vezes para pulsar o pino E.
for(k = 0; k < 2; k++) {
// Pino E.
LCD595_Send_Bit(!k.B0);
// Pino RS.
LCD595_Send_Bit(nibble.B4);
// Pinos D4 - D7.
for(i = 0; i < 4; i++) {
LCD595_Send_Bit(nibble.B3);
nibble <<= 1;
}
// Atualiza as saídas do 74HC595.
LCD595_Latch = 1;
Delay_us(1);
LCD595_Latch = 0;
LCD595_Data = 0;
// De novo...
nibble = aux;
}
Delay_us(100);
}
// Envia um comando.
void LCD595_Cmd(char cmd) {
LCD595_Send(cmd >> 4);
LCD595_Send(cmd & 0x0F);
Delay_ms(5);
}
// Define a posição do cursor. Começa no 1..
void LCD595_Set_Cursor(char row, char col) {
switch(row) {
case 2: row = 191; break;
case 3: row = 147; break;
case 4: row = 211; break;
default: row = 127;
}
LCD595_Cmd(row + col);
}
// Envia um dado ou escreve um caracter na posição atual do cursor.
void LCD595_Chr_CP(char character) {
LCD595_Send((character >> 4 ) | 0x10);
LCD595_Send((character & 0x0F ) | 0x10);
}
// Envia um dado ou escreve um caracter na posição especificada.
void LCD595_Chr(char row, char col, char character) {
LCD595_Set_Cursor(row, col);
LCD595_Chr_CP(character);
}
// Escreve um texto na posição atual do cursor.
void LCD595_Out_CP(char *text) {
while(*text) {
LCD595_Chr_CP(*text++);
}
}
// Escreve um texto na posição especificada.
void LCD595_Out(char row, char col, char *text) {
LCD595_Set_Cursor(row, col);
LCD595_Out_CP(text);
}
// Inicializa o display LCD.
void LCD595_Init() {
// Define a direção dos pinos.
LCD595_Data_Direction = 0;
LCD595_Clock_Direction = 0;
LCD595_Latch_Direction = 0;
Delay_ms(50);
LCD595_Send(3);
Delay_us(4500);
LCD595_Send(3);
Delay_us(4500);
LCD595_Send(3);
Delay_us(150);
LCD595_Send(2);
// modo 4bits, 5x8, 2 linhas
LCD595_Cmd(0x28);
// Display ON
LCD595_Cmd(12);
// left, shift decrement
LCD595_Cmd(6);
}
void main() {
char mensagem[5], contador = 0;
CMCON = 7; // Desabilita o comparador analogico.
ANSEL = 0; // Desabilita o canal analogico.
LCD595_Init(); // Iniciliza o display LCD.
LCD595_Cmd(_LCD_CLEAR); // Limpa o display.
// Escreve o texto no LCD na linha 1, coluna 3.
LCD595_Out(1, 3, "LCD 74HC595");
while(1) {
// Converte o numero para String.
ByteToStr(contador++, mensagem);
// Escreve a mensagem no LCD na linha 2, coluna 7.
LCD595_Out(2, 7, mensagem);
// Faz nada por 1s.
Delay_ms(1000);
}
}
view raw LCD595.c hosted with ❤ by GitHub

Escreva um comentário

6 comentários:

  1. Tenho um display 16×2, modelo JHD 162A, quando ligo ele ao pic 18F4550, com a rotina normal, o display nao exibe nada em sua primeira linha, e sua segunda linha apresenta blocos preenchidos, gostaria de uma ajuda para que conseguisse imprimir algo no display, no proteus o programa funciona corretamente, mas quando coloco no protoboard acontece isto.

    ResponderExcluir
  2. cara, fantastico, vc esta de parabens!

    ResponderExcluir
  3. Depois de varias tentativas sem sucesso, preciso de sua ajuda para usar um lm 35 e imprimir o valor da temperatura no display usando o pic12F675 .Não estou conseguindo programar o envios dos dados para o registrador 74hc595. Se puder me ajudar mais uma vez, eu agradeço muito desde ja, e parabens pelo seu trabalho no blog.

    ResponderExcluir