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.

[PIC] Problem with MCLR in 16x2 LCD in PIC16F876A

Status
Not open for further replies.

richardlaishram

Member level 4
Member level 4
Joined
Jan 6, 2013
Messages
77
Helped
6
Reputation
12
Reaction score
6
Trophy points
1,298
Location
Planet Earth
Visit site
Activity points
1,804
Every time I power on the board, the LCD shows some garbage characters and I have to press MCLR button to make it work. Following are the details of my code. Please let me know if there is any error with the code. It works fine with Proteus.

Configuration:
__CONFIG(FOSC_HS & WDTE_ON & PWRTE_ON & CP_OFF & BOREN_ON & LVP_OFF & CPD_OFF & DEBUG_OFF);

LCD Initialization Code (4 bit Mode):

Code:
void ToggleEpinOfLCD(void)
{
	LCD_E = 1;                // Give a pulse on E pin
	__delay_us(E_Delay);      // so that LCD can latch the
	LCD_E = 0;                // data from data bus
	__delay_us(E_Delay); 	
}


void WriteCommandToLCD(unsigned char Command)  
{
	LCD_RS = 0;				  // Command
	__delay_ms(40);
	
	PORTD &= 0x0F;			  // Make Data pins zero
	PORTD |= (Command&0xF0);  // Write Upper nibble of data
	ToggleEpinOfLCD();		  // Give pulse on E pin	
	
	PORTD &= 0x0F;			  // Make Data pins zero
	PORTD |= ((Command<<4)&0xF0); // Write Lower nibble of data
	ToggleEpinOfLCD();		  // Give pulse on E pin
}


void WriteDataToLCD(char LCDChar)  
{
	LCD_RS = 1;				  // It is data
	__delay_ms(40);
	
	PORTD &= 0x0F;			  // Make Data pins zero
	PORTD |= (LCDChar&0xF0);  // Write Upper nibble of data
	ToggleEpinOfLCD();		  // Give pulse on E pin	
	
	PORTD &= 0x0F;			  // Make Data pins zero
	PORTD |= ((LCDChar<<4)&0xF0); // Write Lower nibble of data
	ToggleEpinOfLCD();		  // Give pulse on E pin
}


void InitLCD(void)
{ 
	// Firstly make all pins output
	LCD_E  		 		 = 0;   // E  = 0
	LCD_RS  	 		 = 0;   // RS = 0
	LCD_Data_Bus_D4		 = 0;  	// Data bus = 0
	LCD_Data_Bus_D5		 = 0;  	// Data bus = 0
	LCD_Data_Bus_D6		 = 0;  	// Data bus = 0
	LCD_Data_Bus_D7		 = 0;  	// Data bus = 0
	LCD_E_Dir    		 = 0;   // Make Output
	LCD_RS_Dir    	 	 = 0;   // Make Output
	LCD_Data_Bus_Dir_D4  = 0;   // Make Output
	LCD_Data_Bus_Dir_D5  = 0;   // Make Output
	LCD_Data_Bus_Dir_D6  = 0;   // Make Output
	LCD_Data_Bus_Dir_D7  = 0;   // Make Output

   __delay_ms(40);
   
	PORTD &= 0x0F;			  // Make Data pins zero
	PORTD |= 0x30;			  // Write 0x3 value on data bus
	ToggleEpinOfLCD();		  // Give pulse on E pin

   __delay_ms(20);

	PORTD &= 0x0F;			  // Make Data pins zero
	PORTD |= 0x30;			  // Write 0x3 value on data bus
	ToggleEpinOfLCD();		  // Give pulse on E pin

   __delay_ms(20);

	PORTD &= 0x0F;			  // Make Data pins zero
	PORTD |= 0x30;			  // Write 0x3 value on data bus
	ToggleEpinOfLCD();		  // Give pulse on E pin

   __delay_ms(20);
   
	PORTD &= 0x0F;			  // Make Data pins zero
	PORTD |= 0x20;			  // Write 0x2 value on data bus
	ToggleEpinOfLCD();		  // Give pulse on E pin
	
	__delay_ms(20);

	WriteCommandToLCD(0x28);    //function set
	__delay_ms(20);
	WriteCommandToLCD(0x0c);    //display on,cursor off,blink off
	__delay_ms(20);
	WriteCommandToLCD(0x01);    //clear display
	__delay_ms(20);
	WriteCommandToLCD(0x06);    //entry mode, set increment
}


void WriteStringToLCD(const char *s)
{
	while(*s)
		WriteDataToLCD(*s++);   // print first character on LCD 
}


