Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

4 bit mode writing problem on LCD

Status
Not open for further replies.

mariuszoll

Member level 5
Joined
Aug 28, 2012
Messages
82
Helped
1
Reputation
2
Reaction score
0
Trophy points
1,286
Activity points
2,147
Hi,

I use on my project a PIC18F24J11, and I want to display data on LCD on 4bit mode. I use MPLAB, and the compiler MCC18.
RA5-->RS
RA6-->EN
RC0...RC3--> DB4...DB7
Could you help me please to fix this problem? Below is attached the C code:
//Program

/* LCD 16x2
4 bit mode
RA5--> RS
RA6-->Enable
RC0..RC3 --> DB4...DB7
R/W --> GND
LCD: BT 21605VSS-SRE-HQ from Batron
KS0070_lcd_driver
PIC18F24J11
uC internal clock 4MHz
*/

#include <p18f24j11.h>
#include <delays.h>
#include <string.h>
//#include <xlcd.h>

// Pragma

#pragma config WDTEN = OFF
#pragma config OSC = INTOSC
#pragma config XINST = OFF
#pragma config DSBOREN = OFF
#pragma config RTCOSC = INTOSCREF

//*****************************************************************************
// CONSTANT DEFINITION
//*****************************************************************************

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

// Variables


/** L O C A L F U N C T I O N S *******************************************/

void set_hi_nibble(char data) // output hi nibble data on port lines
{
unsigned char temp=PORTC;

temp= temp & 0xF0;
temp= temp | (data>>4);
LATC=temp;
}

void set_lo_nibble(char data) // output low nibble data on port lines
{
unsigned char temp=PORTC;

temp= temp & 0xF0;
temp= temp | (data & 0xF0);
LATC=temp;
}

void en_set(void) //function used to set Enable signal properly
{
LATAbits.LATA6 = 1; // Set EN on 1
Delay1KTCYx(1); // delay 1ms
LATAbits.LATA6 = 0; // Set EN on 0
}

void data(unsigned char c) // function used to write data to LCD
{
LATAbits.LATA5=1; // set RS on 1
set_hi_nibble(c);
en_set();
Delay1KTCYx(50); // delay 50ms

set_lo_nibble(c);
en_set();
Delay1KTCYx(50); // delay 50ms

}

void cmd(unsigned char c) // function used to send commands to LCD
{
LATAbits.LATA5=0; // set RS on 0

set_hi_nibble(c);
en_set();
Delay1KTCYx(50); // delay 50ms

set_lo_nibble(c);
en_set();
Delay1KTCYx(50); // delay 50ms
}

void LCDInit(void)
{
Delay10KTCYx(20); // delay 200ms

TRISCbits.TRISC0=0; //RC0 output, DB4
TRISCbits.TRISC1=0; //RC1 output, DB5
TRISCbits.TRISC2=0; //RC2 output, DB6
TRISCbits.TRISC3=0; //RC3 output, DB7

TRISAbits.TRISA5=0; //RA5 output, RS
TRISAbits.TRISA6=0; //RA6 output, EN

// Oscillator frequency
OSCCON=0b01100000; // 4MHz

// pins configurred as digital
ANCON0=0b11111111;
ANCON1=0b00011111;

LATAbits.LATA6=0; // Set EN on 0
Delay1KTCYx(100); // Delay 100ms

LATAbits.LATA5=0; // Set RS on 0
Delay1KTCYx(15); // delay 15ms
LATC=0x2;
en_set();
Delay1KTCYx(5); // delay 5ms
en_set();
Delay100TCYx(1); // delay 100us
en_set();
Delay1KTCYx(5); // delay 5ms
LATC=0x2;
en_set();
Delay10TCYx(4); // delay 40us

//Function set

cmd(0x28); // 4 bits, 2 lines, 5x7 dots format display mode
Delay10TCYx(4); // delay 40us

//Display ON control

cmd(0x0E); // display on, cursor on, blinking cursor position off
Delay10TCYx(4); // delay 40us

//Clear Display

cmd(0x01); // dispaly clear
Delay1KTCYx(2); // delay 2ms

//Entry set increment

cmd(0x07); // increment, display shift to left
Delay100TCYx(10); // delay 1ms

}

