4 bit LCD display configuration issues .

Status
Not open for further replies.

aliyesami

Full Member level 6
Joined
Jan 7, 2010
Messages
369
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,296
Location
USA
Visit site
Activity points
4,190
my 8 bit LCD is working without issues so i am trying now to goto 4 bit mode to save pins.
its giving me headaches . after reading many posts online i modified the LCD busy routine as follows , where am i going wrong?

this code for 8 bit works fine !

Code:
 void Check_LCD_Busy() 
{ 
   DataDir_LCD_data = 0; 
   LCD_controls |= 1<<ReadWrite; 
   LCD_controls &= ~1<<RS; 

   while (LCD_data >= 0x80) 
   { 
      strobe_enable(); 
   } 
   DataDir_LCD_data = 0xFF;                
} 

void strobe_enable() 
{ 
   LCD_controls |= 1<<Enable; 
   _delay_us(50); 
   LCD_controls &= ~1<<Enable; 
}

the following change I made for 4 bit which is not working I think.

Code:
void Check_LCD_Busy() 
{ 
        unsigned char portbyte; 
   DataDir_LCD_data = 0; 
   LCD_controls |= 1<<ReadWrite; 
   LCD_controls &= ~1<<RS; 
    
    
   while (LCD_data >= 0x80) 
   { 
      strobe_enable(); 
        portbyte = LCD_data; 
      portbyte = ((LCD_data << 4) & 0xF0);             //shift the nibble to MSB
       strobe_enable(); 
       portbyte |= (LCD_data & 0x0F);            // get the low nibble 
      LCD_data = portbyte; 
   } 
   DataDir_LCD_data = 0xFF;                      
}


these routines work fine for 8 bit mode!

Code:
 void Send_A_Command(unsigned char command) 
{ 
   Check_LCD_Busy(); 
   LCD_data = command; 
   LCD_controls &= ~ ((1<<ReadWrite)|(1<<RS)); 
   strobe_enable(); 
   LCD_data = 0; 
} 

void Send_A_Character(unsigned char character) 
{ 
   Check_LCD_Busy(); 
   LCD_data = character; 
   LCD_controls &= ~ (1<<ReadWrite); 
   LCD_controls |= 1<<RS; 
   strobe_enable(); 
   LCD_data = 0; 
}


these routines I modified for 4 bit

Code:
 void Send_A_Command(unsigned char command) 
{ 
   Check_LCD_Busy(); 
   LCD_data = ((command << 4) & 0xF0);            // send high nibble first 
   LCD_controls &= ~ ((1<<ReadWrite)|(1<<RS)); 
   strobe_enable(); 
   LCD_data = (command & 0b00001111) ;            // send low nibble first 
   LCD_controls &= ~ ((1<<ReadWrite)|(1<<RS)); 
   strobe_enable(); 
    
   LCD_data = 0; 
} 


void Send_A_Character(unsigned char character) 
{ 
   Check_LCD_Busy(); 
   LCD_data = ((character >> 4) & 0x0F) ;          //send high nibble first 
   LCD_controls &= ~ (1<<ReadWrite); 
   LCD_controls |= 1<<RS; 
   strobe_enable(); 
   LCD_data = (character & 0b00001111) ;     //send low nibble next 
   LCD_controls &= ~ (1<<ReadWrite); 
   LCD_controls |= 1<<RS; 
   strobe_enable(); 
    
   LCD_data = 0; 
}
 

here is my lcd init function .

Code:
void init_lcd()
{
		DataDir_LCD_controls |= 1<<Enable | 1<<ReadWrite | 1<<RS;
		_delay_ms(25);

		Send_A_Command(0x01);		//Clear Screen 0x01 = 00000001
		_delay_ms(10);
		Send_A_Command(0x38);		//8-bit mode
		_delay_ms(3);
		Send_A_Command(0b00001111);	//display on , cursor non blinking
		_delay_ms(5);
		//	Send_A_Command(0x06);
		//	_delay_ms(2);
		Send_A_Command(0x38);       //8bit , 2 lines, 5x7 font!
		_delay_ms(2);
}
 