void ClearLCDScreen(void)       // Clear the Screen and return cursor to zero position
{
	WriteCommandToLCD(0x01);    // Clear the screen
	__delay_ms(20);              // Delay for cursor to return at zero position
}

I want the code to display the proper lines when I power up the board. Please help and thanks in advance.
 

Hi,

Cannot help with the C code, but would say you need the Config WDTE = OFF and try BOREN = OFF
 

I think that the issue here is that you have not given enough time for the LCD set itself up.
Give some delay before calling the lnitLCD() function for the LCD to power up fully and also give some time after the function.
About 50ms each should be good enough.
 

hello


Where is your main code ?


void main()
{
__delay_ms(200);
InitLCD();
WriteStringToLCD("Hello ");
... etc ..
while(1);
}
 

but would say you need the Config WDTE = OFF and try BOREN = OFF
I tried with the WDTE_OFF and I'm not seeing anything in the LCD, not even some garbage character.

Main Code:

Code:
void main()
{
	__delay_ms(100);
	InitLCD();
	WriteCommandToLCD(0x80);
	WriteStringToLCD("Hello World!!");
	__delay_ms(500);
	ClearLCDScreen();
}

I even tried increasing the delays and putting some extra LCD initialization steps...
Code:
PORTD &= 0x0F;			  // Make Data pins zero
PORTD |= 0x30;			  // Write 0x3 value on data bus
ToggleEpinOfLCD();		  // Give pulse on E pin

Has LCD somehow related with the Vref and Vref+ because somehow in the PICDEM-2 Plus board I'm able to write in the LCD by adding an extra
Code:
ADCON1=0x0E;
which is basically setting Vref+ and Vref- as Vdd and Vss respectively. I'm really confused. Please help.
 

Hi,
first remove 0s in output lines you don need them just initialize the direction registers......

Second you don need a lot of delay first time 20ms second time 5ms third time 1ms after that 40us is enough between commands and datas....
 

1) in your code there is no while(1) loop

2)
Code:
void InitLCD(void)
{ 
	// Firstly make all pins output
	LCD_E  		 		 = 0;   // E  = 0
	LCD_RS  	 		 = 0;   // RS = 0
	LCD_Data_Bus_D4		 = 0;  	// Data bus = 0
	LCD_Data_Bus_D5		 = 0;  	// Data bus = 0
	LCD_Data_Bus_D6		 = 0;  	// Data bus = 0
	LCD_Data_Bus_D7		 = 0;  	// Data bus = 0
	LCD_E_Dir    		 = 0;   // Make Output
	LCD_RS_Dir    	 	 = 0;   // Make Output
	LCD_Data_Bus_Dir_D4  = 0;   // Make Output
	LCD_Data_Bus_Dir_D5  = 0;   // Make Output
	LCD_Data_Bus_Dir_D6  = 0;   // Make Output
	LCD_Data_Bus_Dir_D7  = 0;   // Make Output

   __delay_ms(40);
   
	PORTD &= 0x0F;			  // Make Data pins zero
	PORTD |= 0x30;			  // Write 0x3 value on data bus
	ToggleEpinOfLCD();		  // Give pulse on E pin

   __delay_ms(20);

	PORTD &= 0x0F;			  // Make Data pins zero
	PORTD |= 0x30;			  // Write 0x3 value on data bus
	ToggleEpinOfLCD();		  // Give pulse on E pin

   __delay_ms(20);

	PORTD &= 0x0F;			  // Make Data pins zero
	PORTD |= 0x30;			  // Write 0x3 value on data bus
	ToggleEpinOfLCD();		  // Give pulse on E pin

   __delay_ms(20);
   
	PORTD &= 0x0F;			  // Make Data pins zero
	PORTD |= 0x20;			  // Write 0x2 value on data bus
	ToggleEpinOfLCD();		  // Give pulse on E pin
	
	__delay_ms(20);

	WriteCommandToLCD(0x28);    //function set
//	__delay_ms(20);
	WriteCommandToLCD(0x0c);    //display on,cursor off,blink off
//	__delay_ms(20);
	WriteCommandToLCD(0x01);    //clear display
//	__delay_ms(20);
	WriteCommandToLCD(0x06);    //entry mode, set increment
}
and also use less delay in initlcd() function as Venkadesh_M mentioned .
 

Tried again... The same problem persists. Is there any chances that there's some noise in the board. Kindly share me where the error might crept in. :cry:

- - - Updated - - -