///////////////////main function///////////////////////////////////////////

void main()
{
LCDInit();

data('A');

while(1);
}//main

Thank you in advance.
 

Dont worry

- - - Updated - - -

yesterday only i got solved the same problem

- - - Updated - - -

my post... https://www.edaboard.com/threads/292100/ today i will post the code and try it.....
 

Hi venkadeshm,

Would you like to post your code please?

Thank you.
 

ya, i will post my working code and you can try it with some pin changes...

The main problem in 4 bit mode is command sequence, so it will be easy......
 

Code:
#include <pic.h>
#include <htc.h>

#define _XTAL_FREQ 20000000

#define RW RD2
#define RS RD3
#define EN RD1
#define databits PORTD

void data(unsigned char c)
{
	databits = ( c & 0xF0 ) | 0x08 | 0x02;
   	__delay_us(50);
	databits = ( c & 0XF0 ) | 0x08;
    __delay_us(50);
	databits = ( ( c << 4 ) & 0xF0 ) | 0x08 | 0x02;
    __delay_us(50);
	databits = ( ( c << 4 ) & 0XF0 ) | 0x08;
}

void cmd(unsigned char c)
{
	databits = ( c & 0xF0 ) | 0x02;
   	__delay_us(50);
	databits = ( c & 0XF0 );
    __delay_us(50);
	databits = ( ( c << 4 ) & 0xF0 ) | 0x02;
    __delay_us(50);
	databits = ( ( c << 4 ) & 0XF0 );
}

void init(unsigned char c)
{
	databits = ( c & 0xF0 ) | 0x02;
   	__delay_us(50);
	databits = ( c & 0XF0 );
    __delay_ms(10);
	databits = ( ( c << 4 ) & 0xF0 ) | 0x02;
    __delay_us(50);
	databits = ( ( c << 4 ) & 0XF0 );
}

void puts(char* str)
{	
	cmd(0x01);
	cmd(0x80);
	__delay_ms(31);
    for(char i = 0; str[i] != 0; i++)
	{
    __delay_us(20);
	data(str[i]);
	}
}
    
void lcd_init(void)
{
    __delay_ms(16);
    init(0x33);
    __delay_ms(1);
	cmd(0x32);
    __delay_us(20);
	cmd(0x2C);
    __delay_us(20);
	cmd(0x0C);
    __delay_us(20);
	cmd(0x06);	
	__delay_us(20);
	cmd(0x0C);
	__delay_us(20);
	cmd(0x01);
    __delay_us(20);
	cmd(0x80);
    __delay_us(20);
	
}


main()
{
	char i, wel[]="    WELCOME";

    TRISD = 0;
	TRISC = 0;
	RC0 = RC1 = RC2 = 0;

	lcd_init();

	puts(wel);

 

	for( i = 0; i < 50; i++)
	__delay_ms(30);


	while(1);
}
 

Hi, I succeeded to fix my software, and now it is working fine. Below is attached:
//Program

/* LCD 16x2
4 bit mode
RA5--> RS
RA6-->Enable
RC0..RC3 --> DB4...DB7
R/W --> GND
LCD: BT 21605VSS-SRE-HQ from Batron
KS0070_lcd_driver
PIC18F24J11
uC internal clock 4MHz
*/

#include <p18f24j11.h>
#include <delays.h>
#include <string.h>
//#include <xlcd.h>

// Pragma

#pragma config WDTEN = OFF
#pragma config OSC = INTOSC
#pragma config XINST = OFF
#pragma config DSBOREN = OFF
#pragma config RTCOSC = INTOSCREF

//*****************************************************************************
// CONSTANT DEFINITION
//*****************************************************************************

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

// Variables


/** L O C A L F U N C T I O N S *******************************************/

