quinta-feira, 5 de maio de 2016

Como gravar um display lcd no pic 16f628a

Salve salve galerinha, de tanto eu mexer com arduino, dessa vez so pra variar estou começando a utilizar o pic. O arquirival da plataforma arduino, muito embora ele seja BEM, BEM BEM mais complicado de mexer.

Então povo, pra começar os microcontroladores PIC são da familia microchip e são programados em assembly, que e nada mais nada menos que a linguagem "mae" de todas as outras linguagens, c,c++ e suas infinitas variações, paschal e tudo mais.

Para usar codigo de outra linguagem voce precisaria ter um compilador, que converte linguagem c, c++ ou seja lah o que for em assembly.Nessa parte e bastante importante voce usar o compilador certo, principalmente pro codigo que esteja usando.

Existem compiladores que são pagos, mas no meu caso irei utilizar um  compilador gratuito mesmo, o C CCS.

Começando pelo inicio, voce precisa comprar um gravador de PIC, existem varios no mercado, o k150, o pickit2, o pickit3, eu estarei usando o pickit 3, que e esta graçinha aqui.


que possui como datasheet essa seguinte pinagem
e como chip estarei utilizando o 16f628a, que e famoso para os iniciantes no pic.Ele possui essa pinagem aqui

para pinar voce deve conectar os fios do pickit3 com os mesmos nomes do chip do pic 16f628, nesse caso o pino 6 não entra do pickkit3.
fica mais ou menos assim:

pickit 3           pic16f628a
1-------------------4
2-------------------14
3------------------5
4-------------------13
5------------------12
Como software voce vai precisar de 3 programit as: O MPLAB, o CCS C COMPILER*gratuito* e o pick3

Esses 2 primeiros são apenas para gerar o arquivo hexadecimal, e o terceiro ja e pra gravar o mesmo no pic.

Meu video no youtube ensinara passo a passo como criar o arquivo hexadecimal, então so me resta colocar aqui o codigo fonte e a biblioteca do display lcd do mesmo.

biblioteca do display lcd(salvar em arquivo lcd.h)

-----------------------------------------
*************************************************************************/
/* Rotinas para o LCD */
/***************************************************************************/
//Este é o bloco com as rotinas necessárias para manipular o LCD
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Envio de "Nibble" para o LCD *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
//Esta rotina lê o "Nibble" inferior de uma variável e envia para o LCD.
void envia_nibble_lcd(int dado)
{
//Carrega as vias de dados (pinos) do LCD de acordo com o nibble lido
output_bit(lcd_db4, bit_test(dado,0));    //Carrega DB4 do LCD com o bit DADO<0>
output_bit(lcd_db5, bit_test(dado,1));    //Carrega DB5 do LCD com o bit DADO<1>
output_bit(lcd_db6, bit_test(dado,2));    //Carrega DB6 do LCD com o bit DADO<2>
output_bit(lcd_db7, bit_test(dado,3));    //Carrega DB7 do LCD com o bit DADO<3>
//Gera um pulso de enable
output_high(lcd_enable);      // ENABLE = 1
delay_us(1);                  // Recomendado para estabilizar o LCD
output_low(lcd_enable);       // ENABLE = 0
return;                       // Retorna ao ponto de chamada da função
}
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Envio de Byte para o LCD *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
//Esta rotina irá enviar um dado ou um comando para o LCD conforme abaixo:
// ENDEREÇO = 0 -> a variável DADO será uma instrução
// ENDEREÇO = 1 -> a variável DADO será um caractere
void envia_byte_lcd(boolean endereco, int dado)
{
output_bit(lcd_rs,endereco);  // Seta o bit RS para instrução ou caractere
delay_us(100);                // Aguarda 100 us para estabilizar o pino do LCD
output_low(lcd_enable);       // Desativa a linha ENABLE
envia_nibble_lcd(dado>>4);   // Envia a parte ALTA do dado/comando
envia_nibble_lcd(dado & 0x0f); // Limpa a parte ALTA e envia a parte BAIXA do
                               // dado/comando
delay_us(40);                  // Aguarda 40us para estabilizar o LCD
return;                       // Retorna ao ponto de chamada da função
}
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Envio de caractere para o LCD *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
// Esta rotina serve apenas como uma forma mais fácil de escrever um caractere
// no display. Ela pode ser eliminada e ao invés dela usaremos diretamente a
// função envia_byte_lcd(1,"<caractere a ser mostrado no LCD>"); ou
// envia_byte_lcd(1,<código do caractere a ser mostrado no LCD>);
void escreve_lcd(char c)
// envia caractere para o display
{
envia_byte_lcd(1,c);
}
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Função para limpar o LCD *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
// Como esta operação pode ser muito utilizada, transformando-a em função
// faz com que o código compilado seja menor.
void limpa_lcd()
{
envia_byte_lcd(0,0x01);          // Envia instrução para limpar o LCD
delay_ms(2);                     // Aguarda 2ms para estabilizar o LCD
return;                          // Retorna ao ponto de chamada da função
}
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Inicializa o LCD *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void inicializa_lcd()
{
output_low(lcd_db4);     // Garante que o pino DB4 estão em 0 (low)
output_low(lcd_db5);     // Garante que o pino DB5 estão em 0 (low)
output_low(lcd_db6);     // Garante que o pino DB6 estão em 0 (low)
output_low(lcd_db7);     // Garante que o pino DB7 estão em 0 (low)
output_low(lcd_rs);      // Garante que o pino RS estão em 0 (low)
output_low(lcd_enable);  // Garante que o pino ENABLE estão em 0 (low)
delay_ms(15);            // Aguarda 15ms para estabilizar o LCD
envia_nibble_lcd(0x03);  // Envia comando para inicializar o display
delay_ms(5);             // Aguarda 5ms para estabilizar o LCD
envia_nibble_lcd(0x03);  // Envia comando para inicializar o display
delay_ms(5);             // Aguarda 5ms para estabilizar o LCD
envia_nibble_lcd(0x03);  // Envia comando para inicializar o display
delay_ms(5);             // Aguarda 5ms para estabilizar o LCD
envia_nibble_lcd(0x02);  // CURSOR HOME - Envia comando para zerar o
                         //contador de caracteres e retornar à posição
                         // inicial (0x80).
delay_ms(1);             // Aguarda 1ms para estabilizar o LCD
envia_byte_lcd(0,0x28);  // FUNCTION SET - Configura o LCD para 4 bits,
                         // 2 linhas, fonte 5X7.
envia_byte_lcd(0,0x0c);  // DISPLAY CONTROL - Display ligado, sem cursor
limpa_lcd();             // Limpa o LCD
envia_byte_lcd(0,0x06);  // ENTRY MODE SET - Desloca o cursor para a direita
return;                  // Retorna ao ponto de chamada da função
}
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Define inicio da escrita *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
//Esta função foi adicionada e serve para se definir em que posição do
//LCD deseja-se iniciar a escrita. Para isto basta chamar a Função
//"caracter_Inicio()" indicando a linha e a coluna onde o cursor será
// posicionado antes de se mandar escrever
void caracter_inicio(int linha, int coluna)//define a posicão de inicio da frase
{
int16 posicao=0;
   if(linha == 1)
   {
      posicao=0x80;     //Se setado linha 1, end incial 0x80
   }
   if(linha == 2)
   {
      posicao=0xc0;     //Se setado linha 2, end incial 0xc0
   }
posicao=posicao+coluna;     //soma ao end inicial, o numero da coluna
posicao--;                  //subtrai 1 para corrigir posição
envia_byte_lcd(0,posicao);
return;
}
/***************************************************************************/
/* Final das rotinas para o LCD */
/***************************************************************************/
----------------------------------------------------------------------------
----------------------------------------------------------------------------