hello,

you didn't change the LCD mode to 4 bits mode ...

adapt this ...

Code:
void LCD_init(void)
{
  // Wait for more than 15 ms after VCC rises to 5 V
  Delay10KTCYx(500);

  // Send Command 0x30
  LCD_putcmd(0x30,0);

  // Wait for more than 4.1 ms
  Delay10KTCYx(100);

  // Send Command 0x30
  LCD_putcmd(0x30,0);

  // Wait for more than 100 us
  Delay10KTCYx(10);           

  // Send Command 0x30
  LCD_putcmd(0x30,0);
    Delay10KTCYx(5);  

  // Function set: Set interface to be 4 bits long (only 1 cycle write).
  LCD_putcmd(0x20,0); 
    Delay10KTCYx(5);   

  // Function set: DL=0;Interface is 4 bits, N=1; 2 Lines, F=0; 5x8 dots font)
  LCD_putcmd(0x28,1);
    Delay10KTCYx(5);  

  // Display Off: D=0; Display off, C=0; Cursor Off, B=0; Blinking Off
  LCD_putcmd(0x08,1);
    Delay10KTCYx(5);  

  // Display Clear
  LCD_putcmd(LCD_CLEAR,1);
    Delay10KTCYx(5);  

  // Entry Mode Set: I/D=1; Increament, S=0; No shift
  LCD_putcmd(0x06,1);
    Delay10KTCYx(5);  

  // Display On, Cursor Off
  LCD_putcmd(0x0C,1);
    Delay10KTCYx(20);  
}
 

sorry it was typo. . I am setting the mode for 4 bit by sending 0x28.
so what else could be wrong? I don't think its the other initialization code since my initialization code is working fine for 8 bit.
I think the problem is sending high and low bytes or in checking the busy flag in 5 bit mode.
 

hello


in 4 bits mode, generaly we don't use ligne R/W , tied to ground on LCD..
so only write to LCD is possible and impossible to read the flag busy..
so never tested ... some time replaced by a litle delay x mS
try to remove this test.
 
hi PAul !
I changed the code based on your suggestion please take a look , its still not working . I have tied the R/W to ground .
Code:
// Title		: LCDinterface
// Software		: WINAVR GCC
// Description  : 4-bit LCD Interface

#define F_CPU 20000000UL
#include <avr/io.h>
#include <util/delay.h>

// used pins on port D
#define LCD_DB4 4    // PORTD.4
#define LCD_DB5 5    // PORTD.5
#define LCD_DB6 6    // PORTD.6
#define LCD_DB7 7    // PORTD.7
#define LCD_E  5     // PORTA.5 Enable
#define LCD_RS 7     // PORTA.7 Register Select


//LCD commands
#define LCD_CLR 		0x01    // clear display
#define LCD_HOME 		0x02    // return home

#define LCD_INC 		0x06    // Increment, display freeze
#define LCD_MOV 		0x10    // Cursor move, not shift

#define LCD_OFF         0x08    // lcd off
#define LCD_ON          0x0C    // lcd on
#define LCD_BLINK_ON	0x0D    // blink on
#define LCD_CURSOR_ON	0x0E    // cursor on
#define LCD_ALL_ON	    0x0F    // cursor on /  blink on
#define LCD_LINE1  		0x80    // cursor Pos on line 1 (or with column)
#define LCD_LINE2  		0xC0    // cursor Pos on line 2 (or with column)

unsigned char chr,data,pos;

// writes a char to the LCD
void LCD_char(unsigned char data)

{
	PORTD = (data&0b11110000) >> 4; //high nibble
	PORTA |= 1<<LCD_RS;
	PORTA |= 1<<LCD_E;
	_delay_ms(2);
	PORTA &= ~(1<<LCD_E);
	_delay_ms(2);

	PORTD = (data&0b00001111); //low nibble
	PORTA |= 1<<LCD_RS;
	PORTA |= 1<<LCD_E;
	_delay_ms(2);
	PORTA &= ~(1<<LCD_E);
	_delay_ms(2);
}


