Escrever em LCD por apenas 4 vias em C (RESOLVIDO)

Software e Hardware para uC PIC

Moderadores: andre_luis, 51, guest2003, Renie

Escrever em LCD por apenas 4 vias em C (RESOLVIDO)

Mensagempor valecovo » 13 Jan 2014 16:57

Olá
Estou a chegar ao Forum. Não sei se é necessário fazer a apresentação. Se for, por favor me digam.

Estou a usar o compilador PCW-CCS e o ISIS 7.8SP2 e não consigo escrever no LCD. Não sai nada. Já experimentei de várias formas, mas por 4 vias de dados não consigo.

Imagem do ISIS:

Imagem

Codigo usado:
Código: Selecionar todos
#include <16F877A.h>
#device adc=16

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES XT                       //High speed Osc (> 4mhz for PCM/PCH) (>10mhz for PCD)
#FUSES PUT                      //Power Up Timer
#FUSES NOBROWNOUT               //No brownout reset
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD                    //No EE protection
#FUSES NOWRT                    //Program memory not write protected
#FUSES NODEBUG                  //No Debug mode for ICD
#FUSES NOPROTECT                //Code not protected from reading

#use delay(clock=4000000)

#include <lcd.c>

#define RS_PIN pin_D0
#define RW_PIN pin_D1
#define ENABLE_PIN pin_D2
#define Data4 pin_D4
#define Data5 pin_D5
#define Data6 pin_D6
#define Data7 pin_D7

//#include <lcd.c>

int i=0;

void main()
{
   lcd_init();   // inicializa LCD
   while(true)    // Loop infinito
      {
      //if(input(pin_a0)==1)    // Se a chave do pino RA0 estiver em 1
      if(i==0)
         {
         //lcd_gotoxy(1,1);     // Escreve na 1ª coluna 1ª linha
         lcd_putc("\n Teste");     // imprime LIGADO
        // delay_ms(10);
         }
      else                                // Senão
         {
         //lcd_gotoxy(1,1);                 // Escreve na 4ª coluna 1ª linha
         //printf(lcd_putc, " DESLIGADO");  // Imprime DESLIGADO
         lcd_putc("\n\r DESLIGADO");  // Imprime DESLIGADO
         }
      }

}
Editado pela última vez por valecovo em 17 Fev 2014 17:38, em um total de 1 vez.
valecovo
Bit
 
Mensagens: 23
Registrado em: 13 Jan 2014 16:49

Re: Escrever em LCD por apenas 4 vias em C

Mensagempor xultz » 13 Jan 2014 18:53

Olá, Valecovo, se apresentar não é uma exigência, mas é recomendado :)

No teu código você comentou a inclusão da biblioteca lcd.c, sem ela não vai dar certo. Mesmo incluindo esta biblioteca, seria interessante você colar o código dela aqui também prá poder fazer algumas verificações. Amanhã eu colo um código que utilizo e funciona bunitinho.
98% das vezes estou certo, e não estou nem aí pros outros 3%.
Avatar do usuário
xultz
Dword
 
Mensagens: 3001
Registrado em: 13 Out 2006 18:41
Localização: Curitiba

Re: Escrever em LCD por apenas 4 vias em C

Mensagempor andre_luis » 13 Jan 2014 19:01

valecovo,


Quanto ao circuito, o primeiro problema que observei foi a ausencia da alimentação e do contraste no LCD.
Já no programa, não vi nenhuma menção á configuração da interface com o LCD, se é 4 ou 8bits, mas talvez o primeiro seja default.

No mais, tenta substituir essa imagem por outra maior...



+++
"Por maior que seja o buraco em que você se encontra, relaxe, porque ainda não há terra em cima."
Avatar do usuário
andre_luis
Dword
 
Mensagens: 5447
Registrado em: 11 Out 2006 18:27
Localização: Brasil - RJ

Re: Escrever em LCD por apenas 4 vias em C

Mensagempor Moreto » 14 Jan 2014 12:32

Olha, quando eu comecei a usar o LCD, esse post aqui me ajudou bastante.... http://www.marcelomaciel.com/2012/03/co ... o-pic.html
Lá vai explicar melhor o funcionamento do LCD, para até se você quiser criar as rotinas de utilização do LCD você mesmo.
Moreto
Bit
 
