LCD 4X20 (A SAGA)

Software e Hardware para uC PIC

Moderadores: andre_luis, 51, guest2003, Renie

LCD 4X20 (A SAGA)

Mensagempor jandom » 12 Jun 2009 00:10

CAROS COLEGAS, ESTOU COM DIFICULDADES DE FAZER FUNCIONAR UM DISPLAY 4X20 COM PIC, POIS TODOS OS PROGRAMAS QUE CONSEGUI NÃO FUNCIONAM DIREITO, QUANDO NÃO DEIXA LENTA A AMOSTRAGEM, NÃO FUNCIONA QUANDO PRECISO MOSTRAR O VALOR DE UMA VARIAVEL.

ESTOU USANDO ESTE MODIFICADO DO FABIO PEREIRA:
USO CCS.

//******************************************************************************
//* MOD_LCD2.C - Biblioteca de manipulação de módulo LCD
//*
//* Modificado por Márcio José Soares para compatibilizar com 16F628
//* do original de Fábio Pereira - Pic Programação em C - Editora Erica
//* Atende agora também quatro tipos de displays
//******************************************************************************

//******************************************************************************
/* endereços para linhas dos display's possíveis para este
módulo:

Display 1ª linha 2ª linha 3ª linha 4ª linha
16 x 2 80H C0H XX XX
16 x 4 80H C0H 94H D4H
20 x 4 80H C0H 90H D0H
40 x 2 80H C0H XX XX

*/
//******************************************************************************

//******************************************************************************
// Arquivos incluídos
//******************************************************************************
#include "mod_lcd2.h"

//******************************************************************************
// Funções do módulo
//******************************************************************************

//******************************************************************************
// Função para enviar nibble para o display
// envia um dado de quatro bits para o display
// recebe - byte a enviar
// retorna - nada
//******************************************************************************
void lcd_envia_nibble( byte dado )
{
// coloca os quatro bits nas saidas
output_bit(lcd_d4,bit_test(dado,0));
output_bit(lcd_d5,bit_test(dado,1));
output_bit(lcd_d6,bit_test(dado,2));
output_bit(lcd_d7,bit_test(dado,3));

// dá um pulso na linha enable
output_high(lcd_enable);
output_low(lcd_enable);
}

//******************************************************************************
// Função para enviar dados para o display
// recebe - endereço -> 0 - comando, 1 dado
// dado
// retorna - nada
//******************************************************************************
void lcd_envia_byte( boolean endereco, byte dado )
{
// coloca a linha rs em 0
output_low(lcd_rs);
// aguarda o display ficar desocupado
//while ( bit_test(lcd_le_byte(),7) ) ;
// configura a linha rs dependendo do modo selecionado
output_bit(lcd_rs,endereco);
delay_us(100); // aguarda 100 us
// caso a linha rw esteja definida, coloca em 0
#ifdef lcd_rw
output_low(lcd_rw);
#endif
// desativa linha enable
output_low(lcd_enable);
// envia a primeira parte do byte
lcd_envia_nibble(dado >> 4);
// envia a segunda parte do byte
lcd_envia_nibble(dado & 0x0f);
}

//******************************************************************************
// Função para inicializar o display
// recebe - nada
// retorna - nada
//******************************************************************************
void lcd_ini()
// rotina de inicialização do display
{
byte conta;
output_low(lcd_d4);
output_low(lcd_d5);
output_low(lcd_d6);
output_low(lcd_d7);
output_low(lcd_rs);
#ifdef lcd_rw
output_high(lcd_rw);
#endif
output_low(lcd_enable);
delay_ms(15);
// envia uma seqüência de 3 vezes 0x03
// e depois 0x02 para configurar o módulo
// para modo de 4 bits
for(conta=1;conta<=3;++conta)
{
lcd_envia_nibble(3);
delay_ms(5);
}
lcd_envia_nibble(2);
// envia string de inicialização do display
for(conta=0;conta<=3;++conta) lcd_envia_byte(0,INI_LCD[conta]);
}

//******************************************************************************
// Função para mudar a linha no display
// implementada por Márcio José Soares
// para alterar a linha de trabalho de um lcd
// com mais de uma linha.
// recebe:
// byte x = display utilizado
// 0 -> 16 x 2
// 1 -> 20 x 4
// 2 -> 16 x 4
// 3 -> 40 x 2
//
// byte y = número da linha a pular
//
// retorna - nada
//******************************************************************************
byte lcd_muda_linha(byte x, byte y)