// writes a instruction to the LCD
void LCD_inst(unsigned char inst)

{
	PORTD = (inst&0b11110000) >> 4; //send high nibble
	PORTA &= ~(1<<LCD_RS); // set RS to instructions
	PORTA |= 1<<LCD_E;
	_delay_ms(2);
	PORTA &= ~(1<<LCD_E);
	_delay_ms(2);

	PORTD = (inst&0b00001111); //send low nibble
	PORTA |= 1<<LCD_E;
	_delay_ms(2);
	PORTA &= ~(1<<LCD_E);
	_delay_ms(2);
}

// clear display
void LCDclr(void)
{
	LCD_inst (LCD_CLR);
}

// return home
void LCDhome(void)
{
	LCD_inst (LCD_HOME);
}

// LCD off
void LCDoff(void)
{
	LCD_inst (LCD_OFF);
}

// LCD on
void LCDon(void)
{
	LCD_inst (LCD_ON);
}

// cursor on
void LCDcursor(void)
{
	LCD_inst (LCD_CURSOR_ON);
}

// blink on
void LCDblink(void)
{
	LCD_inst (LCD_BLINK_ON);
}

// cursor all on
void LCDall(void)
{
	LCD_inst (LCD_ALL_ON);
}

//go to first line
void LCDline1 (void)

{
	LCD_inst (0b10000000);

}

//go to second line
void LCDline2 (void)

{
	LCD_inst (0b11000000);

}


// goto position x,y
void LCDgoto (char x,char y)
{

	if (y == 0)
	{
		pos = 0b00000000 + x;
	}

	else if (y == 1)
	{
		pos = 0b01000000 + x;
	}

	LCD_inst (0b10000000 | pos);

}

//write text to the LCD
void LCDtext(char *data)
{
	while (*data)
	{
		LCD_char(*data);
		data++;
	}
}

// init LCD

void LCD_init(void)
{
	DDRD = 0xFF;  // port D high nibble as output
	_delay_ms(40);

	LCD_inst(0x30);
	_delay_ms(4.1);
	LCD_inst(0x30);
	_delay_us(100);
	LCD_inst(0X30);
	_delay_us(50);
	
	//set 4-bit mode and 2-line
	LCD_inst (0b00101000);

	//turn on display and cursor
	LCD_inst (0b00001100);

	//clr display
	LCD_inst (LCD_CLR);

}


int main( void )
{
	LCD_init();
	LCDtext (">>AVR LCD DEMO<<");
	LCDgoto (2,1);
	LCDtext("Hello World!");
	LCDall();
	LCDhome();
}
 

hello,

I don't know AVR family, but C keep C langage...

read all remarks y made in your code ....
big delay before init the LCD..
You must presente the 4 bits data face on PortD D7..D4 not the reverse..
You can simplify Enable Pulse generation, if you don't use PortA bits 5 and 7 elsewhere.




Code:
// Title		: LCDinterface
// Software		: WINAVR GCC
// Description  : 4-bit LCD Interface

#define F_CPU 20000000UL
#include <avr/io.h>
#include <util/delay.h>

// used pins on port D
#define LCD_DB4 4    // PORTD.4
#define LCD_DB5 5    // PORTD.5
#define LCD_DB6 6    // PORTD.6
#define LCD_DB7 7    // PORTD.7
#define LCD_E  5     // PORTA.5 Enable
#define LCD_RS 7     // PORTA.7 Register Select


//LCD commands
#define LCD_CLR 		0x01    // clear display
#define LCD_HOME 		0x02    // return home

#define LCD_INC 		0x06    // Increment, display freeze
#define LCD_MOV 		0x10    // Cursor move, not shift

#define LCD_OFF         0x08    // lcd off
#define LCD_ON          0x0C    // lcd on
#define LCD_BLINK_ON	0x0D    // blink on
#define LCD_CURSOR_ON	0x0E    // cursor on
#define LCD_ALL_ON	    0x0F    // cursor on /  blink on
#define LCD_LINE1  		0x80    // cursor Pos on line 1 (or with column)
#define LCD_LINE2  		0xC0    // cursor Pos on line 2 (or with column)