void set_hi_nibble(unsigned char data) // output hi nibble data on port lines
{
unsigned char temp=PORTC;

temp= temp & 0xF0;
temp= temp | (data>>4);
LATC=temp;
}

void set_lo_nibble(unsigned char data) // output low nibble data on port lines
{
unsigned char temp=PORTC;

temp= temp & 0xF0;
temp= temp | (data & 0x0F);
LATC=temp;
}

void en_set(void) //function used to set Enable signal properly
{
LATAbits.LATA6 = 1; // Set EN on 1
Delay1KTCYx(1); // delay 1ms
LATAbits.LATA6 = 0; // Set EN on 0
}

void data(unsigned char c) // function used to write data to LCD
{
LATAbits.LATA5=1; // set RS on 1
set_hi_nibble(c);
en_set();
Delay1KTCYx(50); // delay 50ms

set_lo_nibble(c);
en_set();
Delay1KTCYx(50); // delay 50ms

}

void cmd(unsigned char c) // function used to send commands to LCD
{
LATAbits.LATA5=0; // set RS on 0

set_hi_nibble(c);
en_set();
Delay1KTCYx(50); // delay 50ms

set_lo_nibble(c);
en_set();
Delay1KTCYx(50); // delay 50ms
}

void LCDInit(void)
{
Delay10KTCYx(20); // delay 200ms

LATA=0;
LATC=0;

TRISCbits.TRISC0=0; //RC0 output, DB4
TRISCbits.TRISC1=0; //RC1 output, DB5
TRISCbits.TRISC2=0; //RC2 output, DB6
TRISCbits.TRISC3=0; //RC3 output, DB7

TRISAbits.TRISA5=0; //RA5 output, RS
TRISAbits.TRISA6=0; //RA6 output, EN

// Oscillator frequency
OSCCON=0b01100000; // 4MHz

// pins configurred as digital
ANCON0=0b11111111;
ANCON1=0b00011111;

LATAbits.LATA6=0; // Set EN on 0
Delay1KTCYx(100); // Delay 100ms

LATAbits.LATA5=0; // Set RS on 0
Delay1KTCYx(15); // delay 15ms

LATC=0x3;
en_set();
Delay1KTCYx(5); // delay 5ms

/* en_set();
Delay100TCYx(1); // delay 100us
en_set();
Delay1KTCYx(5); // delay 5ms
LATC=0x2;
en_set();
Delay10TCYx(4); // delay 40us */

LATC=0x3;
en_set();
Delay100TCYx(1); // delay 100us

LATC=0x3;
en_set();
Delay10TCYx(4); // delay 40us

LATC=0x2;
en_set();
Delay10TCYx(4); // delay 40us

//Function set

cmd(0x28); // 4 bits, 2 lines, 5x7 dots format display mode
Delay10TCYx(4); // delay 40us

//Display ON control

cmd(0x0E); // display on, cursor on, blinking cursor position off
Delay10TCYx(4); // delay 40us

//Clear Display

cmd(0x01); // dispaly clear
Delay1KTCYx(2); // delay 2ms

//Entry set increment

cmd(0x06); // increment, display shift to left
Delay100TCYx(10); // delay 1ms

}

///////////////////main function///////////////////////////////////////////

void main()
{
unsigned char i=0;

LCDInit();

data('M');
data('A');
data('R');
data('I');
data('U');
data('S');
cmd(0xC0);

while(1)
{
i++;
if(i>9)
{
i=0;
cmd(0x01);
}
data('0'+i);
Delay10KTCYx(100);

}//while(1)
}//main
 

Yes, it seems work, but very slowly because of excessive or unnecessary delays.

Some examples:

In function data(char) the first 50 ms is unnecessary and the second may be 50 us (not 50 ms).

In function cmd(char) the first 50 ms is also unnecessary and the second may be 50 us too if (char > 3) else 2 ms.

In function en_set() the 1 ms is unnecessary, 1 uS is also enough.

A note to both nibble functions:
unsigned char temp = LATC; //instead of PORTC;

Try it!
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top