Mensagens: 18
Registrado em: 04 Jul 2013 11:09

Re: Escrever em LCD por apenas 4 vias em C

Mensagempor tcpipchip » 14 Jan 2014 13:34

------------------------------------------
http://www.youtube.com/tcpipchip
Avatar do usuário
tcpipchip
Dword
 
Mensagens: 6560
Registrado em: 11 Out 2006 22:32
Localização: TCPIPCHIPizinho!

Re: Escrever em LCD por apenas 4 vias em C

Mensagempor valecovo » 14 Jan 2014 16:30

"xultz"
No código existe uma biblioteca de LCD comentada e outra sem estar comentada.
Vou colar o código da biblioteca de LCD.

"andre_teprom"
Para simular no ISIS não necessita da alimentação e do contraste no LCD.
Quanto à configuração da interface com o LCD, se é 4 ou 8bits, não sei como se faz. Estou a iniciar agora e há pormenores que ainda me escapam.

"Moreto"
Já tinha andado pela pagina do marcelo e já tentei fazer alguns testes baseados nesta informação, mas também não saiu nada.

"tcpipchip"
Já visitei o link. É bastante interessante para quem está a iniciar. Vou aprender alguma coisa ali.


Aqui fica o código da biblioteca LCD do compilador PCW-CCS que estou a usar.
Código: Selecionar todos
///////////////////////////////////////////////////////////////////////////////
////                             LCD.C                                     ////
////                 Driver for common LCD modules                         ////
////                                                                       ////
////  lcd_init()   Must be called before any other function.               ////
////                                                                       ////
////  lcd_putc(c)  Will display c on the next position of the LCD.         ////
////                 \a  Set cursor position to upper left                 ////
////                 \f  Clear display, set cursor to upper left           ////
////                 \n  Go to start of second line                        ////
////                 \b  Move back one position                            ////
////              If LCD_EXTENDED_NEWLINE is defined, the \n character     ////
////              will erase all remanining characters on the current      ////
////              line, and move the cursor to the beginning of the next   ////
////              line.                                                    ////
////              If LCD_EXTENDED_NEWLINE is defined, the \r character     ////
////              will move the cursor to the start of the current         ////
////              line.                                                    ////
////                                                                       ////
////  lcd_gotoxy(x,y) Set write position on LCD (upper left is 1,1)        ////
////                                                                       ////
////  lcd_getc(x,y)   Returns character at position x,y on LCD             ////
////                                                                       ////
////  CONFIGURATION                                                        ////
////  The LCD can be configured in one of two ways: a.) port access or     ////
////  b.) pin access.  Port access requires the entire 7 bit interface     ////
////  connected to one GPIO port, and the data bits (D4:D7 of the LCD)     ////
////  connected to sequential pins on the GPIO.  Pin access                ////
////  has no requirements, all 7 bits of the control interface can         ////
////  can be connected to any GPIO using several ports.                    ////
////                                                                       ////
////  To use port access, #define LCD_DATA_PORT to the SFR location of     ////
////  of the GPIO port that holds the interface, -AND- edit LCD_PIN_MAP    ////
////  of this file to configure the pin order.  If you are using a         ////
////  baseline PIC (PCB), then LCD_OUTPUT_MAP and LCD_INPUT_MAP also must  ////
////  be defined.                                                          ////
////                                                                       ////
////  Example of port access:                                              ////
////     #define LCD_DATA_PORT getenv("SFR:PORTD")                         ////
////                                                                       ////
////  To use pin access, the following pins must be defined:               ////
////     LCD_ENABLE_PIN                                                    ////
////     LCD_RS_PIN                                                        ////
////     LCD_RW_PIN                                                        ////
////     LCD_DATA4                                                         ////
////     LCD_DATA5                                                         ////
////     LCD_DATA6                                                         ////
////     LCD_DATA7                                                         ////
////                                                                       ////
////  Example of pin access:                                               ////
////     #define LCD_ENABLE_PIN  PIN_E0                                    ////
////     #define LCD_RS_PIN      PIN_E1                                    ////
////     #define LCD_RW_PIN      PIN_E2                                    ////
////     #define LCD_DATA4       PIN_D4                                    ////
////     #define LCD_DATA5       PIN_D5                                    ////
////     #define LCD_DATA6       PIN_D6                                    ////
////     #define LCD_DATA7       PIN_D7                                    ////
////                                                                       ////
///////////////////////////////////////////////////////////////////////////////
////        (C) Copyright 1996,2010 Custom Computer Services           ////
//// This source code may only be used by licensed users of the CCS C  ////
//// compiler.  This source code may only be distributed to other      ////
//// licensed users of the CCS C compiler.  No other use, reproduction ////
//// or distribution is permitted without written permission.          ////
//// Derivative programs created using this software in object code    ////
//// form are not restricted in any way.                               ////
///////////////////////////////////////////////////////////////////////////