unsigned char chr,data,pos;

[I][B]void Pulse_E()
{
	LCD_E=1;
	_delay_ms(1);
	LCD_E=0;
	_delay_ms(1);
}	
[/B][/I]

// writes a char to the LCD
void LCD_char(unsigned char data)
{  
	LCD_RS=1;  // LCD RS pin =1 for Data
//  hi nible RD4..RD7 are linked to LCD , no link between RD0..RD3 to LCD!!
//	PORTD = (data&0b11110000) >> 4; //high nibble
	[B]PORTD = (data&0b11110000); //high nibble[/B]

	Pulse_E();

// it 's more complicated to follow this kind of writing !
// you can modify PortA bit directly if not used for other purpose
//	PORTA |= 1<<LCD_RS;
//	PORTA |= 1<<LCD_E;
//	_delay_ms(2);
//	PORTA &= ~(1<<LCD_E);
//	_delay_ms(2);


//  low nible of DATA must be linked to Port D4..D7
//	PORTD = (data&0b00001111); //low nibble

	[B]PORTD = (data&0b00001111)<<4; //low nibble[/B]
	Pulse_E();

//	PORTA |= 1<<LCD_RS;
//	PORTA |= 1<<LCD_E;
//	_delay_ms(2);
//	PORTA &= ~(1<<LCD_E);
//	_delay_ms(2);
}


// writes a instruction to the LCD
void LCD_inst(unsigned char inst)

{
	LCD_RS=0;  // LCD RS pin =0 for commande
//	PORTD = (inst&0b11110000) >> 4; //send high nibble
	PORTD = (inst&0b11110000); //send high nibble
    Pulse_E();
	
//	PORTA &= ~(1<<LCD_RS); // set RS to instructions
//	PORTA |= 1<<LCD_E;
//	_delay_ms(2);
//	PORTA &= ~(1<<LCD_E);
//	_delay_ms(2);

//	PORTD = (inst&0b00001111); //send low nibble
	PORTD = (inst&0b00001111)<<4 ; //send low nibble
    Pulse_E();
	
//	PORTA |= 1<<LCD_E;
//	_delay_ms(2);
//	PORTA &= ~(1<<LCD_E);
//	_delay_ms(2);
}

// clear display
void LCDclr(void)
{
	LCD_inst (LCD_CLR);
}

// return home
void LCDhome(void)
{
	LCD_inst (LCD_HOME);
}

// LCD off
void LCDoff(void)
{
	LCD_inst (LCD_OFF);
}

// LCD on
void LCDon(void)
{
	LCD_inst (LCD_ON);
}

// cursor on
void LCDcursor(void)
{
	LCD_inst (LCD_CURSOR_ON);
}

// blink on
void LCDblink(void)
{
	LCD_inst (LCD_BLINK_ON);
}

// cursor all on
void LCDall(void)
{
	LCD_inst (LCD_ALL_ON);
}

//go to first line
void LCDline1 (void)
{
	LCD_inst (0b10000000);
}

//go to second line
void LCDline2 (void)
{
	LCD_inst (0b11000000);
}


// goto position x,y
void LCDgoto (char x,char y)
{
	if (y == 0)
	{
		pos = 0b00000000 + x;
	}
	else if (y == 1)
	{
		pos = 0b01000000 + x;
	}
	LCD_inst (0b10000000 | pos);
}

//write text to the LCD
void LCDtext(char *data)
{
	while (*data)
	{
		LCD_char(*data);
		data++;
	}
}

// init LCD

