LCD

Jswale

Joined Jun 30, 2015
121
That is strange! So it does show full initialization and gives me the impression that the LCD is not blown after all.
Can you post the most up to date code?

Reasons include wiring being incorrect, incorrect power rails, current surges.

#pragma config PWRT = OFF
Set this to ON.
 

Thread Starter

KansaiRobot

Joined Jan 15, 2010
324
Same thing happens although the black squares more often

C:
/*
* File:   main.c
*Here we have adapted the code from JohninTx that is originally for 16F1787
* to our processor 18F4553
*
* Created on 2015/08/06, 16:57
*/

//#include <stdio.h>
#include <stdlib.h>

#include <xc.h>

// #pragma config statements should precede project file includes.

#pragma config PLLDIV = 5  //(20MHz crystal div by 5 preescale
#pragma config CPUDIV = OSC4_PLL6  //we get 16 MHz
#pragma config FOSC = INTOSC_HS   //Internal oscillator, HS oscillator used by USB (INTHS)
#pragma config USBDIV = 2  //Usb from PLL
#pragma config FCMEN    = OFF   // fail safe clock disabled
#pragma config IESO = OFF  //oscillator switch over mode disabke
#pragma config PWRT = ON //OFF
#pragma config BOR = ON  //CHANGED
#pragma config BORV=3 //ADDED
#pragma config VREGEN = ON //CHANGED
#pragma config WDT = OFF
#pragma config WDTPS = 32768


#pragma config CCP2MX = ON
#pragma config PBADEN = OFF
#pragma config LPT1OSC = OFF

#pragma config MCLRE = ON

#pragma config STVREN = ON
#pragma config LVP = OFF
#pragma config ICPRT = OFF
#pragma config XINST = OFF
#pragma config DEBUG = OFF
#pragma config WRTD = OFF



#define _XTAL_FREQ 4000000      // 4MHz for the delay function

void initIO(void)
{
OSCCON = 0x62; // 0110 0010 set CPU Frequency as 4 MHz Internal Oscillator
TRISD=0x00;
PORTD=0x00;
//no analog inputs on D

}

//---------------------IO DEFINITIONS  --------------------------
// These are for the F4553
#define lcd_port  LATD        // write to LAT, read from PORT
// RD7-4 is the LCD 4 bit databus
#define LCD_RSout LATD2     // moved from ICSP
#define LCD_ENout LATD3

//-------------------- DISPLAY SETTINGS  ---------------------
// Define some display settings.  These could be defined as complete
// commands as well..
#define lcdLINE1 0x00       // where line 1 begins
#define lcdLINE2 0x40       // where line 2 begins

//--------------------- STROBE LCD ---------------------------
// Pulses E line on LCD to write
int strobeLCD(void)
{
LCD_ENout = 1;
__delay_us(2);     // Added a little here
LCD_ENout = 0;
}

//--------------------- WRITE 8 BIT DATA TO LCD  -----------------
// Assumes LCD is ready and RS is set to correct value
// LCD data bus is RD4-RD7
// Enable cycle time is a side effect of execution time - faster clocks
// may require a specific delay.
void writeLCD(unsigned char dat)
{
    lcd_port &= 0x0f;               // get current port, clear upper bits
    lcd_port |= (dat & 0xf0);       // combine w/upper nibble, leave lower same
    strobeLCD();

    __delay_us(1);

    lcd_port &= 0x0f;               // get current port, clear upper bits
    lcd_port |= ((dat <<4) & (0xf0)); // combine w/lower nibble, leave lower port same
    strobeLCD();
    __delay_ms(2);                // wait for display to process
}
//-------------------- WRITE LCD COMMAND  -------------------------
// Write cmd to LCD with RS=0
// Assumes E is low and display is NOT busy
void lcd_cmd (unsigned char cmd)
{
    LCD_RSout = 0;       // select command register

    __delay_us(1);

       writeLCD(cmd);
}
//---------------------- WRITE LCD DATA  --------------------------
// Write dat to LCD with RS=1
// Assumes E is low and display is NOT busy
void lcd_data (unsigned char dat)
{
    LCD_RSout = 1;       // select data register

    __delay_us(1);

    writeLCD(dat);
}