Here is the actual code:

Code:
OPTION_REG &= 0x7F
void main()
{
unsigned int Mode=1,;
TRISB = 1;
PORTB = 0x00;
TRISA=1;
ADCON1=0x0E;
__delay_ms(50);
InitLCD();
WriteCommandToLCD(0x80);
WriteStringToLCD("Initializing...");
__delay_ms(500);
ClearLCDScreen();
while(1)
{
if(MSel == 1)
{
	while(MSel == 1);
	__delay_ms(20);
	Mode = eeprom_read(0);
	Mode++;
	eeprom_write(0, Mode);
	if(eeprom_read(0) == 6)
	eeprom_write(0, 1);
	WriteCommandToLCD(0x80);
	WriteStringToLCD("Mode:");
	WriteDataToLCD(eeprom_read(0)+0x30);
}

- - - Updated - - -

When I press the MCLR button, the LCD displays Black boxes on all the character units, like it's displayed serially if I press and hold the MCLR button. What might be the problem, if this information helps. I'm really in a big trouble :cry:
 

I think you are trying the example program from a website Don worry at last its going to be fine......
but the time matters try some other working program from this forum itself.........
 

I think you are trying the example program from a website Don worry at last its going to be fine......
but the time matters try some other working program from this forum itself.........
Yes, I have taken some sample codes from websites, I have done a little editing. The code is working perfectly fine in Proteus and also if I press the MCLR button once, it's working perfectly fine. The only problem is that the LCD is showing some garbage character on powering up for the first time. I'm worried whether my board is having some problem or do I need to define anything for the actual board to work.
 

Hi,

Are you sure your hardware is wired correctly ? has it ever displayed anything correctly ?

Looking back at your earlier posts you were using a 877A and 4 line display, now it a 876A and a 2 line display.

Can you give fuller details of your dev board and lcd wiring / current set up etc.

How are you programming the 876A, in a dedicated programmer socket or icsp ?

Might then be able to send you a proven .hex file to test out your board/lcd
 

Are you sure your hardware is wired correctly ? has it ever displayed anything correctly ?
Yes, once the MCLR button is pressed, it's working perfectly fine. Also I'm able to use the same code for both 16x2 and 20x4 LCD. For programming the PIC, I'm using MPLAB ICD 3 and PICDEM 2 Plus Demo Board. Previously I tried with the PIC16F877A which is a 40PIN PDIP, so I shifted to PIC16F876A which is a 28PIN PDIP. I'm facing the same problem in both the cases. The board is designed like in the Proteus Simulation and for 5V Supply I'm using the 7805 Voltage regulator. Crystal is connected along with two capacitances as mentioned. I have attached the whole project as zip. Please have a look. Thanks in advance.

- - - Updated - - -

I'm using the LCD in 4-Bit mode. The RW pin of LCD is grounded.
 

Attachments

  • PIC16F876A_LCD_With_Error.rar
    113.3 KB · Views: 92

hello

in InitLCD
initialize first the bit direction
Code:
void InitLCD(void)
{ 
	// Firstly make all pins output
[COLOR="#0000CD"]	LCD_E_Dir    		 = 0;   // Make Output
	LCD_RS_Dir    	  = 0;   // Make Output
	LCD_Data_Bus_Dir_D4  = 0;   // Make Output
	LCD_Data_Bus_Dir_D5  = 0;   // Make Output
	LCD_Data_Bus_Dir_D6  = 0;   // Make Output
	LCD_Data_Bus_Dir_D7  = 0;   // Make Output[/COLOR]

	LCD_E  		 	 = 0;   // E  = 0
	LCD_RS  	 		 = 0;   // RS = 0
	LCD_Data_Bus_D4		 = 0;  	// Data bus = 0
	LCD_Data_Bus_D5		 = 0;  	// Data bus = 0
	LCD_Data_Bus_D6		 = 0;  	// Data bus = 0
	LCD_Data_Bus_D7		 = 0;  	// Data bus = 0
 

Hi I can say a idea to check it out

Code C - [expand]
1
2
__delay_ms(1000);
__delay_ms(1000);


put this lines on main of declaring variable and before all initialization look and tell what is happening????????
 

So what you learned is don worry for any problem there will be solution I told the same in #6, did you tried it??
Yes sir, I tried it. Sorry, but ii was in the wrong part. I removed the PORTD &= 0x0F; and used only PORTD |= 0x30; in the InitLCD function, again it was not working. I was not clear with what you have said earlier, else it would have been resolved much earlier :-(
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top