// define the pinout.
// only required if port access is being used.
typedef struct 
{                            // This structure is overlayed
   BOOLEAN enable;           // on to an I/O port to gain
   BOOLEAN rs;               // access to the LCD pins.
   BOOLEAN rw;               // The bits are allocated from
   BOOLEAN unused;           // low order up.  ENABLE will
   int     data : 4;         // be LSB pin of that port.
  #if defined(__PCD__)       // The port used will be LCD_DATA_PORT.
   int    reserved: 8;
  #endif
} LCD_PIN_MAP;

// this is to improve compatability with previous LCD drivers that accepted
// a define labeled 'use_portb_lcd' that configured the LCD onto port B.
#if ((defined(use_portb_lcd)) && (use_portb_lcd==TRUE))
 #define LCD_DATA_PORT getenv("SFR:PORTB")
#endif

#if defined(__PCB__)
   // these definitions only need to be modified for baseline PICs.
   // all other PICs use LCD_PIN_MAP or individual LCD_xxx pin definitions.
/*                                    EN, RS,   RW,   UNUSED,  DATA  */
 const LCD_PIN_MAP LCD_OUTPUT_MAP =  {0,  0,    0,    0,       0};
 const LCD_PIN_MAP LCD_INPUT_MAP =   {0,  0,    0,    0,       0xF};
#endif

////////////////////// END CONFIGURATION ///////////////////////////////////

#ifndef LCD_ENABLE_PIN
   #define lcd_output_enable(x) lcdlat.enable=x
   #define lcd_enable_tris()   lcdtris.enable=0
#else
   #define lcd_output_enable(x) output_bit(LCD_ENABLE_PIN, x)
   #define lcd_enable_tris()  output_drive(LCD_ENABLE_PIN)
#endif

#ifndef LCD_RS_PIN
   #define lcd_output_rs(x) lcdlat.rs=x
   #define lcd_rs_tris()   lcdtris.rs=0
#else
   #define lcd_output_rs(x) output_bit(LCD_RS_PIN, x)
   #define lcd_rs_tris()  output_drive(LCD_RS_PIN)
#endif

#ifndef LCD_RW_PIN
   #define lcd_output_rw(x) lcdlat.rw=x
   #define lcd_rw_tris()   lcdtris.rw=0
#else
   #define lcd_output_rw(x) output_bit(LCD_RW_PIN, x)
   #define lcd_rw_tris()  output_drive(LCD_RW_PIN)
#endif

// original version of this library incorrectly labeled LCD_DATA0 as LCD_DATA4,
// LCD_DATA1 as LCD_DATA5, and so on.  this block of code makes the driver
// compatible with any code written for the original library
#if (defined(LCD_DATA0) && defined(LCD_DATA1) && defined(LCD_DATA2) && defined(LCD_DATA3) && !defined(LCD_DATA4) && !defined(LCD_DATA5) && !defined(LCD_DATA6) && !defined(LCD_DATA7))
   #define  LCD_DATA4    LCD_DATA0
   #define  LCD_DATA5    LCD_DATA1
   #define  LCD_DATA6    LCD_DATA2
   #define  LCD_DATA7    LCD_DATA3
#endif

