PIC16F1459 & LCD PC1602LRS config

Thread Starter

Jswale

Joined Jun 30, 2015
121
Okay I have had a major breakthrough, on the back it showed the pin numbers (which I hadn't seen till now)...left to right, 15,16,1.....14. Therefore it was wired up wrong, but it is a strange pin config. I have wired it up properly and now the PIC transmits the signals and the LCD receives them. There does look to be life from the LCD but it seems to fade out after a few seconds. Both the PIC and LCD are warm now though so that shows communication atleast.
 

Thread Starter

Jswale

Joined Jun 30, 2015
121
This is what happens when I run the code with the HELLO write enabled, it doesn't fade out but just stays like this until I cut the power.

I don't need to ground DB0-3 do i?

Just seems strange the exact code worked for @nerdegutta
 

Attachments

Last edited:

Thread Starter

Jswale

Joined Jun 30, 2015
121
Last edited:

JohnInTX

Joined Jun 26, 2012
4,787
Its possible that you've smoked the LCD driver. Do you have another LCD?
I'm puzzled why you indicated that the contrast control worked when it was wired incorrectly. Anyway, neither the PIC nor the LCD should get warm in operation, they are both CMOS devices.

You don't need to ground DB0-3 to make it work but its a good idea for a final design.
@nerdegutta 's LCD worked because the code does. Walk through our code vs. the code in your (very good) link, to see if it does the same sequence, I think it does.
 

Thread Starter

Jswale

Joined Jun 30, 2015
121
Yeh the LCD doesn't get warm anymore, the power supply was at a wrong value.
I have gone through the simulation in our code and it looks perfect!

The function 0x28 for example,
runs like;
DB7-DB4
0010 (En=0)
0010 (En=1)
0010 (En=0)
1000 (En=0)
1000 (En=1)
1000 (En=0)

It does this for ALL the commands so looks perfect, yet it doesn't want to work.
 

Thread Starter

Jswale

Joined Jun 30, 2015
121
I have just been testing the lcd_data by changing what symbol is sent before the while(1) and the values on the PIC are always correct, e.g '!' is 0001 and '#' is 0011 (lower nibble)
 

Thread Starter

Jswale

Joined Jun 30, 2015
121
VSS and VDD were the wrong way round. The LCD is displaying what it did previously but obviously there is no way to test the LCD is there?

Yeah the wiring is correct;

VSS-0v
VDD-5v
Vo- POT
RS-RC2
RW-0v
E-RC3

DB4-RC4
DB5-RC5
DB6-RC6
DB7-RC7
 

JohnInTX

Joined Jun 26, 2012
4,787
I'll buy a second LCD, any suggestions for ease of initialization etc etc?
I think we have the init covered. If Vss and Vdd were interchanged, the LCD is toast. The PIC might be unhappy as well if your power supply was >5V or a port was sinking too much current...

Unfortunately the way to test the LCD is to plug it into a known-working circuit..
 

Thread Starter

Jswale

Joined Jun 30, 2015
121
The PIC seems fine, the pins seem to be working as expected as I scope them.

I will re-order this LCD, should come tomorrow.
 

Thread Starter

Jswale

Joined Jun 30, 2015
121
Here is the completed Initialization code.

Code:
// PIC16F1459 Configuration Bit Settings
// 'C' source line config statements
#include <xc.h>
// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.
// CONFIG1
#pragma config FOSC = INTOSC    // Oscillator Selection Bits (INTOSC oscillator: I/O function on CLKIN pin)
#pragma config WDTE = OFF       // Watchdog Timer Enable (WDT disabled)
#pragma config PWRTE = ON       // Power-up Timer Enable (PWRT enabled)
#pragma config MCLRE = ON       // MCLR Pin Function Select (MCLR/VPP pin function is MCLR)
#pragma config CP = OFF         // Flash Program Memory Code Protection (Program memory code protection is disabled)
#pragma config BOREN = OFF      // Brown-out Reset Enable (Brown-out Reset disabled)
#pragma config CLKOUTEN = OFF   // Clock Out Enable (CLKOUT function is disabled. I/O or oscillator function on the CLKOUT pin)
#pragma config IESO = ON        // Internal/External Switchover Mode (Internal/External Switchover Mode is enabled)
#pragma config FCMEN = ON       // Fail-Safe Clock Monitor Enable (Fail-Safe Clock Monitor is enabled)
// CONFIG2
#pragma config WRT = OFF        // Flash Memory Self-Write Protection (Write protection off)
#pragma config CPUDIV = NOCLKDIV// CPU System Clock Selection Bit (NO CPU system divide)
#pragma config USBLSCLK = 48MHz // USB Low SPeed Clock Selection bit (System clock expects 48 MHz, FS/LS USB CLKENs divide-by is set to 8.)
#pragma config PLLMULT = 3x     // PLL Multipler Selection Bit (3x Output Frequency Selected)
#pragma config PLLEN = ENABLED  // PLL Enable Bit (3x or 4x PLL Enabled)
#pragma config STVREN = ON      // Stack Overflow/Underflow Reset Enable (Stack Overflow or Underflow will cause a Reset)
#pragma config BORV = LO        // Brown-out Reset Voltage Selection (Brown-out Reset Voltage (Vbor), low trip point selected.)
#pragma config LPBOR = OFF      // Low-Power Brown Out Reset (Low-Power BOR is disabled)
#pragma config LVP = OFF        // Low-Voltage Programming Enable (High-voltage on MCLR/VPP must be used for programming)
#define _XTAL_FREQ 4000000      // 4MHz for now
//---------------------IO DEFINITIONS  --------------------------
#define lcd_port  LATC        // write to LAT, read from PORT
// RC7-4 is the LCD 4 bit databus
#define LCD_RSout LATC2     // moved from ICSP
#define LCD_ENout LATC3
// RC0,RC1 reserved for ICSP DEBUG
//--------------------- 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 RC4-RC7
// 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();
    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  --------------------
// Assumes E is low and display is NOT busy
void lcd_cmd (unsigned char cmd)
{
    LCD_RSout = 0;       // select command register
    writeLCD(cmd);
}
//---------------------- WRITE LCD DATA  --------------------------
void lcd_data (unsigned char dat)
{
    LCD_RSout = 1;       // select data register
    writeLCD(dat);
}
//-------------------- RESET/CONFIGURE LCD  -------------------------
// Delays are generous, trim when able
void lcd_reset()
{
    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);
}
//------------------------ INIT AND CONFIGURE LCD  ---------------------
void lcd_init ()
{
    __delay_ms(100);   // power up delay for LCD

    lcd_reset();         // LCD reset
    __delay_ms(1);
    lcd_cmd(0x02);        // Switches to 4 bit mode
    lcd_cmd(0x28);       // Funciton Set: 4-bit mode - 2 line - 5x7 font.
    lcd_cmd(0x08);        // Display ON/OFF Control, NOT Cursor etc
    lcd_cmd(0x01);        // Clear Display
    lcd_cmd(0x06);       // Automatic Increment - No Display shift.DisplayON, cursor ON, blink ON
    //End of initialization
    lcd_cmd(0x0C);       // DisplayON, cursor ON, blink ON
    lcd_cmd(0x80);       // Address DDRAM with 0 offset 80h.
}
//======================= MAIN =====================================
void main ()
{
    OSCCON = 0b00110100;  // Internal oscillator = 4MHz (for now)
    TRISC=0b00000000;
    PORTC=0b00000000;
    ANSELC=0b00000000;
    TRISB=0b00000000;
    PORTB=0b00000000;
    ANSELB=0b00000000;
    TRISA=0b00000000;
    PORTA=0b00000000;
    ANSELA=0b00000000;
    lcd_init();

    //lcd_data("H");  // a flashing cursor will do for now
    //lcd_data("H");
   // lcd_data("H");
 
    while(1);       // wait forever
}//main
 

