# PIC16F877A (with LCD) not working

I have designed a PIC18F877A micro controller project to read temperature from an LM35 using ADC, display it on an LCD and transmit it to a serial port.

When the program starts, sometimes it shows a startup message - sometimes it doesn't display anything. Also, the serial port connection is not working. Can anyone help - am I missing something? Are there any ground connections missing?

My code:

#include <16F877A.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=20000000)
#use rs232 (baud=9600,rcv=PIN_C7, xmit=PIN_C6)
#include <lcd.c>
float value;
float temp;
float temp2;
float temp3;
float temp4;
float temp5[14];
float count[14];
int c;
void main(void)
{
while(1)
{
lcd_init();
lcd_gotoxy (1,1);
delay_ms(1000);
printf(lcd_putc,"   WELCOME TO\n Micro Tech Sol.");
delay_ms(3000);
lcd_gotoxy (1,1);
printf(lcd_putc,"  Fuel Monitoring \n     PROJECT   ");
delay_ms(3000);
}

}

• Do you have a power-up delay before you start initializing the display? If not, try waiting 1s before doing anything with your uC. This is because the VDD might rise slowly when drawing much current (by a backlight, e.g.). – user17592 Mar 17 '13 at 12:04
• Each Vdd-Vss pair of pins should be decoupled close to the chip. – Leon Heller Mar 17 '13 at 12:18
• please show your code and compiler details, If your code is able to display welcome message then the chances of hardware to be faulty is just aprox 10%. Major chances can be in coding logic error. – Abdul Rehman Mar 17 '13 at 13:38
• Where's the initialization delay? I don't see it. Also: lcd_init() is in the while(1) loop. You're initializing the LCD continuously! – user17592 Mar 17 '13 at 14:39
• Have both Vdd pins been decoupled? This is like pulling teeth! – Leon Heller Mar 17 '13 at 14:47

1. Your comment "Its working some times which may mean code is working." means (to me) that the hardware isn't fried (it wouldn't work at all otherwise) and that your software needs adjustment.

2. You might want to use an unused GPIO pin as a 'heartbeat' signal, and toggle it through various places in your while loop. This allows you to not only make sure your code isn't getting lost (with your simple program, it shouldn't be) but also whether or not your overall timing is valid. For example, you can set the pin before one of your delays then clear it afterwards. If you see the pin change state for 1 second, you know that your crystal is working, the PIC oscillator is set properly and that your delays are working.

3. There may be some incompatibility between the LCD driver you're using and the specific LCD that you're working with. You may need to tweak that LCD code - add extra delays, etc. until your LCD cooperates.

4. lcd_init() and a delay(1000) need to go outside the while loop, as others have said. You need that delay(1000) after calling lcd_init() before any commands are sent - you may need a slightly longer delay depending on your specific LCD hardware.

• He also needs a delay before lcd_init() to allow VDD to rise to a respectable level. – user17592 Mar 17 '13 at 16:37
• ... if the PIC doesn't have brown-out detection. – Adam Lawrence Mar 17 '13 at 17:36
• A brown-out is for when the PIC can't operate anymore. The LCD might have a higher minimum supply voltage, which is why I was always recommended to do a delay before initializing the display. However, when testing shows that for that particular application the delay isn't needed, you can leave it out. – user17592 Mar 17 '13 at 17:43
• What I'm used to seeing when BOR is enabled is that the power-on timer doesn't start until after BOR clears - even on the first power-up - which is around 4V or so. When it isn't enabled, the timer starts up at a lower voltage. This gives you some 'free' headroom improvement in VDD without an explicit delay. That being said, a start-up delay is fairly standard practice for those parts that use lots of extra peripherals and don't spend time doing things like waiting for the PLL to synchronize and the clock to change. – Adam Lawrence Mar 17 '13 at 17:52
• Well, you probably know a lot more about this than me, so you're probably right ;-) – user17592 Mar 17 '13 at 18:35

Do following things,

• Call lcd_init() function outside the while(1) loop,
• Call lcd_clear() before re-writing on same position (e.g. xy(1,1), just a test case, not required, you can overwrite any character of the lcd, but by clearing the lcd is just can be a test case if your gotoxy() function is working properly or not)
• Most importantly verify your crystals frequency

Try removing capacitors across the crystal, try changing the crystal, and if you can try using 4Mhz crystal. Using capacitors with high frequency crystal some time causes problems there check for datasheet for proper capacitors value to attach, better to use some lower frequency crystal or by removing capacitors with same crystal

• Also make sure you do not change the fuse bits at the time of flash burning, make them same as you mentioned in your code, brown out detect and power up timer will be preferable to use.
• Why should you call lcd_clear()? I never do that. You can just overwrite characters. – user17592 Mar 17 '13 at 16:31
• lcd_clear() is not working with Pic C compiler returning undefined error. – sharafjaffri Mar 18 '13 at 7:35
• lcd_clear() mean try to clear the lcd, it can be done by sending 0x01 command to lcd – Abdul Rehman Mar 18 '13 at 11:48