#ifndef LCD_DATA4
#ifndef LCD_DATA_PORT
   #if defined(__PCB__)
      #define LCD_DATA_PORT      0x06     //portb
      #define set_tris_lcd(x)   set_tris_b(x)
   #else
     #if defined(PIN_D0)
      #define LCD_DATA_PORT      getenv("SFR:PORTD")     //portd
     #else
      #define LCD_DATA_PORT      getenv("SFR:PORTB")     //portb
     #endif
   #endif   
#endif

#if defined(__PCB__)
   LCD_PIN_MAP lcd, lcdlat;
   #byte lcd = LCD_DATA_PORT
   #byte lcdlat = LCD_DATA_PORT
#elif defined(__PCM__)
   LCD_PIN_MAP lcd, lcdlat, lcdtris;
   #byte lcd = LCD_DATA_PORT
   #byte lcdlat = LCD_DATA_PORT
   #byte lcdtris = LCD_DATA_PORT+0x80
#elif defined(__PCH__)
   LCD_PIN_MAP lcd, lcdlat, lcdtris;
   #byte lcd = LCD_DATA_PORT
   #byte lcdlat = LCD_DATA_PORT+9
   #byte lcdtris = LCD_DATA_PORT+0x12
#elif defined(__PCD__)
   LCD_PIN_MAP lcd, lcdlat, lcdtris;
   #word lcd = LCD_DATA_PORT
   #word lcdlat = LCD_DATA_PORT+2
   #word lcdtris = LCD_DATA_PORT-0x02
#endif
#endif   //LCD_DATA4 not defined

#ifndef LCD_TYPE
   #define LCD_TYPE 2           // 0=5x7, 1=5x10, 2=2 lines
#endif

#ifndef LCD_LINE_TWO
   #define LCD_LINE_TWO 0x40    // LCD RAM address for the second line
#endif

#ifndef LCD_LINE_LENGTH
   #define LCD_LINE_LENGTH 20
#endif

BYTE const LCD_INIT_STRING[4] = {0x20 | (LCD_TYPE << 2), 0xc, 1, 6};
                             // These bytes need to be sent to the LCD
                             // to start it up.

BYTE lcd_read_nibble(void);

BYTE lcd_read_byte(void)
{
   BYTE low,high;

 #if defined(__PCB__)
   set_tris_lcd(LCD_INPUT_MAP);
 #else
  #if (defined(LCD_DATA4) && defined(LCD_DATA5) && defined(LCD_DATA6) && defined(LCD_DATA7))
   output_float(LCD_DATA4);
   output_float(LCD_DATA5);
   output_float(LCD_DATA6);
   output_float(LCD_DATA7);
  #else
   lcdtris.data = 0xF;
  #endif
 #endif
       
   lcd_output_rw(1);
   delay_cycles(1);
   lcd_output_enable(1);
   delay_cycles(1);
   high = lcd_read_nibble();
     
   lcd_output_enable(0);
   delay_cycles(1);
   lcd_output_enable(1);
   delay_us(1);
   low = lcd_read_nibble();
     
   lcd_output_enable(0);

 #if defined(__PCB__)
   set_tris_lcd(LCD_OUTPUT_MAP);
 #else
  #if (defined(LCD_DATA4) && defined(LCD_DATA5) && defined(LCD_DATA6) && defined(LCD_DATA7))
   output_drive(LCD_DATA4);
   output_drive(LCD_DATA5);
   output_drive(LCD_DATA6);
   output_drive(LCD_DATA7);
  #else
   lcdtris.data = 0x0;
  #endif
 #endif

   return( (high<<4) | low);
}

BYTE lcd_read_nibble(void)
{
  #if (defined(LCD_DATA4) && defined(LCD_DATA5) && defined(LCD_DATA6) && defined(LCD_DATA7))
   BYTE n = 0x00;

   /* Read the data port */
   n |= input(LCD_DATA4);
   n |= input(LCD_DATA5) << 1;
   n |= input(LCD_DATA6) << 2;
   n |= input(LCD_DATA7) << 3;
   
   return(n);
  #else
   return(lcd.data);
  #endif
}