JohnInTX

Joined Jun 26, 2012
4,787
lcd_cmd(0x02); // Switches to 4 bit mode
Oops. Lost that one.. Sorry. But you'll have to put it into lcd_reset, it is only a 4bit write like the others in lcd_init:
C:
//-------------------- RESET/CONFIGURE LCD  -------------------------
// Delays are generous, trim when able
void lcd_reset()
{
    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);
}
 

JohnInTX

Joined Jun 26, 2012
4,787
How does this compile for you? Do you have the 20-pin version of the PIC16F1454?
It compiles OK - @Jswale is using the 1459 which is 20pins.
Question for you @nerdegutta , since I dropped that last init line (the switch to 4 bits) was that why your setup didn't go past the cursor I wonder? Anyway, thanks for doing that and hopefully we all are just about there.
Regards,
JinTX
 

nerdegutta

Joined Dec 15, 2009
2,684
I think I got some 14-pins 16F1454. Somewhere. Now I'm curious. I'll make a breadboard setup with one of those on Sunday.

I'm the best man in a wedding tomorrow, so I'll better be there. No time to do Nerdy stuff...

I did try the last setup/init but I didn't get past the cursor. The IC seemed dead slow. After programming it, it usually restart after a few seconds. Now I have to remove the power.

Well, I'll be back on Sunday.
 