codigo fonte para gerar o programa:



--------------------------
#include <16F628A.h>            //Define o modelo do microcontrolador
// Fusíveis de configuração do microcontrolador
#FUSES NOWDT                    //Watch Dog Timer desabilitado
#FUSES HS                       //oscilador cristal
#FUSES PUT                      //Power Up Timer
#FUSES NOPROTECT                //sem proteção para leitura da eprom
#FUSES BROWNOUT                 //Resetar quando detectar brownout
#FUSES NOMCLR                   //Reset desabilitado
#FUSES NOLVP                    //prog. baixa voltagem desabilitado
#FUSES NOCPD                    //Sem travar o chip
#use delay(clock=16000000)      //Define o cristal utilizado
//Definição de entradas e saídas
//Cada bit representa um pino físico de I/O
// 0 significa que o pino será uma saída
// 1 significa que o pino será uma entrada
#define trisa 0b00000000
#define trisb 0b00000000
// Estas são as definições dos pinos que o LCD utiliza.
// Definem quais pinos do PIC controlarão os pinos do LCD
#define lcd_enable pin_a1       // pino enable do LCD
#define lcd_rs     pin_a0       // pino rs (register select)do LCD
                                // (0) para comandos    (1) para dados
#define lcd_db4    pin_b4       // pino de dados d4 do LCD
#define lcd_db5    pin_b5       // pino de dados d5 do LCD
#define lcd_db6    pin_b6       // pino de dados d6 do LCD
#define lcd_db7    pin_b7       // pino de dados d7 do LCD
#include <lcd.h>                //declaração da biblioteca do LCD
//Programa principal
void main(){
    inicializa_lcd();               //Inicializa o LCD
while(1){
        //limpa_lcd();            //Limpa o display do LCD
        caracter_inicio(2,6);
        printf(escreve_lcd,"                ");
        delay_ms(500);
        caracter_inicio(1,4);   //Define o caracter de inicio da escrita
        printf(escreve_lcd,"ELETRONICAEUTILIDADES");  //Escreve no LCD
        delay_ms(2000);
                
        caracter_inicio(1,4);
        printf(escreve_lcd,"           ");
        delay_ms(500);
        caracter_inicio(2,6);
        printf(escreve_lcd,"P I C");
        delay_ms(2000);        
        }
} //fecha void main
----------------------------------
E e claro a imagem com o esquema de montagem:
 E em breve o video pessoal, aguardem:
 E como prometido, eis o vídeo funcionando:

Nenhum comentário: