Ir ao conteúdo

Inicialização de LCD 2x20 com PIC 18F1320 e compilador MPLAB C18


Visitante

Posts recomendados

Postado

Pessoal,

Estou tentando inicializar um LCD de 2x20 com um pic 18f1320 usando o compliador C18 (Mplab)...

Segue o código...


#include "includes.h"
#include "p18f1320.h"
#include "xlcd.h"

#if defined(__18F1320)
// external HS = 8 MHz
// TCLK = 1/8.000.000 = 125 ns
#pragma config OSC = HS
#pragma config WDT = ON, WDTPS = 4096
#pragma config PWRT = ON
#pragma config CP0 = OFF
#pragma config CP1 = OFF
#pragma config LVP = OFF
#pragma config MCLRE = ON
#pragma config DEBUG = ON
#pragma config BOR = OFF
#pragma config FSCM = OFF
#pragma config IESO = OFF
#pragma config STVR = OFF
#pragma config CPB = OFF
#pragma config CPD = OFF
#pragma config WRT0 = OFF
#pragma config WRT1 = OFF
#pragma config WRTB = OFF
#pragma config WRTC = OFF
#pragma config WRTD = OFF
#pragma config EBTR0 = OFF
#pragma config EBTR1 = OFF
#pragma config EBTRB = OFF

#define lcd_rs LATBbits.LATB5 // define RS Pin
#define lcd_e LATBbits.LATB6 // define E Pin

#define lcd_DB7 LATAbits.LATB3 // define LCD Data Bit 7
#define lcd_DB6 LATAbits.LATB2 // define LCD Data Bit 6
#define lcd_DB5 LATAbits.LATA4 // define LCD Data Bit 5
#define lcd_DB4 LATBbits.LATB0 // define LCD Data Bit 4
#define lcd_DB3 LATAbits.LATA3 // define LCD Data Bit 3
#define lcd_DB2 LATAbits.LATA2 // define LCD Data Bit 2
#define lcd_DB1 LATAbits.LATA1 // define LCD Data Bit 1
#define lcd_DB0 LATAbits.LATA0 // define LCD Data Bit 0

//#define lcd_db_tris TRISB // define LCD Data Bits TRIS
//#define lcd_cnt_tris TRISA // define LCD Control Bits TRIS


#define Line1 0x00
#define Line2 0x40

void config_chip(void)
{
RCON = 0; //RCON: RESET CONTROL REGISTER
INTCON = 0; //INTERRUPT CONTROL REGISTER
INTCON2 = 0x80; //INTERRUPT CONTROL REGISTER, mantem RBPU ligado
INTCON3 = 0; //INTERRUPT CONTROL REGISTER
IPR1 = 0; //LOW PRIORITY: PERIPHERAL INTERRUPT CONFIG
IPR2 = 0; //LOW PRIORITY: PERIPHERAL INTERRUPT CONFIG
PIR1 = 0; //PERIPHERAL INTERRUPT REQUEST FLAGS
PIR2 = 0; //PERIPHERAL INTERRUPT REQUEST FLAGS
TRISB = 0x0f; // todos os bits como saidas
TRISA = 0x0f; // todos os bits como saidas
}

void DelayFor18TCY( void )
{
Nop();Nop();Nop();Nop();Nop();Nop();Nop();Nop();Nop();Nop();Nop();Nop();
}

void DelayPORXLCD (void)
{
Delay1KTCYx(120); // Delay of 15ms
// Cycles = (TimeDelay * Fosc) / 4
// Cycles = (15ms * 16MHz) / 4
// Cycles = 60,000
return;
}

void DelayXLCD (void)
{
Delay1KTCYx(20); // Delay of 5ms
// Cycles = (TimeDelay * Fosc) / 4
// Cycles = (5ms * 16MHz) / 4
// Cycles = 20,000
return;
}

void comandXLCD(unsigned char a)
{
BusyXLCD();
WriteCmdXLCD(a);
}