void lcd_send_nibble(BYTE n)
{
  #if (defined(LCD_DATA4) && defined(LCD_DATA5) && defined(LCD_DATA6) && defined(LCD_DATA7))
   /* Write to the data port */
   output_bit(LCD_DATA4, bit_test(n, 0));
   output_bit(LCD_DATA5, bit_test(n, 1));
   output_bit(LCD_DATA6, bit_test(n, 2));
   output_bit(LCD_DATA7, bit_test(n, 3));
  #else     
   lcdlat.data = n;
  #endif
     
   delay_cycles(1);
   lcd_output_enable(1);
   delay_us(2);
   lcd_output_enable(0);
}

void lcd_send_byte(BYTE address, BYTE n)
{
  #if defined(__PCB__)
   set_tris_lcd(LCD_OUTPUT_MAP);
  #else
   lcd_enable_tris();
   lcd_rs_tris();
   lcd_rw_tris();
  #endif

   lcd_output_rs(0);
   while ( bit_test(lcd_read_byte(),7) ) ;
   lcd_output_rs(address);
   delay_cycles(1);
   lcd_output_rw(0);
   delay_cycles(1);
   lcd_output_enable(0);
   lcd_send_nibble(n >> 4);
   lcd_send_nibble(n & 0xf);
}

#if defined(LCD_EXTENDED_NEWLINE)
unsigned int8 g_LcdX, g_LcdY;
#endif

void lcd_init(void)
{
   BYTE i;

 #if defined(__PCB__)
   set_tris_lcd(LCD_OUTPUT_MAP);
 #else
  #if (defined(LCD_DATA4) && defined(LCD_DATA5) && defined(LCD_DATA6) && defined(LCD_DATA7))
   output_drive(LCD_DATA4);
   output_drive(LCD_DATA5);
   output_drive(LCD_DATA6);
   output_drive(LCD_DATA7);
  #else
   lcdtris.data = 0x0;
  #endif
   lcd_enable_tris();
   lcd_rs_tris();
   lcd_rw_tris();
 #endif

   lcd_output_rs(0);
   lcd_output_rw(0);
   lcd_output_enable(0);
   
   delay_ms(15);
   for(i=1;i<=3;++i)
   {
       lcd_send_nibble(3);
       lcd_send_nibble(0);
       delay_ms(5);
   }
   
   lcd_send_nibble(2);
   lcd_send_nibble(0);
   delay_ms(5);
   for(i=0;i<=3;++i)
      lcd_send_byte(0,LCD_INIT_STRING[i]);

  #if defined(LCD_EXTENDED_NEWLINE)
   g_LcdX = 0;
   g_LcdY = 0;
  #endif
}

void lcd_gotoxy(BYTE x, BYTE y)
{
   BYTE address;
   
   if(y!=1)
      address=LCD_LINE_TWO;
   else
      address=0;
     
   address+=x-1;
   lcd_send_byte(0,0x80|address);

  #if defined(LCD_EXTENDED_NEWLINE)
   g_LcdX = x - 1;
   g_LcdY = y - 1;
  #endif
}

void lcd_putc(char c)
{
   switch (c)
   {
      case '\a'   :  lcd_gotoxy(1,1);     break;

      case '\f'   :  lcd_send_byte(0,1);
                     delay_ms(2);
                    #if defined(LCD_EXTENDED_NEWLINE)
                     g_LcdX = 0;
                     g_LcdY = 0;
                    #endif
                     break;

     #if defined(LCD_EXTENDED_NEWLINE)
      case '\r'   :  lcd_gotoxy(1, g_LcdY+1);   break;
      case '\n'   :
         while (g_LcdX++ < LCD_LINE_LENGTH)
         {
            lcd_send_byte(1, ' ');
         }
         lcd_gotoxy(1, g_LcdY+2);
         break;
     #else
      case '\n'   : lcd_gotoxy(1,2);        break;
     #endif
     
      case '\b'   : lcd_send_byte(0,0x10);  break;
     
     #if defined(LCD_EXTENDED_NEWLINE)
      default     :
         if (g_LcdX < LCD_LINE_LENGTH)
         {
            lcd_send_byte(1, c);
            g_LcdX++;
         }
         break;
     #else
      default     : lcd_send_byte(1,c);     break;
     #endif
   }
}
 