JohnInTX

Joined Jun 26, 2012
4,787
@nerdegutta is probably down for the count after the wedding :cool:
So, I got a wild hair and also wired up a display, debugged it and here it is. The last posted code #92 (and mine too) missed some things but they are all in/fixed now. I built it on a different PIC but still enhanced midrange. Works for me and should work for you too.

Howdy.jpg

Here's the code. You will notice some #defines that spec the processor. I left them set up for the 16F1459 so you shouldn't have any trouble compiling for that one. The IO assignments are the same for both chips. Ignore all the F1787 stuff.
When it runs it has an active thingie that gives the processor something to do AND will allow you to tune the timings, etc. while its running.
I would not say that this is the definitive way to run the display but good for now.
BTW: Be sure to add a pull-down resistor to the display E line to keep the display de-selected while the PIC is in reset.
Enjoy.
EDIT: Attached a schematic for reference.

C:
//========================== BASIC LCD INIT/USE =============================
// This is a demo file for Jswale to get his display on line.  It was tested
// using a 16F1787 which is also enhanced midrange.  A few routines have
// been added to demonstrate how to move the cursor, create command primatives
// etc.
//--------------------------- SELECT THE TARGET  ------------------------------
// Uncomment the define to select beteween 16F1787 and 16F1459

//#define P1787 // This is what I developed on.
#define P1459 // uncomment this to build for the 16F1489

#ifdef P1459
//-------------------------- BUILD FOR 16F1459  ---------------------------------
// PIC16F1459 Configuration Bit Settings
// 'C' source line config statements
#include <xc.h>
// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.
// CONFIG1
#pragma config FOSC = INTOSC    // Oscillator Selection Bits (INTOSC oscillator: I/O function on CLKIN pin)
#pragma config WDTE = OFF       // Watchdog Timer Enable (WDT disabled)
#pragma config PWRTE = ON       // Power-up Timer Enable (PWRT enabled)
#pragma config MCLRE = ON       // MCLR Pin Function Select (MCLR/VPP pin function is MCLR)
#pragma config CP = OFF         // Flash Program Memory Code Protection (Program memory code protection is disabled)
#pragma config BOREN = OFF      // Brown-out Reset Enable (Brown-out Reset disabled)
#pragma config CLKOUTEN = OFF   // Clock Out Enable (CLKOUT function is disabled. I/O or oscillator function on the CLKOUT pin)
#pragma config IESO = ON        // Internal/External Switchover Mode (Internal/External Switchover Mode is enabled)
#pragma config FCMEN = ON       // Fail-Safe Clock Monitor Enable (Fail-Safe Clock Monitor is enabled)
// CONFIG2
#pragma config WRT = OFF        // Flash Memory Self-Write Protection (Write protection off)
#pragma config CPUDIV = NOCLKDIV// CPU System Clock Selection Bit (NO CPU system divide)
#pragma config USBLSCLK = 48MHz // USB Low SPeed Clock Selection bit (System clock expects 48 MHz, FS/LS USB CLKENs divide-by is set to 8.)
#pragma config PLLMULT = 3x     // PLL Multipler Selection Bit (3x Output Frequency Selected)
#pragma config PLLEN = ENABLED  // PLL Enable Bit (3x or 4x PLL Enabled)
#pragma config STVREN = ON      // Stack Overflow/Underflow Reset Enable (Stack Overflow or Underflow will cause a Reset)
#pragma config BORV = LO        // Brown-out Reset Voltage Selection (Brown-out Reset Voltage (Vbor), low trip point selected.)
#pragma config LPBOR = OFF      // Low-Power Brown Out Reset (Low-Power BOR is disabled)
#pragma config LVP = OFF        // Low-Voltage Programming Enable (High-voltage on MCLR/VPP must be used for programming)

#define _XTAL_FREQ 4000000      // 4MHz for now

//---------------------INIT IO -----------------------------------
void initIO(void){
    OSCCON = 0b00110100;  // Internal oscillator = 4MHz (for now)
    TRISC=0b00000000;
    PORTC=0b00000000;
    ANSELC=0b00000000;
    TRISB=0b00000000;
    PORTB=0b00000000;
    ANSELB=0b00000000;
    TRISA=0b00000000;
    PORTA=0b00000000;
    ANSELA=0b00000000;
}
#endif