//-------------------- RESET/CONFIGURE LCD  -------------------------
// Delays are generous, trim when able

void lcd_init(void)
{
    lcd_port &= 0x0f;   // clear upper bits of LCD port
    lcd_port |= 0x30;   // direct data to LCD DB7-4
    LCD_RSout = 0;
    strobeLCD();        // write 3h, wait 10ms
    __delay_ms(10);
    strobeLCD();        // write 3h, wait..
    __delay_ms(10);
     strobeLCD();       // write 3h
    __delay_ms(10);

   lcd_port &= 0x0f;    // clear upper bits of LCD port
   lcd_port |= 0x20;    // direct data to LCD DB7-4
   strobeLCD();         // write 2h
   __delay_ms(10);

    lcd_cmd(0x28);       // Funciton Set: 4-bit mode - 2 line - 5x7 font.
    lcd_cmd(0x0e);       // DisplayON, cursor ON, blink OFF
    lcd_cmd(0x06);       // Automatic Increment - No Display shift.
    lcd_cmd(0x80);       // Address DDRAM with 0 offset 80h.
}

//----------------------- WRITE STRING TO LCD  ---------------------
// Writes null terminated string to LCD from ROM
void lcd_WriteStr(const unsigned char *c)
{
    while(*c != '\0'){
        lcd_data(*c);
        c++;
    }
}

//--------------------  SETS CURSOR ANYWHERE IN DISPLAY MEMORY  ---------
// Valid locations are 0-79 decimal.  This doesn't check for valid location

void lcd_SetCursor(unsigned char loc)
{
    lcd_cmd(loc | 0x80);        // form and send 'set DDRAM address' cmd
}

//----------------- CANNED LINE COMMANDS  -------------------------
// For a 2 line display

void lcd_LINE1(void)
{
    lcd_SetCursor(lcdLINE1);
}

void lcd_LINE2(void)
{
    lcd_SetCursor(lcdLINE2);
}

//======================= MAIN =====================================
const char spin[] = {".oOo. "};

int main(int argc, char** argv)
{
    unsigned char i;
    initIO();               // init the chip IO
    __delay_ms(100);        // power up delay for LCD - adjust as necessary
    __delay_ms(100);
    __delay_ms(100);
    lcd_init();             // init the LCD

    lcd_cmd(0x01);

    lcd_cmd(0x80);
    lcd_WriteStr("Kansai Robot-HH");
    lcd_cmd(0xC0);
    lcd_WriteStr("Salutes You XXX");
    while(1);


   
/*    lcd_WriteStr("Howdy there");
    lcd_LINE2();
    lcd_WriteStr("from TX!");
    // a little active display :)
    do{
        for(i=0; spin[i]!= '\0'; i++){
            lcd_SetCursor(lcdLINE2 + 11); // locate spinner
            lcd_data(spin[i]);
            __delay_ms(100);
            __delay_ms(100);
//            __delay_ms(200);
        }
    }while(1);       // do forever


*/



    return (EXIT_SUCCESS);
}
 

Jswale

Joined Jun 30, 2015
121
C:
//======================= MAIN =====================================

void main(void)
{
    initIO();               // init the chip IO
    __delay_ms(100);        // power up delay for LCD - adjust as necessary
    __delay_ms(100);
    __delay_ms(100);
    lcd_init();             // init the LCD

    lcd_cmd(0x80);
    lcd_WriteStr("Kansai Robot-HH");

    lcd_cmd(0xC0);
    lcd_WriteStr("Salutes You XXX");

    while(1);
}

Also check the delays are correct by rotating a pin ON/OFF on the pic and measuring the width of the pulse, try __delay_ms(50);


Try this. I can't figure out why it works after RESETs and not straight away, but give it a go.
 

nerdegutta

Joined Dec 15, 2009
2,684
I can't figure out why it works after RESETs and not straight away, but give it a go.
Perhaps a small delay to wait for oscillator to get stable will help. (I haven't read the new code, so it might be a delay doing that. In that case, don't pay attention to this post.) :)
 

atferrari

Joined Jan 6, 2004
4,771
Hola KR,

I know you use C but, if you are eventually interested, I could post the code (Assembler) I wrote very long time ago.

BTW, also long time ago I stopped reading the BUSY flag because, up to now, I never did anything so pressing to need that check to write again immediately.