void gotoxyXLCD(unsigned char x, unsigned char y)//posição do cursor
{
unsigned char direction;
if (y != 1)
direction = 0x40;
else
direction = 0;

direction += x-1;//the same as direction = direction + x - 1;
comandXLCD (0x80 | direction);
}


void main (void)
{
OSCCON = 0x70; // muda INTOSC Postscaler para 8 MHz, pois o default é 4 MHz
ClrWdt(); // Clear the WDT
config_chip();

while (1){
ClrWdt();
//openXLCD (FOUR_BIT & LINES_5X7);
comandXLCD(0x06);
comandXLCD(0x0C);
putsXLCD("Testando LCD L1");
gotoxyXLCD(1,2);
putrsXLCD("Testando LCD L2");
}
}

Não aparece nada no meu display...em anexo está o meu esquemático de ligação do LCD, quero ligar com 8 bits, não sei se a configuração do software está correta...

Se alguém puder me ajudar...agradeço...

Abraço..

jrgob

post-341709-13884959614768_thumb.jpg

Postado

Já vou lhe adiantando que não entendo nada de programação em C.

Somente programo em Assembly.

Mas, como vi que é urgente, vou tentar ajudar dentro das minhas possibilidades.

No esquema, o pino RB6 (ENA1) não deveria estar ligado ao conector do display?

Para que você possa usar os pinos RA0 a RA3 como entradas e ou saídas digitais, você precisa desabilitar o módulo A/D, fazendo o valor do registrador ADCON1 = 0x7F

Para que todos os pinos do PORTA e do PORTB sejam saídas, você tem que fazer os valores dos registradores TRISA e TRISB = 0

Recomendo desativar os resistores de Pull-up internos do PORTB, eliminando esta linha, pois, no mínimo é inútil:

INTCON2 = 0x80; //INTERRUPT CONTROL REGISTER, mantem RBPU ligado

Postado

Obrigado Mulder_Fox pela ajuda...

Bom, quanto a sua pergunta sobre o pino RB6, ele está ligado ao pino Enable (ENA1) do display, só uso em paralelo para programação in circuit.

Na função que eu uso a config_chip(), já faz quase tudo que você disse, só nao desabilita o módulo A/D....vou testar....

jrgob

Mesmo mudando esse parametro, não consegui fazer funcionar o lcd....

Acho que é alguma configuração de inicialização....

alguém tem alguma outra ideia?

Obrigado.

jrgob

Postado

Fiz um novo código...mas agora o problema é que tranca na função busyXLCD(), que vem junto na biblioteca C18..

Eu comentei a função, mas o correto é não comentar ela....

Se alguém puder me ajudar....

Obrigado.

jrgob


#include <stdio.h>
#include <string.h>
#include <delays.h>
#include <stdlib.h>
#include <p18f1320.h>
#include <xlcd.h>


#if defined(__18F1320)
// external HS = 8 MHz
// TCLK = 1/8.000.000 = 125 ns
#pragma config OSC = HS
#pragma config WDT = ON, WDTPS = 4096
#pragma config PWRT = ON
#pragma config CP0 = OFF
#pragma config CP1 = OFF
#pragma config LVP = OFF
#pragma config MCLRE = ON
#pragma config DEBUG = ON
#pragma config BOR = OFF
#pragma config FSCM = OFF
#pragma config IESO = OFF
#pragma config STVR = OFF
#pragma config CPB = OFF
#pragma config CPD = OFF
#pragma config WRT0 = OFF
#pragma config WRT1 = OFF
#pragma config WRTB = OFF
#pragma config WRTC = OFF
#pragma config WRTD = OFF
#pragma config EBTR0 = OFF
#pragma config EBTR1 = OFF
#pragma config EBTRB = OFF


/* DDRAM Addresses for visible LCD lines */
int Line1 = 0x00;
int Line2 = 0x40;


/* Prototypes for C18 LCD library */
void OpenXLCD( unsigned char lcdtype );
void DelayFor18TCY( void );
void DelayPORXLCD (void);
void DelayXLCD (void);
void putsXLCD( char *buffer );
void config_chip(void);