char lcd_getc(BYTE x, BYTE y)
{
   char value;

   lcd_gotoxy(x,y);
   while ( bit_test(lcd_read_byte(),7) ); // wait until busy flag is low
   lcd_output_rs(1);
   value = lcd_read_byte();
   lcd_output_rs(0);
   
   return(value);
}
valecovo
Bit
 
Mensagens: 23
Registrado em: 13 Jan 2014 16:49

Re: Escrever em LCD por apenas 4 vias em C

Mensagempor valecovo » 14 Jan 2014 17:38

Bom, já consegui fazer o exemplo constante no link
http://www.marcelomaciel.com/2012/03/co ... o-pic.html

Porém, tentei criar uma biblioteca à parte com o código do LCD, mas assim não consigo escrever.

Outra coisa que não consigo é escrever números. Alguém me ajuda, já agora.

Obrigado.
valecovo
Bit
 
Mensagens: 23
Registrado em: 13 Jan 2014 16:49

Re: Escrever em LCD por apenas 4 vias em C

Mensagempor andre_luis » 14 Jan 2014 18:33

valecovo escreveu:Bom, já consegui fazer o exemplo constante no link.
Porém, tentei criar uma biblioteca à parte com o código do LCD, mas assim não consigo escrever.


Pra mim não ficou claro se não consegiu executar o programa do exemplo, ou se o problema está fazer funcionar á parte numa biblioteca.
Passa mais alguns detalhes...

+++
"Por maior que seja o buraco em que você se encontra, relaxe, porque ainda não há terra em cima."
Avatar do usuário
andre_luis
Dword
 
Mensagens: 5447
Registrado em: 11 Out 2006 18:27
Localização: Brasil - RJ

Re: Escrever em LCD por apenas 4 vias em C

Mensagempor ÁgioFelipe » 15 Jan 2014 09:17

Só complementando, para simular LCD no proteus não precisa de alimentação nem contraste.
ÁgioFelipe
Word
 
Mensagens: 626
Registrado em: 27 Out 2006 20:04

Re: Escrever em LCD por apenas 4 vias em C

Mensagempor valecovo » 15 Jan 2014 18:48

Com este código escreve no display utilizando só 4 vias de dados. Porém, há duas coisas que não consigo fazer:
1ª - Escrever na 2ª. linha. A função existente para esse fim parece não funcionar.
2ª - Escrever no LCD separando o código destinado ao LCD para um ficheiro à parte.

Código: Selecionar todos
// Exemplo http://www.marcelomaciel.com/2012/03/configuracao-display-lcd-no-pic.html
#include <LCD07.h>


/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* CONSTANTES INTERNAS *
* * * * * * * * * * *  * * * * * * * * * * * * * * * * * * * * * */

// 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_d1     // pino enable do LCD
#define lcd_rs pin_d0         // pino rs (register select)do LCD
                              // (0) para comandos (1) para dados
#define lcd_db4 pin_d4        // pino de dados d4 do LCD
#define lcd_db5 pin_d5        // pino de dados d5 do LCD
#define lcd_db6 pin_d6        // pino de dados d6 do LCD
#define lcd_db7 pin_d7        // pino de dados d7 do LCD

/* * * * * * * * * * * *  * * * * * * * * * * * * *
* DEFINIÇÃO E INICIALIZAÇÃO DOS PORTS *
* * * * * * * * * * * * * * * * * * * * * * * * * */

#byte porta = 0x05
#byte portb = 0x06
#byte portc = 0x07
#byte portd = 0x08
#byte porte = 0x09


/* * * * * * * *  * * * * * * * * * * * * * * * * * * * * * * * * * * *
* ENVIO DE NIBBLE PARA O LCD *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

//Esta rotina lê o "Nibble" inferior de uma variável e envia para o LCD.
//1byte = 8 bits = 2 Nibbles. Serão enviados para os pinos db4, db5, db6, db7 do 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
}


/* * * * * * * * * * *  * * * * * * * * * * * * * * * * * * *
* 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 CARACTER PARA O LCD *
* * * * * * * * * * * * * *  * * * * * * * * * * * * * * * */