{
byte endereco, ret;
if(y==1){
endereco = lcd_prim_lin;
ret = 1;
}
else if(y==2){
endereco = lcd_seg_lin;
ret = 2;
}
else if(y==3){
if (x==2)
endereco = lcd_terc_lin;
else
endereco = lcd_terc_lin + 0x04;
ret = 3;
}
else if(y==4){
if (x==2)
endereco = lcd_quar_lin;
else
endereco = lcd_quar_lin + 0x04;
ret = 4;
}
else
endereco = lcd_prim_lin;

lcd_envia_byte(0,endereco);
return ret;
}


//******************************************************************************
// Função para posicionar o caracter no display
// recebe - linha e coluna (posição relativa no display)
// retorna - nada
//******************************************************************************
void lcd_pos(byte lin, byte pos){

byte pos1;

if ((LCD_TP==0) || (LCD_TP==1) || (LCD_TP==3))
switch (lin){
case 1:
pos1 = lcd_prim_lin+pos;
break;
case 2:
pos1 = lcd_seg_lin+pos;
break;
case 3:
pos1 = lcd_terc_lin+pos;
break;
case 4:
pos1 = lcd_quar_lin+pos;
break;
default:
pos1 = pos;
break;
}

if (LCD_TP==2)
switch (lin){
case 1:
pos1 = lcd_prim_lin+pos;
break;
case 2:
pos1 = lcd_seg_lin+pos;
break;
case 3:
pos1 = (lcd_terc_lin-4)+pos;
break;
case 4:
pos1 = (lcd_quar_lin-4)+pos;
break;
default:
pos1 = pos;
break;
}

lcd_envia_byte(0,pos1);
return;
}


//******************************************************************************
// Função para apagar o display
// recebe - nada
// retorna - nada
//******************************************************************************
void lcd_clear(){
lcd_envia_byte(0,1);
return;
}

//******************************************************************************
// Função para enviar um byte para o display
// recebe - caracter a ser enviado
// retorna - nada
//******************************************************************************
void lcd_escreve(char c)
{
lcd_envia_byte(1,c);
return;
}

//******************************************************************************
// Arquivo mod_lcd2.h
// Desenvolvido por Márcio José Soares
// diretrizes de pré-compilação para módulo mod_lcd2.c
//******************************************************************************

//******************************************************************************
// As definições a seguir são utilizadas para acesso aos pinos do display
// caso o pino RW não seja utilizado, comente a definição lcd_rw
//
//algumas definições foram modificadas para compatibilizar com a PIC16F628
//definições modificadas (pinos de trabalho para o LCD)
//******************************************************************************
#ifndef lcd_enable
#define lcd_enable pin_b0 // pino enable do LCD
#define lcd_rs pin_b3 // pino rs do LCD
//#define lcd_rw pin_e2 // pino rw do LCD
#define lcd_d4 pin_b4 // pino de dados d4 do LCD
#define lcd_d5 pin_b5 // pino de dados d5 do LCD
#define lcd_d6 pin_b6 // pino de dados d6 do LCD
#define lcd_d7 pin_b7 // pino de dados d7 do LCD
#endif

//******************************************************************************
// Define setup do LCD
//******************************************************************************
#define lcd_type 2 // 0=5x7, 1=5x10, 2=2 linhas

//******************************************************************************
// Definições para endereços das linhas (sempre na primeira coluna)
// Endereço base display 16 caracteres por coluna
// para outros LCD, somar ou subtrair
//******************************************************************************
#define lcd_prim_lin 0x80 // Endereço da primeira linha na RAM do LCD 16x4
#define lcd_seg_lin 0xC0 // Endereço da segunda linha na RAM do LCD 16x4
#define lcd_terc_lin 0x94 // Endereço da terceira linha na RAM do LCD 16x4
#define lcd_quar_lin 0xD4 // Endereço da quarta linha na RAM do LCD 16x4

//#define lcd_back pin_a7 // pino para back ligth do LCD
//#define lcd_led pin_a3 // pino para o led de apoio do display

//******************************************************************************
// Variáveis globais do módulo
//******************************************************************************

// a constante abaixo define a seqüência de inicialização do módulo LCD
byte CONST INI_LCD[4] = {0x20 | (lcd_type << 2), 0x0F, 1, 6};