/* 18 cycle (approx) delay for LCD routines */
void DelayFor18TCY( void )
{
Nop();Nop();Nop();Nop();Nop();Nop();Nop();Nop();Nop();Nop();Nop();Nop();Nop();Nop();Nop();Nop();
}

/* 15 msec (approx) delay for LCD routines */
void DelayPORXLCD (void)
{
Delay1KTCYx(35); // Delay of 15ms
// Cycles = (TimeDelay * Fosc) / 4
// Cycles = (15ms * 8MHz) / 4
// Cycles = 30,000
return;
}

/* 5 msec (approx) delay for LCD routines */
void DelayXLCD (void)
{
Delay1KTCYx(15); // Delay of 5ms
// Cycles = (TimeDelay * Fosc) / 4
// Cycles = (5ms * 8MHz) / 4
// Cycles = 10,000
return;
}

void putsXLCD(char *buffer)
{
while(*buffer) // Write data to LCD up to null
{
//while(BusyXLCD()); // Wait while LCD is busy
WriteDataXLCD(*buffer); // Write character to LCD
buffer++; // Increment buffer
}
return;
}


void config_chip(void)
{
RCON = 0; //RCON: RESET CONTROL REGISTER
INTCON = 0; //INTERRUPT CONTROL REGISTER
INTCON2 = 0x80; //INTERRUPT CONTROL REGISTER, mantem RBPU ligado
INTCON3 = 0; //INTERRUPT CONTROL REGISTER
IPR1 = 0; //LOW PRIORITY: PERIPHERAL INTERRUPT CONFIG
IPR2 = 0; //LOW PRIORITY: PERIPHERAL INTERRUPT CONFIG
PIR1 = 0; //PERIPHERAL INTERRUPT REQUEST FLAGS
PIR2 = 0; //PERIPHERAL INTERRUPT REQUEST FLAGS
TRISB = 0x0f; // todos os bits como saidas
TRISA = 0x0f; // todos os bits como saidas
ADCON1 = 0x7F; //desabilita os módulos a/d

}

void main()
{
config_chip();


/* LCD Setup */
Delay10KTCYx(255); // Wait for LCD to start up, needs at least 200ms
OpenXLCD( EIGHT_BIT & LINES_5X7 ); //Open LCD
//while(BusyXLCD());
WriteCmdXLCD(0x01); // Clear display
WriteCmdXLCD( BLINK_ON );
WriteCmdXLCD( SHIFT_DISP_LEFT );
//while(BusyXLCD());
//WriteCmdXLCD(DON&CURSOR_OFF&BLINK_OFF);
//while(BusyXLCD());
SetDDRamAddr( Line1 );
//while(BusyXLCD());
//putrsXLCD("Starting Up...");
/* End LCD Setup */

while(1) //MAIN LOOP BEGINS HERE
{
SetDDRamAddr( Line1 );
//while(BusyXLCD());
putrsXLCD("TESTE LCD L2");
//while(BusyXLCD());
SetDDRamAddr( Line2 );
//while(BusyXLCD());
putrsXLCD("TESTE LCD L1");
}//END MAIN LOOP
}

  • mês depois...
Postado

Administrador,

Por favor feche este tópico. Pois ninguem responde, nao tenho por que deixar aberto.

Muito Obrigado.

Postado

Experimente o seguinte:

while(BusyXLCD());

Depois de :

WriteCmdXLCD(0x01); 

Use 'while(BusyXLCD())' depois de enviar um comando.

Postado

Pelo que vi no ciruito você não está ligando o pino R/W do display, portanto não é possível ler o busyflag.

Você tem que dar delays de 50us para instruções e dados, exceto a instrução 0x01 (apagar display) que deve ser acompanhada de um delay de 2ms.

  • mês depois...
Postado

Agradeço a ajuda, mas tive que ficar um bom tempo sem mexer nesse projeto....talvez eu nem o faça mais....

Pode retirar o tópico...

Obrigado.

  • Coordenador
Postado

Tópico Fechado sem solução

Caso o autor do tópico necessite, o mesmo será reaberto, para isso deverá entrar em contato com a moderação solicitando o desbloqueio.

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...