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 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
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; 
}
 

hello,


The main change do you have to do is in the LCD init !!
show us your LCD init function
 

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.
 
may i know which lcd are you using now?
 
iam using the popular HD44780 .
 

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();
}
 
once again thank you for helping me out .
 

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

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top