// Esta rotina serve apenas como uma forma mais fácil de escrever um caractere no display.

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
      // 0 - envio de instrução. 0X01 - mostrar tabela
   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(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,0x20); // FUNCTION SET - Configura o LCD para
                           //4 bits, 1 linha, fonte 5X7.
                           // 0 - envio de instrução 0x20 - mostrar tabela
   envia_byte_lcd(0,0x0C); // DISPLAY CONTROL - Display ligado, sem cursor
                           // 0 - envio de instrução 0x0C - mostrar tabela
   limpa_lcd();            // Limpa o LCD
   envia_byte_lcd(0,0x06); // ENTRY MODE SET - A cada caracter, incrementa uma posição
                           // 0 - envio de instrução 0x06 - mostrar tabela
   return;                 // Retorna ao ponto de chamada da função
}

// 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;
}

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* CONFIGURAÇÕES DO PIC *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

void main()
{
   int16 i=0;
   int n=0;
   set_tris_a(0xFF);  // configura os tris. configuração da direção dos pinos de I/O
   set_tris_b(0xFF);
   set_tris_c(0xFF);
   set_tris_d(0xFF);
   set_tris_e(0xFF);
   
   porta = 0;  // Reseta portas
   portb = 0;
   portc = 0;
   portd = 0;
   porte = 0;

   inicializa_lcd();    // Inicializa o LCD

   escreve_lcd("O");    //Escreve tela
   escreve_lcd("L");
   escreve_lcd("A ");
   escreve_lcd("M");
   escreve_lcd("U");
   escreve_lcd("N");
   escreve_lcd("D");
   escreve_lcd("O");
   escreve_lcd("!");
   DELAY_MS(1000);
   //printf(escreve_lcd,"");

   /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
   * ROTINA PRINCIPAL *
   * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

   // Como não há outra execução, a rotina principal fica vazia
   while(true)
   { 
      if(input(pin_a0)==1)
      {
         i++;
         while(input(pin_a0)==1);
         if(i==1)
         {
            limpa_lcd();            // Limpa o LCD
            //comando_lcd(0x0E); 
            //envia_byte_lcd(0,0x0B);  // Display em branco
            //envia_byte_lcd(0,0x0C);  // Sem cursor
            //envia_byte_lcd(0,0x0D);  // Cursor fixo
            //envia_byte_lcd(0,0x0E);  // Cursor fixo
            //envia_byte_lcd(0,0x0F);  // Cursor piscando
            //caracter_inicio(1,1);   // Deveria posicionar na linha 1, coluna 0
            printf(escreve_lcd,"jose");
         }
          if(i==2)
         {
            limpa_lcd();            // Limpa o LCD
            caracter_inicio(1,1);   // Deveria posicionar na linha 2, coluna 1
            printf(escreve_lcd,"silva");
         }
          if(i>=3)
         {
            limpa_lcd();            // Limpa o LCD
            caracter_inicio(1,4);   // Deveria posicionar na linha 1, coluna 4
            printf(escreve_lcd,"%2Lu",i);
         }
         /*
         printf(lcd_putc,”/n “);  //pula para a segunda linha do display
         printf(lcd_putc,”/f “);   //limpa o display
         printf(lcd_putc,”/b “);  //apaga caractere em que está posicionado o cursor
         */
      }
     }
   

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* FIM DO PROGRAMA
* * * * * * * * * * * * *  * * * * * * * * * * * * * * * * * * ***/
}



Separei o código destinado ao LCD para um ficheiro à parte e ficou como abaixo. Compila bem, mas não escreve no LCD. Não sei o que se passa:
Código: Selecionar todos
// Conteudo do arquivo "MyLCD.h", criado em 14-01-2014 por José Silva:

// 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_d1       // pino enable do LCD
#define lcd_rs pin_d0           // pino rs (register select)do LCD
                                                                  // (0) para comandos (1) para dados
#define lcd_db4 pin_d4          // pino de dados d4 do LCD
#define lcd_db5 pin_d5          // pino de dados d5 do LCD
#define lcd_db6 pin_d6          // pino de dados d6 do LCD
#define lcd_db7 pin_d7          // pino de dados d7 do LCD