void LCD_init(void)
{
	DDRD = 0xFF;  //   port D high nibble as output
// sure FF is to define output.. on PIC FF is for inputs 
	LCD_inst(0x30);
[COLOR="#FF0000"][B]// float use inside delay ???[/B][/COLOR]
// _delay_ms(4.1); 
	_delay_ms(5);  
	LCD_inst(0x30);
	_delay_ms(5);  
	LCD_inst(0X30);
	_delay_ms(5);  
	//set 4-bit mode and 2-line
	LCD_inst (0b00101000);
	_delay_ms(1);  
	//turn on display and cursor
	LCD_inst (0b00001100);
	_delay_ms(1);  
	//clr display
	LCD_inst (LCD_CLR);

}


int main( void )
{	[B]_delay_ms(100);[/B]  // big delay necessary , wait voltage stabilisation
	LCD_init();
	LCDtext (">>AVR LCD DEMO<<");
	LCDgoto (2,1);
	LCDtext("Hello World!");
	LCDall();
	LCDhome();
}
 
hi Paul can you help me with your code, i tried to compile it but its complaining about LC_E and LC_RS
 

hello,

Sorry , i see the mistake
Code:
#define LCD_E  5     // PORTA.5 Enable
#define LCD_RS 7     // PORTA.7 Register Select

a bit confusing with C18 MPLAB with
#define LCD_E PORTAbits.RA5
we can do LCD_E=1;

I don't know if you have instruction to set or reset a bit with AVR MCU
i saw in your code you are using OR or AND to change only one bit..
replace change LCD_E and LCD_RS change bit by your OWN rule..
instead of LCD_E=1
PORTA = PORTA | 1<<LCD_E;
as you did before....
 

hi Paul !
the code compiled now but not displaying text in 4bit mode. (corrected for my mistake )

Code:
// Title		: LCDinterface
// Software		: WINAVR GCC
// Description  : 4-bit LCD Interface

#define F_CPU 20000000UL
#include <avr/io.h>
#include <util/delay.h>

// used pins on port D
#define LCD_DB4 4    // PORTD.4
#define LCD_DB5 5    // PORTD.5
#define LCD_DB6 6    // PORTD.6
#define LCD_DB7 7    // PORTD.7
#define LCD_E  PINA5     // PORTA.5 Enable
#define LCD_RS PINA7     // PORTA.7 Register Select


//LCD commands
#define LCD_CLR 		0x01    // clear display
#define LCD_HOME 		0x02    // return home

#define LCD_INC 		0x06    // Increment, display freeze
#define LCD_MOV 		0x10    // Cursor move, not shift

#define LCD_OFF         0x08    // lcd off
#define LCD_ON          0x0C    // lcd on
#define LCD_BLINK_ON	0x0D    // blink on
#define LCD_CURSOR_ON	0x0E    // cursor on
#define LCD_ALL_ON	    0x0F    // cursor on /  blink on
#define LCD_LINE1  		0x80    // cursor Pos on line 1 (or with column)
#define LCD_LINE2  		0xC0    // cursor Pos on line 2 (or with column)

unsigned char chr,data,pos;

void Pulse_E()
{
	PORTA = (PORTA | 1<<LCD_E);
	_delay_ms(1);
	PORTA &= ~(PORTA | 1<<LCD_E);
	_delay_ms(1);
}


// writes a char to the LCD
void LCD_char(unsigned char data)
{
	PORTA |= (1<<LCD_E);  // LCD RS pin =1 for Data
	PORTD = (data&0b11110000); //high nibble
    Pulse_E();

	PORTD = (data&0b00001111)<<4; //low nibble
	Pulse_E();

}


// writes a instruction to the LCD
void LCD_inst(unsigned char inst)

{
	PORTA &= ~(1<<LCD_E);        // LCD RS pin =0 for command
	PORTD = (inst&0b11110000);           //send high nibble
	Pulse_E();
	PORTD = (inst&0b00001111)<<4 ;       //send low nibble
	Pulse_E();
}

// clear display
void LCDclr(void)
{
	LCD_inst (LCD_CLR);
}

// return home
void LCDhome(void)
{
	LCD_inst (LCD_HOME);
}

// LCD off
void LCDoff(void)
{
	LCD_inst (LCD_OFF);
}

// LCD on
void LCDon(void)
{
	LCD_inst (LCD_ON);
}

