PIC16F628A 16x4 Problema de la pantalla LCD al usar MPLABX

0

Estoy intentando conectar un LCD de 16x4 con un PIC16F628A, pero no puedo obtener ninguna respuesta en la pantalla, la pantalla está en blanco. Puse un LED para indicar si era el momento adecuado y, aparentemente, todo es correcto. Lo probé en Proteus y tampoco funciona.

Mi código y mi biblioteca están abajo:

/* 
 * File:   main.c
 * Author: Leonardo
 *
 * Created on 11 de Março de 2014, 00:15
 */

#include <stdio.h>
#include <stdlib.h>
#include "GenericTypeDefs.h"
#include <xc.h>
#include "LCD_lib.h"

// DEFINIÇÃO DOS FUSES
#pragma config FOSC = INTOSCIO      // Oscillator Selection bits (HS oscillator: High-speed crystal/resonator on RA6/OSC2/CLKOUT and RA7/OSC1/CLKIN)
//#pragma config FOSC = INTOSCIO        // Oscillator Selection bits (HS oscillator: High-speed crystal/resonator on RA6/OSC2/CLKOUT and RA7/OSC1/CLKIN)
#pragma config WDTE = OFF       // Watchdog Timer Enable bit (WDT disabled)
#pragma config PWRTE = ON       // Power-up Timer Enable bit (PWRT enabled)
#pragma config MCLRE = OFF      // RA5/MCLR/VPP Pin Function Select bit (RA5/MCLR/VPP pin function is digital input, MCLR internally tied to VDD)
#pragma config BOREN = OFF      // Brown-out Detect Enable bit (BOD disabled)
#pragma config LVP = OFF        // Low-Voltage Programming Enable bit (RB4/PGM pin has digital I/O function, HV on MCLR must be used for programming)
#pragma config CPD = ON        // Data EE Memory Code Protection bit (Data memory code protection off)
#pragma config CP = OFF         // Flash Program Memory Code Protection bit (Code protection off)

#define __XTAL_FREQ 4000000

#define LED_TRIS  TRISAbits.TRISA0
#define LED       PORTAbits.RA0

void delay_ms(long mili);
void delay_us(long micro);

/*
 * 
 */
int main (void){

      lcd_inicia(0x28, 0x0f, 0x06);      // Inicializa LCD
     lcd_limpa_tela();                 // Limpa LCD
     LED_TRIS = 0;
     LED = 0;
//  Prcessamento

        while(TRUE){
            LED = 1;
              lcd_posicao(1,1);
     imprime_string_lcd("Tensao Entrada AN0");
       lcd_posicao(2,2);
            lcd_escreve_dado('A');
            delay_ms(1000);
            LED = 0;
            delay_ms(1000);
        }
}

//*******************FUNÇÃO DELAY EM MILI-SEGUNDOS*******************////
// conta 4mhz/4 = 1mhz T = 1/1mhz = 1us para se obter 1ms então temos:
// então 1ms/1us = 1000 ciclos.
void delay_ms(long mili)
{
   while(mili > 0)
   {
      _delay(1000);//1ms com clock de 20mhz = 5000
      mili--;      //1ms com clock de 4mhz = 1000
   }

}
////////////////////////////////////////////////////////////////////////////

//*******************FUNÇÃO DELAY EM MICRO-SEGUNDOS*******************////
// conta 4mhz/4 = 1mhz T = 1/1mhz = 1us para se obter 1ms então temos:
// então 1us/1us = 1 ciclo.
void delay_us(long micro)
{
   while(micro > 0)
   {
      _delay(1);//1us com clock de 20mhz = 5
      micro--;//1us com clock de 4mhz = 1
   }

}

///////////////////////////////////////////////////////////////////////////

/* 
 * File:   LCD_lib.h
 * Author: bruno
 *
 * Created on 20 de Agosto de 2013, 14:25
 */

#ifndef LCD_LIB_H
#define LCD_LIB_H