//---------------------------- BUILD FOR 16F1787  ------------------------------
// JohnInTX built this on a 16F1787 - More pins but same core. External canned
// oscillator too.

#ifdef P1787
#include <xc.h>
#define _XTAL_FREQ 4000000      // 4MHz for now
#include "P1787_IO.h"           // Put 1787-specific IO inits in header file
                                // to avoid confusioin
void initIO(void)
{
    ANSELA = ANSELAinit;    // ANSELs are in BANK3
    ANSELB = ANSELBinit;
    ANSELD = ANSELDinit;
    ANSELE = ANSELEinit;

    WPUA = WPUAinit;        // Weak pullups in BANK4
    WPUB = WPUBinit;
    WPUC = WPUCinit;
    WPUD = WPUDinit;
    WPUE = WPUEinit;

    ODCONA = ODCONAinit;    //Open Drain controls in BANK5
    ODCONB = ODCONBinit;
    ODCONC = ODCONCinit;
    ODCOND = ODCONDinit;
    ODCONE = ODCONEinit;

    SLRCONA = SLRCONAinit;  // Slew Rate Controls in BANK6
    SLRCONB = SLRCONBinit;
    SLRCONC = SLRCONCinit;
    SLRCOND = SLRCONDinit;
    SLRCONE = SLRCONEinit;

    INLVLA = INLVLAinit;    // Input level controls in BANK7
    INLVLB = INLVLBinit;
    INLVLC = INLVLCinit;
    INLVLD = INLVLDinit;
    INLVLE = INLVLEinit;

    LATA = LATAinit;        // LAT in BANK2
    LATB = LATBinit;
    LATC = LATCinit;
    LATD = LATDinit;
    LATE = LATEinit;

    TRISA = TRISAinit;      // TRIS in BANK1
    TRISB = TRISBinit;
    TRISC = TRISCinit;
    TRISD = TRISDinit;
    TRISE = TRISEinit;
}
#endif

//---------------------IO DEFINITIONS  --------------------------
// These are for the 1459 - 1787 uses same..
#define lcd_port  LATC        // write to LAT, read from PORT
// RC7-4 is the LCD 4 bit databus
#define LCD_RSout LATC2     // moved from ICSP
#define LCD_ENout LATC3
// RC0,RC1 reserved for ICSP DEBUG

//-------------------- 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 RC4-RC7
// 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();

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

void main (void)
{
    unsigned char i;

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

    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(200);
        }
    }while(1);       // do forever
}//main
 

Attachments

Last edited:

Thread Starter

Jswale

Joined Jun 30, 2015
121
Run the code above but commented out line 56 to line 110 and get the errors,

Warning [228] C:\mplab\LCDTest.c; 11.1 illegal character (0xFFFFFFA0)
Error [1361] C:\mplab\LCDTest.c; 20.1 syntax error in configuration argument
Error [1361] C:\mplab\LCDTest.c; 21.1 syntax error in configuration argument
Error [1361] C:\mplab\LCDTest.c; 22.1 syntax error in configuration argument
Error [1361] C:\mplab\LCDTest.c; 23.1 syntax error in configuration argument
Error [1361] C:\mplab\LCDTest.c; 24.1 syntax error in configuration argument
Error [1361] C:\mplab\LCDTest.c; 25.1 syntax error in configuration argument
Error [1361] C:\mplab\LCDTest.c; 26.1 syntax error in configuration argument
Error [1361] C:\mplab\LCDTest.c; 27.1 syntax error in configuration argument
Error [1361] C:\mplab\LCDTest.c; 28.1 syntax error in configuration argument
Error [1361] C:\mplab\LCDTest.c; 30.1 syntax error in configuration argument
Error [1361] C:\mplab\LCDTest.c; 33.1 syntax error in configuration argument
Error [1361] C:\mplab\LCDTest.c; 34.1 syntax error in configuration argument
Error [1361] C:\mplab\LCDTest.c; 35.1 syntax error in configuration argument
Error [1361] C:\mplab\LCDTest.c; 36.1 syntax error in configuration argument
Error [1361] C:\mplab\LCDTest.c; 37.1 syntax error in configuration argument
Error [1361] C:\mplab\LCDTest.c; 38.1 syntax error in configuration argument

Got a new display too and it looks much better.

I am using MPLAB (NOT MPLABX) if that will cause it.
 
Last edited:
Top