// cursor on
void LCDcursor(void)
{
	LCD_inst (LCD_CURSOR_ON);
}

// blink on
void LCDblink(void)
{
	LCD_inst (LCD_BLINK_ON);
}

// cursor all on
void LCDall(void)
{
	LCD_inst (LCD_ALL_ON);
}

//go to first line
void LCDline1 (void)
{
	LCD_inst (0b10000000);
}

//go to second line
void LCDline2 (void)
{
	LCD_inst (0b11000000);
}


// goto position x,y
void LCDgoto (char x,char y)
{
	if (y == 0)
	{
		pos = 0b00000000 + x;
	}
	else if (y == 1)
	{
		pos = 0b01000000 + x;
	}
	LCD_inst (0b10000000 | pos);
}

//write text to the LCD
void LCDtext(char *data)
{
	while (*data)
	{
		LCD_char(*data);
		data++;
	}
}

// init LCD

void LCD_init(void)
{
	DDRD = 0xFF;  //   port D high nibble as output
	// sure FF is to define output.. on PIC FF is for inputs
	LCD_inst(0x30);
	// float use inside delay ???
	// _delay_ms(4.1);
	_delay_ms(5);
	LCD_inst(0x30);
	_delay_ms(5);
	LCD_inst(0X30);
	_delay_ms(5);
	//set 4-bit mode and 2-line
	LCD_inst (0b00101000);
	_delay_ms(1);
	//turn on display and cursor
	LCD_inst (0b00001100);
	_delay_ms(1);
	//clr display
	LCD_inst (LCD_CLR);

}


int main( void )
{	_delay_ms(100);  // big delay necessary , wait voltage stabilisation
	LCD_init();
	LCDtext (">>AVR LCD DEMO<<");
	LCDgoto (2,1);
	LCDtext("Hello World!");
	LCDall();
	LCDhome();
}

the following program I found online displays text but I cant do any modification to it , it breaks. e.g if i just put a clear screen command it start displaying garbage characters.

Code:
// Program to interface LCD in 4 bit mode with AVR microcontroller

#define F_CPU 20000000UL
#include<avr/io.h>
#include<util/delay.h>
#include<inttypes.h>

#define rs PINA7
#define rw PINA6
#define en PINA5

void lcd_init();
void dis_cmd(char);
void dis_data(char);
void lcdcmd(char);
void lcddata(char);

int main(void)
{
	unsigned char data0[11]="ENGINEERS";
	unsigned char data1[10]="GARAGE";
	
	int i=0;
	DDRD=0xFF;
	DDRA=0xFF;
	lcd_init();
	
	while(data0[i]!='\0')
	{
		dis_data(data0[i]);
		_delay_ms(200);
		i++;
	}
	
	dis_cmd(0xC5);
	
	i=0;
	while(data1[i]!='\0')
	{
		dis_data(data1[i]);
		_delay_ms(200);
		i++;
	}
	
	while(1) {};
}



void lcd_init()	// fuction for intialize
{
	dis_cmd(0x02);		// to initialize LCD in 4-bit mode.
	dis_cmd(0x28);		//to initialize LCD in 2 lines, 5X7 dots and 4bit mode.
	dis_cmd(0x0C);
	dis_cmd(0x06);
	dis_cmd(0x83);
}

void dis_cmd(char cmd_value)
{
	char cmd_value1;
	
	cmd_value1 = cmd_value & 0xF0;		//mask lower nibble because PD4-PD7 pins are used.
	lcdcmd(cmd_value1);			// send to LCD
	
	cmd_value1 = ((cmd_value<<4) & 0xF0);	//shift 4-bit and mask
	lcdcmd(cmd_value1);			// send to LCD
}


void dis_data(char data_value)
{
	char data_value1;
	
	data_value1=data_value&0xF0;
	lcddata(data_value1);
	
	data_value1=((data_value<<4)&0xF0);
	lcddata(data_value1);
}