ESTE NÃO CONSIGO MOSTRAR VARIAVEIS COMO:
LCD_ESCREVE("MENSAGEM %3U ",VARIAVEL);

ESTE DEIXA O PROGRAMA LENTO

// LCD STUFF
#define LCD_D4 PIN_b6 //pino 11 lcd 40 pic
#define LCD_D5 PIN_b4 //pino 12 lcd 37
#define LCD_D6 PIN_b7 //pino 13 lcd 39
#define LCD_D7 PIN_b5 //pino 14 lcd 38

#define LCD_EN PIN_b3 //pino 6 lcd 36
#define LCD_RS PIN_b2 //pino 4 lcd 35

#define PRI_LINE 0x80
#define SEC_LINE 0xC0
#define TER_LINE 0x94
#define QUA_LINE 0xD4

#define CLEAR_DISP 0x01
#define CURS_ON 0x0e
#define CURS_OFF 0x0c


//------------------------------------------------------------------------------
// proto statements
void LCD_Init ( void );
void LCD_SetPosition ( unsigned int cX );
void LCD_PutChar ( unsigned int cX );
void LCD_PutCmd ( unsigned int cX );
void LCD_PulseEnable ( void );
void LCD_SetData ( unsigned int cX );

//------------------------------------------------------------------------------
void LCD_Init ( void )
{
LCD_SetData ( 0x00 );
output_low ( LCD_RS );
LCD_SetData ( 0x03 ); // init with specific nibbles to start 4-bit mode
LCD_PulseEnable();
LCD_PulseEnable();
LCD_PulseEnable();
LCD_SetData ( 0x02 ); // set 4-bit interface
LCD_PulseEnable(); // send dual nibbles hereafter, MSN first
LCD_PutCmd ( 0x2C ); // function set (all lines, 5x7 characters)
LCD_PutCmd ( 0x0C ); // display ON, cursor off, no blink
LCD_PutCmd ( 0x01 ); // clear display
LCD_PutCmd ( 0x06 ); // entry mode set, increment
}

void LCD_SetPosition ( unsigned int cX )
{
// this subroutine works specifically for 4-bit Port A
LCD_SetData ( swap ( cX ) | 0x08 );
LCD_PulseEnable();
LCD_SetData ( swap ( cX ) );
LCD_PulseEnable();
}

void LCD_PutChar ( unsigned int cX )
{
// this subroutine works specifically for 4-bit Port A
output_high ( LCD_RS );
LCD_SetData ( swap ( cX ) ); // send high nibble
LCD_PulseEnable();
LCD_SetData ( swap ( cX ) ); // send low nibble
LCD_PulseEnable();
output_low ( LCD_RS );
}

void LCD_PutCmd ( unsigned int cX )
{
// this subroutine works specifically for 4-bit Port A
LCD_SetData ( swap ( cX ) ); // send high nibble
LCD_PulseEnable();
LCD_SetData ( swap ( cX ) ); // send low nibble
LCD_PulseEnable();
}

void LCD_PulseEnable ( void )
{
output_high ( LCD_EN );
delay_us ( 10 );
output_low ( LCD_EN );
delay_ms ( 2 );//ALTERA TEMPO DE AMOSRA NO LCD
}

void LCD_SetData ( unsigned int cX )
{
output_bit ( LCD_D4, cX & 0x01 );
output_bit ( LCD_D5, cX & 0x02 );
output_bit ( LCD_D6, cX & 0x04 );
output_bit ( LCD_D7, cX & 0x08 );
}
//------------------------------------------------------------------------------

ALGUEM TEM ALGUMA IDEIA OU ROTINA QUE FUNCIONE?!
jandom
Byte
 
Mensagens: 132
Registrado em: 03 Nov 2006 20:40

Mensagempor fabim » 12 Jun 2009 00:22

void LCD_SetData ( unsigned int cX )
{
output_bit ( LCD_D4, cX & 0x01 );
output_bit ( LCD_D5, cX & 0x02 );
output_bit ( LCD_D6, cX & 0x04 );
output_bit ( LCD_D7, cX & 0x08 );
}

Bom não sei como o CCS entende uma int.
Mais no geral int = 16 bits.
Vi que faz swap para pegar os dados em 4 bits.
Se fizer swap em 16 bits ele vai trocar os bytes, e não os nibles de um byte.