/* * * * * * * * * * * *  * * * * * * * * * * * * *
* DEFINIÇÃO E INICIALIZAÇÃO DOS PORTS *
* * * * * * * * * * * * * * * * * * * * * * * * * */

#byte porta = 0x05
#byte portb = 0x06
#byte portc = 0x07
#byte portd = 0x08
#byte porte = 0x09

/***************************************************************************/
/* 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 LCDenvia_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 */
/***************************************************************************/
valecovo
Bit
 
Mensagens: 23
Registrado em: 13 Jan 2014 16:49

Re: Escrever em LCD por apenas 4 vias em C

Mensagempor andre_luis » 15 Jan 2014 19:16

valecovo escreveu:Com este código escreve no display utilizando só 4 vias de dados. Porém, há duas coisas que não consigo fazer:1ª - Escrever na 2ª. linha. A função existente para esse fim parece não funcionar.

Olha, eu não sei se você postou o código que funciona, ou o que deveria funcionar, mas nele apenas a linha 1 é acessada.
Código: Selecionar todos
caracter_inicio(1,x);

valecovo escreveu:...2ª - Escrever no LCD separando o código destinado ao LCD para um ficheiro à parte...

Qual é a versão do seu CCS ? Se for 3.xxx talvez eu possa ajudar.
Se possível, tenta passar seu projeto zipado...


+++
"Por maior que seja o buraco em que você se encontra, relaxe, porque ainda não há terra em cima."
Avatar do usuário
andre_luis
Dword
 
Mensagens: 5447
Registrado em: 11 Out 2006 18:27
Localização: Brasil - RJ

Re: Escrever em LCD por apenas 4 vias em C

Mensagempor valecovo » 15 Jan 2014 20:17

O primeiro código postado tem incluído o código para o LCD e funciona. o Segundo código postado foi o código que separei para criar uma biblioteca à parte, mas assim não consigo fazer com que escreva no LCD, embora faça a sua inclusão no cabeçalho do ficheiro do programa. Não sei se está a perceber!

Escrever na 2ª. linha está resolvido: o display estava configurado apenas para escrever na primeira linha "envia_byte_lcd(0,0x20)". Configurei para "envia_byte_lcd(0,0x28)" e já escreve na segunda.

A versão do PCW-CCS é: 4.114
valecovo
Bit
 
Mensagens: 23
Registrado em: 13 Jan 2014 16:49

Re: Escrever em LCD por apenas 4 vias em C

Mensagempor andre_luis » 16 Jan 2014 20:56

valecovo,

O segundo programa que voce postou acima ( o drive do display ), não vi problemas, e parece correto para ser utilizado como biblioteca.
Entretanto, no primeiro programa você teria de remover todas as definições de funções, e substituir apenas pelo seu protótipo, pois estão duplicadas.

Veja no trecho abaixo, que antes do main(), teria apenas isso mostrado abaixo:

Código: Selecionar todos
    #include <LCD07.h>

    void envia_nibble_lcd(int dado)               ;
    void envia_byte_lcd(boolean endereco, int dado)       ;
    void escreve_lcd(char c)                   ;
    void limpa_lcd()                         ;
    void inicializa_lcd()                      ;
    void caracter_inicio(int linha, int coluna)          ;

    /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
    * CONFIGURAÇÕES DO PIC *
    * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
    void main()
    {



+++
"Por maior que seja o buraco em que você se encontra, relaxe, porque ainda não há terra em cima."
Avatar do usuário
andre_luis
Dword
 
Mensagens: 5447
Registrado em: 11 Out 2006 18:27
Localização: Brasil - RJ

Re: Escrever em LCD por apenas 4 vias em C (RESOLVIDO)

Mensagempor valecovo » 17 Fev 2014 17:39

Obrigado a todos. Já consegui resolver o problema. Pequenos pormenores de principiante........
valecovo
Bit
 
Mensagens: 23
Registrado em: 13 Jan 2014 16:49


Voltar para PIC

Quem está online

Usuários navegando neste fórum: Google [Bot] e 1 visitante

x