void lcdcmd(char cmdout)
{
	PORTD = cmdout ;
	PORTA&=~(1<<rs);
	PORTA&=~(1<<rw);
	PORTA|=(1<<en);
	_delay_ms(1);
	PORTA&=~(1<<en);
}

void lcddata(char dataout)
{
	PORTD = dataout ;
	PORTA|=(1<<rs);
	PORTA&=~(1<<rw);
	PORTA|=(1<<en);
	_delay_ms(1);
	PORTA&=~(1<<en);
}
 
Last edited:

Can We see your LCD and MCU pin connection?
 

//used pins on port D
#define LCD_DB4 PIND0 // PORTD.4
#define LCD_DB5 PIND1 // PORTD.5
#define LCD_DB6 PIND2 // PORTD.6
#define LCD_DB7 PIND3 // PORTD.7
#define LCD_E PINA5 // PORTA.5 Enable
#define LCD_RS PINA7 // PORTA.7 Register Select

R/W is grounded.

- - - Updated - - -

also if i have something like this

PORTD = nibble (where nibble can have values 0x02 or 0x06 )

how can i modify it so that it only writes to the pin 0-3 of PORT D?
in the above example the whole of PORTD bits are effected.
 

hello,

try this..
Code:
void dis_data (unsigned char C1)
{
unsigned char dataout;
             dataout= C1 &0xF0;
// High  nible
    if(  dataout & 0x10) PORTD = PORTD | 0x10 ; else PORTD=PORTD & 0xEF ;
    if( dataout & 0x20) PORTD = PORTD | 0x20 ; else PORTD=PORTD & 0xDF ;
    if(  dataout & 0x40) PORTD = PORTD | 0x40 ; else PORTD=PORTD & 0xBF ;
    if(  dataout & 0x80) PORTD = PORTD | 0x80 ; else PORTD=PORTD & 0x7F ;
    PORTA|=(1<<rs);
    PORTA&=~(1<<rw);
    PORTA|=(1<<en);
    _delay_ms(1);
    PORTA&=~(1<<en);

// low nibble
            dataout=( C1 <<4) & 0x0F;
    if(  dataout & 0x10) PORTD = PORTD | 0x10 ; else PORTD=PORTD & 0xEF ;
    if( dataout & 0x20) PORTD = PORTD | 0x20 ; else PORTD=PORTD & 0xDF ;
    if(  dataout & 0x40) PORTD = PORTD | 0x40 ; else PORTD=PORTD & 0xBF ;
    if(  dataout & 0x80) PORTD = PORTD | 0x80 ; else PORTD=PORTD & 0x7F ;
    PORTA|=(1<<rs);
    //PORTA&=~(1<<rw);  // <- not used, RW tied to ground
    PORTA|=(1<<en);
    _delay_ms(1);
    PORTA&=~(1<<en);
}


only High nible of portD is modified ...
set or reset individual bit
do the same way for Cmd ...

- - - Updated - - -

hello


Error in the previous code post#14


Code:
// writes a char to the LCD
void LCD_char(unsigned char data)
{
    //[COLOR=#FF0000][B]PORTA |= (1<<LCD_E);  // LCD RS pin =1 for Data[/B][/COLOR]
    PORTA |= (1<<LCD_RS);  // LCD RS pin =1 for Data
    PORTD = (data&0b11110000); //high nibble
    Pulse_E();

    PORTD = (data&0b00001111)<<4; //low nibble
    Pulse_E();

}


// writes a instruction to the LCD
void LCD_inst(unsigned char inst)

{
    //[COLOR=#FF0000][B]PORTA &= ~(1<<LCD_E);      [/B][/COLOR]  // LCD RS pin =0 for command
      PORTA &= ~(1<<LCD_RS);        // LCD RS pin =0 for command
    PORTD = (inst&0b11110000);           //send high nibble
    Pulse_E();
    PORTD = (inst&0b00001111)<<4 ;       //send low nibble
    Pulse_E();
}
 

Status
Not open for further replies.

Similar threads

Cookies are required to use this site. You must accept them to continue using the site. Learn more…