Experimenta mudar tudo que tem _u int, para _u char ou short, compila grava e testa novamente...
Dispois nós discutimos, testa primeiro...

fabim
Mano, ve só.
Sou responsável pelo que escrevo!!! E não pelo que você entende !!!
fabim
Dword
 
Mensagens: 5001
Registrado em: 16 Out 2006 10:18
Localização: aqui uái!!!?

Drive LCD 4X20

Mensagempor Orcino » 12 Jun 2009 22:04

Eu uso o que está abaixo, nunca tive problemas.

Código: Selecionar todos

// Flex_LCD420.c



#define LCD_DB4   PIN_D4 
#define LCD_DB5   PIN_D5
#define LCD_DB6   PIN_D6
#define LCD_DB7   PIN_D7

#define LCD_RS    PIN_D1
#define LCD_RW    PIN_D2
#define LCD_E     PIN_D0

#define USE_RW_PIN   1


// These are the line addresses for most 4x20 LCDs.

#define LCD_LINE_1_ADDRESS 0x00
#define LCD_LINE_2_ADDRESS 0x40
#define LCD_LINE_3_ADDRESS 0x14
#define LCD_LINE_4_ADDRESS 0x54


//========================================

#define lcd_type 2   // 0=5x7, 1=5x10, 2=2 lines(or more)

int8 lcd_line;

int8 const LCD_INIT_STRING[4] =
{
 0x20 | (lcd_type << 2),  // Set mode: 4-bit, 2+ lines, 5x8 dots
 0xc,                     // Display on
 1,                       // Clear display
 6                        // Increment cursor
 };


//-------------------------------------
void lcd_send_nibble(int8 nibble)
{
// Note:  !! converts an integer expression
// to a boolean (1 or 0).
 output_bit(LCD_DB4, !!(nibble & 1));
 output_bit(LCD_DB5, !!(nibble & 2));
 output_bit(LCD_DB6, !!(nibble & 4));
 output_bit(LCD_DB7, !!(nibble & 8));

 delay_cycles(1);
 output_high(LCD_E);
 delay_us(2);
 output_low(LCD_E);
}

//-----------------------------------
// This sub-routine is only called by lcd_read_byte().
// It's not a stand-alone routine.  For example, the
// R/W signal is set high by lcd_read_byte() before
// this routine is called.

#ifdef USE_RW_PIN
int8 lcd_read_nibble(void)
{
int8 retval;
// Create bit variables so that we can easily set
// individual bits in the retval variable.
#bit retval_0 = retval.0
#bit retval_1 = retval.1
#bit retval_2 = retval.2
#bit retval_3 = retval.3

retval = 0;

output_high(LCD_E);
delay_us(1);

retval_0 = input(LCD_DB4);
retval_1 = input(LCD_DB5);
retval_2 = input(LCD_DB6);
retval_3 = input(LCD_DB7);

output_low(LCD_E);
delay_us(1);

return(retval);
}
#endif

//---------------------------------------
// Read a byte from the LCD and return it.

