Ir ao conteúdo
  • Cadastre-se

Problema LCD 16x2 + PIC 18F4550


Drosah

Posts recomendados

O display LCD 16x2 simplesmente não transfere os dados. Aparece aqueles quadrados pretos na 2a linha do LCD. entretanto na simulação funciona perfeitamente.

Eu tô usando o PIC 18f4550. E uso uma custom LCD.h. Existe um LED ligado a uma saída B7. Eu testei com o LCD.c da Microchip e aconteceu a mesma coisa.

O LCD está no modo Nibble.

O datasheet do LCD é:

http://www.sparkfun.com/datasheets/LCD/GDM1602K.pdf

Modelo: 1602GD1622Y (16x2 com backlight)

#include <18F4550.h>
#define TOLERANCIA 230
#fuses NOWDT,NOPROTECT
#fuses NOMCLR
#fuses INTRC_IO

#use delay(INTERNAL=4M)
#include <LCD16x2.h>
void main(){
int luminosidade=0;
setup_ADC_ports(ALL_ANALOG);
setup_adc(ADC_CLOCK_INTERNAL);
lcd_init();
while(1){
set_adc_channel(0); //Acerta o canal para o A0
// delay_ms(50);
luminosidade=read_adc();
delay_ms(20);
printf(lcd_putc,"Ola mundo.");
if (luminosidade>TOLERANCIA)
output_low(PIN_B7);
else
output_high(PIN_B7);
}
}

Código do LCD.h

// flex_lcd.c

// These pins are for the Microchip PicDem2-Plus board,
// which is what I used to test the driver. Change these
// pins to fit your own board.


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

#define LCD_E PIN_B2
#define LCD_RS PIN_B4
#define LCD_RW PIN_B3

// If you only want a 6-pin interface to your LCD, then
// connect the R/W pin on the LCD to ground, and comment
// out the following line.

#define USE_LCD_RW 0

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

#define lcd_type 2 // 0=5x7, 1=5x10, 2=2 lines
#define lcd_line_two 0x40 // LCD RAM address for the 2nd line


int8 const LCD_INIT_STRING[4] =
{
0x20 | (lcd_type << 2), // Func set: 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_LCD_RW
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_cycles(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);

return(retval);
}
#endif

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

#ifdef USE_LCD_RW
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_LCD_RW
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_LCD_RW
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;

output_low(LCD_RS);

#ifdef USE_LCD_RW
output_low(LCD_RW);
#endif

output_low(LCD_E);

delay_ms(15);

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 60 us, so in
// that case, lets just do a 5 ms delay
// after all four of them.
#ifndef USE_LCD_RW
delay_ms(5);
#endif
}

}

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

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

if(y != 1)
address = lcd_line_two;
else
address=0;

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

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

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

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

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

//------------------------------
#ifdef USE_LCD_RW
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

Link para o comentário
Compartilhar em outros sites

Bom, não sei se é esse o problema, mas com os 18F deve-se usar LAT ao invés de PORT devidos aos chaveamentos internos dos capacitores dos pinos. Dê uma pesquisada sobre isso. Já tive muitos problemas com relação a isso na minha transição dos 16F para a família dos 18F.

Link para o comentário
Compartilhar em outros sites

Bom, não sei se é esse o problema, mas com os 18F deve-se usar LAT ao invés de PORT devidos aos chaveamentos internos dos capacitores dos pinos. Dê uma pesquisada sobre isso. Já tive muitos problemas com relação a isso na minha transição dos 16F para a família dos 18F.

Oi como é que eu uso LAT em CCS? De qualquer forma grato irei testar com outro PIC da familia 16.

O problema está no contraste do LCD.

Veja que no esquema você colocou o pino 3 do LCD direto em VCC. Deve-se colocar um potenciometro para regular o contraste.

Dessa forma, os quadrados irao sumir.....

Um pino do potenciometro, a do meio no pino 3 do LCD e o outro pino em 0V,

Falou

Oi, coloquei um potenciometro e nada =x Continua a mesma coisa. Os quadrados sumiram, mas não apareceu a palavra.

Link para o comentário
Compartilhar em outros sites

Seguinte, você colocou o potenciometro. Mas você girou ele ate começar a aparecer os quadrados?

Pois se nao o fizer, dependendo da posiçao do potenciomento, fica tudo em branco ou com os quadrados.

Tente girar para ver se aparece alguma coisa.

Se isso não funcionar, tente com a biblioteca padrão do CCS, a LCD.C. Utilizando os pinos do portD.

TEM q funcionar.

O LED no pino B7 chega a ligar com o código atual?

Falou

Link para o comentário
Compartilhar em outros sites

Seguinte, você colocou o potenciometro. Mas você girou ele ate começar a aparecer os quadrados?

Pois se nao o fizer, dependendo da posiçao do potenciomento, fica tudo em branco ou com os quadrados.

Tente girar para ver se aparece alguma coisa.

Se isso não funcionar, tente com a biblioteca padrão do CCS, a LCD.C. Utilizando os pinos do portD.

TEM q funcionar.

O LED no pino B7 chega a ligar com o código atual?

Falou

Oi ele liga o led sim, modifiquei o código pra o led piscar e funcionou também. Já girei o potenciometro devagar e ficou na mesma, já utilizei o código do LCD.c original e inclusive uma versão do C18. Acho que o LCD é o problema. Não cheguei a testar com outro microcontrolador ainda.

Link para o comentário
Compartilhar em outros sites

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas comunidades sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×
×
  • Criar novo...

 

GRÁTIS: ebook Redes Wi-Fi – 2ª Edição

EBOOK GRÁTIS!

CLIQUE AQUI E BAIXE AGORA MESMO!