#ifdef  __cplusplus
extern "C" {
#endif

#ifdef  __cplusplus
}
#endif

#endif  /* LCD_LIB_H */

/*********************************************************************************************************
******************************************BIBLIOTECA DISPLAY LCD******************************************
**                                                                                                       *
**                    Esta biblioteca contém as funções de controle do display LCD.                      *
**                                                                                                       *
**  Livro: Microcontroladores PIC18 - Aprenda e Programe em Linguagem C.                                 *
**  Autor: Alberto Noboru Miyadaira                                                                      *
**  Versão: v0.1                                                                                         *
**  Data: 12/03/2011                                                                                     *
*********************************************************************************************************/
#include <plib/delays.h>

//#ifndef Fosc
 // #define Fosc 8 //Define a frequência do oscilador. Este valor deve corresponder a frequência do oscilador utilizado pelo PIC18.
//#endif
// Os nome definidos são os próprios nomes dos pinos do display LCD.
#define B7 PORTBbits.RB7 //Define o nome B7 para a estrutra.
#define E_B7 TRISBbits.TRISB7=1;
#define S_B7 TRISBbits.TRISB7=0;
#define B6 PORTBbits.RB6 //Define o nome B6 para a estrutra.
#define E_B6 TRISBbits.TRISB6=1;
#define S_B6 TRISBbits.TRISB6=0;
#define B5 PORTBbits.RB5 //Define o nome B5 para a estrutra.
#define E_B5 TRISBbits.TRISB5=1;
#define S_B5 TRISBbits.TRISB5=0;
#define B4 PORTBbits.RB4 //Define o nome B4 para a estrutra.
#define E_B4 TRISBbits.TRISB4=1;
#define S_B4 TRISBbits.TRISB4=0;
#define E  PORTBbits.RB3  //Define o nome E para a estrutra.
#define E_E TRISBbits.TRISB3=1;
#define S_E TRISBbits.TRISB3=0;
//#define RW PORTBbits.RB2//Define o nome RW para a estrutra.
//#define E_RW TRISBbits.TRISB2=1;
//#define S_RW TRISBbits.TRISB2=0;
#define RS PORTBbits.RB1 //Define o nome RS para a estrutra.
#define E_RS TRISBbits.TRISB1=1;
#define S_RS TRISBbits.TRISB1=0;

void gera_atraso_us(unsigned int atraso)//adaptado para Fosc de 20MHz
{
//  do
//  {
//    atraso--;
//  }while (atraso>0);
       while(atraso > 0)
   {
      _delay(1);//1us com clock de 20mhz = 5
      atraso--;//1us com clock de 4mhz = 1
   }
}

//void delay_us(long micro)
//{
//   while(micro > 0)
//   {
//      _delay(5);//1us com clock de 20mhz = 5
//      micro--;//1us com clock de 20mhz = 4
//   }
//
//}