#ifdef USE_RW_PIN
int8 lcd_read_byte(void)
{
int8 low;
int8 high;

output_high(LCD_RW);
delay_cycles(1);

high = lcd_read_nibble();

low = lcd_read_nibble();

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

//----------------------------------------
// Send a byte to the LCD.
void lcd_send_byte(int8 address, int8 n)
{
output_low(LCD_RS);

#ifdef USE_RW_PIN
while(bit_test(lcd_read_byte(),7)) ;
#else
delay_us(60);
#endif

if(address)
   output_high(LCD_RS);
else
   output_low(LCD_RS);

 delay_cycles(1);

#ifdef USE_RW_PIN
output_low(LCD_RW);
delay_cycles(1);
#endif

output_low(LCD_E);

lcd_send_nibble(n >> 4);
lcd_send_nibble(n & 0xf);
}
//----------------------------

void lcd_init(void)
{
int8 i;

lcd_line = 1;

output_low(LCD_RS);

#ifdef USE_RW_PIN
output_low(LCD_RW);
#endif

output_low(LCD_E);

// Some LCDs require 15 ms minimum delay after
// power-up.  Others require 30 ms.  I'm going
// to set it to 35 ms, so it should work with
// all of them.
delay_ms(35);

for(i=0 ;i < 3; i++)
   {
    lcd_send_nibble(0x03);
    delay_ms(5);
   }

lcd_send_nibble(0x02);

for(i=0; i < sizeof(LCD_INIT_STRING); i++)
   {
    lcd_send_byte(0, LCD_INIT_STRING[i]);

    // If the R/W signal is not used, then
    // the busy bit can't be polled.  One of
    // the init commands takes longer than
    // the hard-coded delay of 50 us, so in
    // that case, lets just do a 5 ms delay
    // after all four of them.
    #ifndef USE_RW_PIN
    delay_ms(5);
    #endif
   }

}

//----------------------------

void lcd_gotoxy(int8 x, int8 y)
{
int8 address;


switch(y)
  {
   case 1:
     address = LCD_LINE_1_ADDRESS;
     break;

   case 2:
     address = LCD_LINE_2_ADDRESS;
     break;

   case 3:
     address = LCD_LINE_3_ADDRESS;
     break;

   case 4:
     address = LCD_LINE_4_ADDRESS;
     break;

   default:
     address = LCD_LINE_1_ADDRESS;
     break;

  }

address += x-1;
lcd_send_byte(0, 0x80 | address);
}

//-----------------------------
void lcd_putc(char c)
{
 switch(c)
   {
    case '\f':
      lcd_send_byte(0,1);
      lcd_line = 1;
      delay_ms(2);
      break;

    case '\n':
       lcd_gotoxy(1, ++lcd_line);
       break;

    case '\b':
       lcd_send_byte(0,0x10);
       break;

    default:
       lcd_send_byte(1,c);
       break;
   }
}

//------------------------------
#ifdef USE_RW_PIN
char lcd_getc(int8 x, int8 y)
{
char value;

lcd_gotoxy(x,y);

// Wait until busy flag is low.
while(bit_test(lcd_read_byte(),7));

output_high(LCD_RS);
value = lcd_read_byte();
output_low(LCD_RS);

return(value);
}
#endif
Orcino
Bit
 
Mensagens: 19
Registrado em: 06 Dez 2006 22:07

Mensagempor jandom » 13 Jun 2009 22:31

OBRIGADO PELA AJUDA!
MAS ESTA ROTINA USA O R/W E NÃO TENHO PINO MAIS DISPONÍVEL NO PIC!
jandom
Byte
 
Mensagens: 132
Registrado em: 03 Nov 2006 20:40

Mensagempor fabim » 14 Jun 2009 15:01

jandom escreveu:OBRIGADO PELA AJUDA!
MAS ESTA ROTINA USA O R/W E NÃO TENHO PINO MAIS DISPONÍVEL NO PIC!


fioti, unsigned int, é reconhecido pelo ccs como 8 ou 16 bits ?
JA colocou tudo que int como short ou char, e fez o teste novamente ?
Mano, ve só.
Sou responsável pelo que escrevo!!! E não pelo que você entende !!!
fabim
Dword
 
Mensagens: 5001
Registrado em: 16 Out 2006 10:18
Localização: aqui uái!!!?

Drive LCD 4X20

Mensagempor Orcino » 14 Jun 2009 15:12

É só vc mudar onde está

#define USE_RW_PIN 1

coloque

#define USE_RW_PIN 0

Orcino
Orcino
Bit
 
Mensagens: 19
Registrado em: 06 Dez 2006 22:07

Mensagempor _blackmore_ » 15 Jun 2009 01:27

fabim

apesar de tu não ter perguntado para mim, e parece que o cabra ali não viu tua chamada então eu respondo ... unsigned int, é reconhecido pelo ccs como 8 bits.
No CCS são 16 bits apenas os modificadores long int, signed long int, unsigned long int e o int16.

abrax!
_blackmore_
Dword
 
Mensagens: 1397
Registrado em: 28 Set 2008 13:26

Mensagempor rodrigoadachi » 15 Jun 2009 16:32

Ola, cara utilizo este aki, fiz a modificação para o 20x4

#define lcd_db4 pin_b0 // pino de dados d4 do LCD
#define lcd_db5 pin_b1 // pino de dados d5 do LCD
#define lcd_db6 pin_b2 // pino de dados d6 do LCD
#define lcd_db7 pin_b3 // pino de dados d7 do LCD
#define lcd_rs pin_b4 // pino rs do LCD
#define lcd_enable pin_b5 // pino enable do LCD

#define lcd_lin1 0x80 // Endereço da primeira linha na RAM do LCD
#define lcd_lin2 0xC0 // Endereço da segunda linha na RAM do LCD
#define lcd_lin3 0x94 // Endereço da terceira linha na RAM do LCD
#define lcd_lin4 0xD4 // Endereço da quarta linha na RAM do LCD

#use fast_io(b) // Inicialização rápida dos Pinos de I/O
#byte portb = 0x06 //#byte porta = 0x05

void envia_nibble_lcd(int dado){// Envio de "Nibble" para o LCD
//Este é o bloco com as rotinas necessárias para manipular o LCD */
//Esta rotina lê o "Nibble" inferior de uma variável e envia para o LCD. */
//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
}
void envia_byte_lcd(boolean endereco, int dado){// 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
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
}
void escreve_lcd(char c){// envia caractere para o display
// 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>);
envia_byte_lcd(1,c);
return; // Retorna ao ponto de chamada da função
}
void limpa_lcd(){// Função para limpar o 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
}
void inicializa_lcd(){// Inicializa o 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
}
void lcd_pos_xy( byte x, byte y){// Dá a localização onde escrever no LCD
// (x,y) x colunas de 1 a 16, y linha 1 a 2
byte endereco;
if(y==1){
endereco = lcd_lin1;
}
if(y==2){
endereco = lcd_lin2;
}
if(y==3){
endereco = lcd_lin3;
}
if(y==4){
endereco = lcd_lin4;
}
endereco += x-1;
envia_byte_lcd(0,endereco);
return; // Retorna ao ponto de chamada da função
}

void main(){
portb = 0;
set_tris_b(0b11000000);
inicializa_lcd();
limpa_lcd();

lcd_pos_xy(1,1);printf(escreve_lcd," PRIMEIRA LINHA ");
lcd_pos_xy(1,2);printf(escreve_lcd," SEGUNDA LINHA ");
lcd_pos_xy(1,3);printf(escreve_lcd," TERCEIRA LINHA ");
lcd_pos_xy(1,4);printf(escreve_lcd," QUARTA LINHA ");
}
rodrigoadachi
Nibble
 
Mensagens: 70
Registrado em: 15 Out 2007 12:19
Localização: Bahia - Brazil

Mensagempor Djalma Toledo Rodrigues » 16 Jun 2009 11:31

Em Assembler + Datasheet do LCD, ficaria muito mais simples.

Ver tópico "Centarlizar texto no LCD"
http://asm51.eng.br/phpbb/viewtopic.php?t=7645
.
Avatar do usuário
Djalma Toledo Rodrigues
Dword
 
Mensagens: 2334
Registrado em: 03 Ago 2008 13:22

Mensagempor rodrigoadachi » 17 Jun 2009 22:02

Gostaria muito d ter tempo pra estudar PIC em asm, masnão tenho e tb sou um pouco priguiçoso, gosto de praticdade ma naum de simplicidade, gosto de coisas complexa mas organizadas.

Imagino q este scritsinho ai em asm viraria um livro kk
rodrigoadachi
Nibble
 
Mensagens: 70
Registrado em: 15 Out 2007 12:19
Localização: Bahia - Brazil

Mensagempor fabim » 18 Jun 2009 08:26

LCD.C
Código: Selecionar todos
/*
 *        LCD interface example
 *        Uses routines from delay.c
 *        This code will interface to a standard LCD controller
 *        like the Hitachi HD44780. It uses it in 4 bit mode, with
 *        the hardware connected as follows (the standard 14 pin
 *        LCD connector is used):
 *       
 *        PORTB bits 4-7 are connected to the LCD data bits 4-7 (high nibble)
 *        PORTB bit 3 is connected to the LCD RS input (register select)
 *        PORTC bit 5 is connected to the LCD EN bit (enable)
 *       
 *        To use these routines, set up the port I/O (TRISB, TRISC) then
 *        call lcd_init(), then other routines as required.
 *       
 */
#include        "lcd.h"

char lcdPosition;

void lcdDataIn(char c)
{
char d,e;
d=(c<<4);
d&=0xf0;
e=(LCD_DATA & 0x0f);
LCD_DATA=(d|e);
}

/* write a byte to the LCD in 4 bit mode */

void lcd_write(unsigned char c)
{
        Delay_Us(40);
        lcdDataIn(c >> 4);       
        LCD_STROBE();
        lcdDataIn(c);
        LCD_STROBE();
}

/*
 *         Clear and home the LCD
 */

void lcd_clear_lb(void)
{
        LCD_RS = 0;
        lcd_write(0x1);
        Delay_Ms(2);
}


/* write one character to the LCD */

void lcd_putch(char c)
{
        LCD_RS = 1;        // write characters
        lcd_write( c );
        lcdPosition++;
  /*if (lcdPosition==15)        16X2
                lcd_goto(0x00);
        if (lcdPosition==0x48)
                lcd_goto(0x00);*/
               
                if (lcdPosition==0x08)
                lcd_goto(0x08);     //16X1
        if (lcdPosition==0x48)
                lcd_goto(0x00);
}


/*
 * Go to the specified position
 */

void lcd_goto(unsigned char pos)
{
char temp;
        LCD_RS = 0;
  temp=pos & 0b00001000; //tirar daqui
        temp=temp<<3;
        pos &= 0b00000111;
        pos+=temp;
        lcdPosition=pos; //até aqui
        lcd_write(0x80+pos);
}
       
/* initialise the LCD - put into 4 bit mode */
void lcd_init_lb()
{
        char init_value;
        init_value = 0x3;
        LCD_CTRL_CONTROL = LCD_CTRL_CFG;
        LCD_DATA_CONTROL = LCD_DATA_CONFIG;
        LCD_RS = 0;
        LCD_EN = 0;
       
        Delay_Ms(15);        // wait 15mSec after power applied,
        lcdDataIn(init_value);
        LCD_STROBE();
        Delay_Ms(5);
        LCD_STROBE();
        Delay_Us(200);
        LCD_STROBE();
        Delay_Us(200);
        lcdDataIn(2);// Four bit mode
        LCD_STROBE();

        lcd_write(0x28); // Set interface length
        lcd_write(0x0C); // Display On, Cursor Off, Cursor don't Blink
        lcd_clear_lb();        // Clear screen
        lcd_write(0x06); // Set entry Mode
        lcd_goto(0);
}


LCD.H

Código: Selecionar todos
     /*
 *        LCD interface header file
 *        See lcd.c for more info
 */


#define        LCD_RS PORTC.F5

#define LCD_EN PORTB.F3

#define LCD_DATA        PORTB

#define LCD_DATA_CONTROL        TRISB

#define LCD_DATA_CONFIG                0x07

#define LCD_CTRL_CONTROL        TRISC

#define LCD_CTRL_CFG        0x5c

#define        LCD_STROBE()        ((LCD_EN = 1),(LCD_EN=0))



void lcdDataIn(char c);

/* write a byte to the LCD in 4 bit mode */

extern void lcd_write(unsigned char);

/* Clear and home the LCD */

extern void lcd_clear_lb(void);


/* Go to the specified position */

void lcd_goto(unsigned char pos);
       
/* intialize the LCD - call before anything else */

extern void lcd_init(void);

void lcd_putch(char c);

/*        Set the cursor position */


#define        lcd_cursor(x)        lcd_write(((x)&0x7F)|0x80)


Eu uso este a anos, só fazer uma modificação simples pra usar com qualquer um LCD...

OBS.: o original era em pascal...


Abraços

Fabim
Mano, ve só.
Sou responsável pelo que escrevo!!! E não pelo que você entende !!!
fabim
Dword
 
Mensagens: 5001
Registrado em: 16 Out 2006 10:18
Localização: aqui uái!!!?

Mensagempor ze » 18 Jun 2009 08:57

faltou
Código: Selecionar todos
/* write a string of chars to the LCD */

void
lcd_puts(const char * s)
{
   LCD_RS = 1;   // write characters
   while(*s)
   lcd_write(*s++);
}
Avatar do usuário
ze
Dword
 
Mensagens: 1655
Registrado em: 05 Jun 2007 14:32

Mensagempor fabim » 18 Jun 2009 13:00

lellis escreveu:faltou
Código: Selecionar todos
/* write a string of chars, in ROM, to the LCD */

void
lcd_puts(const char * s)
{
   LCD_RS = 1;   // write characters
   while(*s)
   lcd_write(*s++);
}


faltou ram..,

Código: Selecionar todos
/* write a string of chars, in RAM, to the LCD */

void lcd_puts( char * s)
{
   LCD_RS = 1;   // write characters
   while(*s)
   lcd_write(*s++);
}


AHÁ !!!
Mano, ve só.
Sou responsável pelo que escrevo!!! E não pelo que você entende !!!
fabim
Dword
 
Mensagens: 5001
Registrado em: 16 Out 2006 10:18
Localização: aqui uái!!!?

Mensagempor jandom » 23 Jun 2009 23:29

agradeço a todos os colegas que me ajudaram, mas o unico programa que ficou bom foi este:

//------------------------------------------------------------------------------

// LCD STUFF
#define LCD_D4 PIN_b5 //pino 11 lcd 38 pic
#define LCD_D5 PIN_b4 //pino 12 lcd 37
#define LCD_D6 PIN_b7 //pino 13 lcd 40
#define LCD_D7 PIN_b6 //pino 14 lcd 39

#define LCD_EN PIN_b2 //pino 6 lcd 35
#define LCD_RS PIN_b3 //pino 4 lcd 36



//INICIA LCD--------------------------------------------------------------------

#define PRI_LINE 0x80
#define SEC_LINE 0xC0
#define TER_LINE 0x94
#define QUA_LINE 0xD4

#define CLEAR_DISP 0x01
#define CURS_ON 0x0e
#define CURS_OFF 0x0c
//------------------------------------------------------------------------------
// proto statements
void LCD_Init ( void );
void LCD_SetPosition ( unsigned int cX );
void LCD_PutChar ( unsigned int cX );
void LCD_PutCmd ( unsigned int cX );
void LCD_PulseEnable ( void );
void LCD_SetData ( unsigned int cX );

//------------------------------------------------------------------------------
void LCD_Init ( void )
{
LCD_SetData ( 0x00 );
output_low ( LCD_RS );
LCD_SetData ( 0x03 ); // init with specific nibbles to start 4-bit mode
LCD_PulseEnable();
LCD_PulseEnable();
LCD_PulseEnable();
LCD_SetData ( 0x02 ); // set 4-bit interface
LCD_PulseEnable(); // send dual nibbles hereafter, MSN first
LCD_PutCmd ( 0x2C ); // function set (all lines, 5x7 characters)
LCD_PutCmd ( 0x0C ); // display ON, cursor off, no blink
LCD_PutCmd ( 0x01 ); // clear display
LCD_PutCmd ( 0x06 ); // entry mode set, increment
}

void LCD_SetPosition ( unsigned int cX )
{
// this subroutine works specifically for 4-bit Port A
LCD_SetData ( swap ( cX ) | 0x08 );
LCD_PulseEnable();
LCD_SetData ( swap ( cX ) );
LCD_PulseEnable();
}

void LCD_PutChar ( unsigned int cX )
{
// this subroutine works specifically for 4-bit Port A
output_high ( LCD_RS );
LCD_SetData ( swap ( cX ) ); // send high nibble
LCD_PulseEnable();
LCD_SetData ( swap ( cX ) ); // send low nibble
LCD_PulseEnable();
output_low ( LCD_RS );
}

void LCD_PutCmd ( unsigned int cX )
{
// this subroutine works specifically for 4-bit Port A
LCD_SetData ( swap ( cX ) ); // send high nibble
LCD_PulseEnable();
LCD_SetData ( swap ( cX ) ); // send low nibble
LCD_PulseEnable();
}

void LCD_PulseEnable ( void )
{
output_high ( LCD_EN );
delay_us ( 10 );
output_low ( LCD_EN );
delay_ms ( 2 );//ALTERA TEMPO DE AMOSRA NO LCD
}

void LCD_SetData ( unsigned int cX )
{
output_bit ( LCD_D4, cX & 0x01 );
output_bit ( LCD_D5, cX & 0x02 );
output_bit ( LCD_D6, cX & 0x04 );
output_bit ( LCD_D7, cX & 0x08 );
}
//------------------------------------------------------------------------------

ex de uso

- para amostrar variavel

LCD_SetPosition ( PRI_LINE +0 );//PRI-1@ LINHA, SEC- 2@ E ETC..
printf ( LCD_PutChar,"exemplo %3.2U ",VARIAVEL);

SEM VARIAVEL
LCD_SetPosition ( PRI_LINE +0 );

GRATO
printf ( LCD_PutChar, " EXEMPLO " );
jandom
Byte
 
Mensagens: 132
Registrado em: 03 Nov 2006 20:40


Voltar para PIC

Quem está online

Usuários navegando neste fórum: Nenhum usuário registrado e 1 visitante

x