Finally, to minimize the H/W, I use the R/W pin grounded. Two pins for power, two for E & RS plus 4 more for data. Few days ago, while writing my own code for the 1Wire protocol, the LCD proved to be helpful and certainly simple to use. I use long wires (well, some centimeters...) to keep it out of the way in my breadboard while still visible. For me at least, it works.
 

Attachments

JohnInTX

Joined Jun 26, 2012
4,787
What could be the possible reasons for some parts of the LCD blown???
Your display has a controller and an extender - the 2ed smaller black blob. That could explain why you can write to the first 8 char in each line but the 2ed half of each line is junk - maybe you blew the extender.

Anorher possibility is that the character addressing is different i.e. you have to adjust the DDADR after the 8th char in each line. Check the datasheet.

Try sending a CLEAR SCREEN command. If the junk chars disappear, I would suspect an addressing problem. If not, I think its toast.

The fact that you got to the 'salute' message says that the basics are working but it sounds like some more power up delay for the LCD may be needed (works after PIC reset).
 

Thread Starter

KansaiRobot

Joined Jan 15, 2010
324
Thank you for all the help.
I have to report that I went to the store, bought another LCD, soldered the connectors and tried the program.
It seems to be working well!!

I think JohninTx is right, the extender must be blown and probably the first blob (controller??) is unstable too...
OpenCVCapture1.jpg

I have one question though. Are LCDs this delicate?? or did I just stumble into a particularly broken one???
Now it is working , everytime I RESET it it immediately shows the message but when I just turn it on (I mean when I turn on the 5V power) for a fraction of a second I can see the whole line of black squares and it scares me :eek::D... why do you think that happens? is that just initialization? why it doesnt happen on reset??



Thank you again to all of you :). Now I can continue with my multi processor project (that I will post later) in which I would appreciate any insights as well.
 

nsaspook

Joined Aug 27, 2009
13,310
I have one question though. Are LCDs this delicate?? or did I just stumble into a particularly broken one???
Now it is working , everytime I RESET it it immediately shows the message but when I just turn it on (I mean when I turn on the 5V power) for a fraction of a second I can see the whole line of black squares and it scares me :eek::D... why do you think that happens? is that just initialization? why it doesnt happen on reset??
The LCD controller chip does a power up routine (where it checks the DDRAM/CGRAM) that can take up to 500ms to complete, once that's done and flagged inside the reset routine is usually less than 1ms.
 
Last edited:

JohnInTX

Joined Jun 26, 2012
4,787
+1 Some of these take a long time to come up BUT ALSO, if you don't have a pulldown on the E line, you can send garbage to the LCD while the PIC is initializing. If you cycle the 5v, be sure that it is off long enough to fully reset all of the devices, discharge MCLR caps, etc.
 

Jswale

Joined Jun 30, 2015
121
What is the difference between the power up and resetting the device? Will the LCD not take just as long to come up because it will need reinitialising and will also run through the code from the beginning...
 

JohnInTX

Joined Jun 26, 2012
4,787
When you hit reset, the lcd has already completed its power up and is ready for another shot at the init sequence.

What does the datasheet say about cold start (power up) time?
 

nerdegutta

Joined Dec 15, 2009
2,684
What is the difference between the power up and resetting the device? Will the LCD not take just as long to come up because it will need reinitialising and will also run through the code from the beginning...
When resetting the MCU, you are doing just that. Resetting the MCU. If you disconnect the power, you reset the MCU and the LCD. The LCD needs a little more time to "boot".
 

Jswale

Joined Jun 30, 2015
121
Once powered on there is a 300ms delay required... but that is implemented in the code. So once the MCU is reset that delay will be stepped through anyway wouldn't it?
 

nsaspook

Joined Aug 27, 2009
13,310
Once powered on there is a 300ms delay required... but that is implemented in the code. So once the MCU is reset that delay will be stepped through anyway wouldn't it?
No, internally usually the controller knows if the 'cold-start' flag is set/unset and will bypass that portition of the code on reboot.

A typical controller will have many boot flags that can be checked to see why the boot is happening like power fail, watchdog timeout, stack-overun, reset. You can check these flags to modify the firmware logic flow.
 
Top