unsigned char lcd_envia_controle (unsigned char instrucao_dado, unsigned int escrita_leitura, unsigned char dado, unsigned int atraso_us)
{
/*
instrucao_dado = 0 //Instrução.
instrucao_dado = 1 //Dado.
escrita_leitura = 1 //Leitura.
escrita_leitura = 0 //Escrita.
*/
unsigned char dado_entrada=0;

//Configura os pinos de dados/controle, como saída.
S_B7;
S_B6;
S_B5;
S_B4;
S_E;
//S_RW;
S_RS;

RS = instrucao_dado; //Informa se é um comando ou dado.
//RW = escrita_leitura; //Informa se é escrita ou leitura.

        if(escrita_leitura == 0)
        {
                B7 = dado>>7;//B7 recebe o bit 7 da variável dado.
                B6 = dado>>6;//B6 recebe o bit 6 da variável dado.
                B5 = dado>>5;//B5 recebe o bit 5 da variável dado.
                B4 = dado>>4;//B4 recebe o bit 4 da variável dado.

                E = 1;//Habilita o Display LCD.
                gera_atraso_us(2); //Gera um delay de 2us.
                E = 0; //Desabilita o Display LCD.

                B7 = dado>>3;//B7 recebe o bit 3 da variável dado.
                B6 = dado>>2;//B6 recebe o bit 2 da variável dado.
                B5 = dado>>1;//B5 recebe o bit 1 da variável dado.
                B4 = dado;//B4 recebe o bit 0 da variável dado.

                E = 1;//Habilita o Display LCD.
                gera_atraso_us(2); //Gera um delay de 2us.
                E = 0; //Desabilita o Display LCD.

                gera_atraso_us(atraso_us); //Gera um delay de xus. MAX 255 ciclos de máquina

                return 0;
        }
        else
        {
                //Configura os pinos de dados, como entrada.
                E_B7;
                E_B6;
                E_B5;
                E_B4;

                E = 1;//Habilita o Display LCD.
          gera_atraso_us(2); //Gera um delay de 2us.

                dado_entrada = B7;
                dado_entrada = dado_entrada<<1 | B6;
                dado_entrada = dado_entrada<<1 | B5;
                dado_entrada = dado_entrada<<1 | B4;

                E = 0; //Desabilita o Display LCD.
                E = 1;//Habilita o Display LCD.
                gera_atraso_us(2); //Gera um delay de 2us.

                dado_entrada = dado_entrada<<1 | B7;
                dado_entrada = dado_entrada<<1 | B6;
                dado_entrada = dado_entrada<<1 | B5;
                dado_entrada = dado_entrada<<1 | B4;

                E = 0; //Desabilita o Display LCD.

                gera_atraso_us(atraso_us); //Gera um delay de xus. MAX 255 ciclos de máquina

                return dado_entrada;
        }
}

//Limpa a tela e coloca o cursor na linha um e coluna um do display.
void lcd_limpa_tela ( )
{
        lcd_envia_controle (0,0,0x01,2000);
}

//Coloca o cursor na linha um e coluna um do display.
void lcd_cursor_home ( )
{
        lcd_envia_controle (0,0,0x02,2000);
}

//Desloca o cursor para a direita ou esquerda.
void lcd_desloca_cursor(unsigned char direita_esquerda)
{
/*
0 - Desloca o cursor para a direita.
1 - Desloca o cursor para a esquerda.
*/
unsigned char cursor[2] = {0x14, 0x10};
        lcd_envia_controle (0,0,cursor[direita_esquerda],40);
}

//Desloca a mensagem para a direita ou esquerda.
void lcd_desloca_mensagem(unsigned char direita_esquerda)
{
/*
0 - Desloca a mensagem para a direita.
1 - Desloca a mensagem para a esquerda.
*/
unsigned char cursor[2] = {0x1c, 0x18};
        lcd_envia_controle (0,0,cursor[direita_esquerda],40);
}

//Liga/Desliga o cursor/display.
void lcd_LD_cursor (unsigned char config)
{
/*
0 - Desliga o cursor.
1 - Desliga o display.
2 - Liga o cursor com alternância.
3 - Liga o display e o cursor.
4 - Liga o display e o cursor piscante.
*/
unsigned char cursor [5] = {0x0c, 0x08, 0x0f, 0x0e, 0x0d};
        lcd_envia_controle (0,0,cursor[config],40);
}

//Coloca o cursor em uma determinada posição do LCD.
void lcd_posicao(unsigned char linha, unsigned char coluna)
{
        switch (linha)
        {
                case 1:
                        lcd_envia_controle (0,0,0x80+coluna-1,40);
                        break;
                case 2:
                        lcd_envia_controle (0,0,0xc0+coluna-1,40);
                        break;
                case 3:
                        lcd_envia_controle (0,0,0x94+coluna-1,40);
                        break;
                case 4:
                        lcd_envia_controle (0,0,0xd4+coluna-1,40);
                        break;
        }
}

//Escreve um caractere ou símbolo no display.
void lcd_escreve_dado(unsigned char dado)
{
        lcd_envia_controle (1,0,dado,45);
}

//Retorna o caractere presente na posição do cursor.
unsigned char lcd_le_dado( )
{
        return lcd_envia_controle (1,1,0,45);
}

//Retorna o valor do status + contador de endereço.
unsigned char lcd_status ( )
{
        return lcd_envia_controle (0,1,0,40);
}

//Envia String para o Display LCD.
//void imprime_string_lcd(const rom char *s_caracteres)
void imprime_string_lcd(unsigned char *s_caracteres)
{
        while (*s_caracteres!=0)
        {
                lcd_escreve_dado(*s_caracteres);
                s_caracteres++;
        }
}

//Envia uma matriz de dados para o Display LCD.
void imprime_buffer_lcd( char *s_caracteres, unsigned char tamanho_buffer)
{
        while (tamanho_buffer--)
        {
                lcd_escreve_dado(*s_caracteres);
                s_caracteres++;
        }
}

//Inicializa o display LCD alfanumérico.
void lcd_inicia( unsigned char conf1, unsigned char conf2, unsigned char conf3)
{
/*
Configuração do display LCD:

(0x28)
- Comunicação 4 vias
- Display com 2 linhas
- Matriz 8x5

(0x0C)
- Liga display
- Cursor piscante

(0x06)
- Desloca o cursor para a direita quando um caractere for inserido.
*/
unsigned char config_LCD[6] = {0x03, 0x02, 0x00, 0x00, 0x00};
unsigned char repeticao;

config_LCD[2] = conf1;
config_LCD[3] = conf2;
config_LCD[4] = conf3;

//Configura os pinos de dados/controle, como saída.
S_B7;
S_B6;
S_B5;
S_B4;
S_E;
//S_RW;
S_RS;

RS = 0; //Instrução.
//RW = 0; //Escrita.
E = 0; //Desabilita LCD.

        gera_atraso_us(20000); //Gera um atraso de 20ms.

        for( repeticao = 0 ; repeticao < 3 ; repeticao++ )
        {
                B7 = config_LCD[0]>>3; //B7 recebe o bit 3 do elemento presente na posição 0 da matriz config_LCD.
                B6 = config_LCD[0]>>2; //B6 recebe o bit 2 do elemento presente na posição 0 da matriz config_LCD.
                B5 = config_LCD[0]>>1; //B5 recebe o bit 1 do elemento presente na posição 0 da matriz config_LCD.
                B4 = config_LCD[0];    //B4 recebe o bit 0 do elemento presente na posição 0 da matriz config_LCD.

                E = 1;//Habilita o Display LCD.
                gera_atraso_us(2); //Gera um delay de 2us.
                E = 0; //Desabilita o Display LCD.

                gera_atraso_us(5000); //Gera um delay de 5ms.
        }

B7 = config_LCD[1]>>3; //B7 recebe o bit 3 do elemento presente na posição 1 da matriz config_LCD.
B6 = config_LCD[1]>>2; //B6 recebe o bit 2 do elemento presente na posição 1 da matriz config_LCD.
B5 = config_LCD[1]>>1; //B5 recebe o bit 1 do elemento presente na posição 1 da matriz config_LCD.
B4 = config_LCD[1];    //B4 recebe o bit 0 do elemento presente na posição 1 da matriz config_LCD.

E = 1;//Habilita o Display LCD.
gera_atraso_us(2); //Gera um delay de 2us.
E = 0; //Desabilita o Display LCD.

gera_atraso_us(40); //Gera um delay de 40us.

lcd_envia_controle (0,0,config_LCD[2],40);
lcd_envia_controle (0,0,config_LCD[3],40);
lcd_envia_controle (0,0,config_LCD[4],40);

lcd_limpa_tela ( );

}
    
pregunta Leonardo Reinoso

1 respuesta

-1

Disculpe la demora, pero el problema se resolvió, los errores se debieron a las funciones de demora y algunos se enviaron comandos incorrectos a la pantalla, gracias.

    
respondido por el Leonardo Reinoso

Lea otras preguntas en las etiquetas