Author Topic: PIC18F4550 to LCD 1602 - “Hello World” Attempt - Demo program problems. *Solved*  (Read 5291 times)

0 Members and 1 Guest are viewing this topic.

Offline t1dTopic starter

  • Super Contributor
  • ***
  • Posts: 1220
  • Country: us
Re: Windows 10/PIC18F4550/MPLAB X IDE v5.25/XC8 v2.10/PICKit2 V2.61/PICCircuits programmer/Built on my custom "Lunch Break" board, which is a "Pinguino" type PCB with sockets for the pin connections/All pin placements confirmed and checked for continuity/Pin to Pin wiring for control lines/Breadboard for the power distribution and the Contrast Pot./DuPont wires and a few jumpers.

I used this tutorial to make my first attempt at using a display with a PIC.
https://www.electronicwings.com/pic/lcd16x2-interfacing-with-pic18f4550
See file links.

It came with the code and hex. The compiler said that the code needed to be updated (pre-v5?.) I accepted that.

I cleaned/compiled the code and noticed that it did compile successfully, but with some errors. Then I thought to check to see if there was a hex provided in the project. There was, so I flashed it to the PIC to avoid the compiling errors.

All that the author’s hex displayed was “Ewings” on the top row from positions 0 through 6 and the back light. See picture. The character contrast will vary with the pot.


So, let’s compile the code and see what we get…
Code: [Select]
/*
 * Interfacing 16x2 LCD with PIC18F4550
 * [url=http://www.electronicwings.com]www.electronicwings.com[/url]
 */

#include <pic18f4550.h>
#include "Configuration_Header_File.h"

#define RS LATD0                    /*PORTD 0 pin is used for Register Select*/
#define EN LATD1                    /*PORTD 1 pin is used for Enable*/
#define ldata LATB                  /*PORTB is used for transmitting data to LCD*/
#define LCD_Port TRISB              /*define macros for PORTB Direction Register*/             
#define LCD_Control TRISD           /*define macros for PORTD Direction Register*/


void LCD_Init();
void LCD_Command(char );
void LCD_Char(char x);
void LCD_String(const char *);
void LCD_String_xy(char ,char ,const char*);
void MSdelay(unsigned int);
/*****************************Main Program*******************************/

void main(void)
{       
    OSCCON=0x72;                            /*Use Internal Oscillator with Frequency 8MHZ*/
    LCD_Init();                             /*Initialize 16x2 LCD*/
    LCD_String_xy(1,5,"Hello");             /*Display string at location(row,location).
                                             * This function passes string to display*/
    LCD_String_xy(2,0,"ElectronicWings");   /*Display string at location(row,location).
                                             * This function passes string to display*/   
   
    while(1);
}

/****************************Functions********************************/
void LCD_Init()
{
    MSdelay(15);           /*15ms,16x2 LCD Power on delay*/
    LCD_Port = 0x00;       /*Set PORTB as output PORT for LCD data(D0-D7) pins*/
    LCD_Control = 0x00;    /*Set PORTD as output PORT LCD Control(RS,EN) Pins*/
LCD_Command(0x38);     /*uses 2 line and initialize 5*7 matrix of LCD*/
    LCD_Command(0x01);     /*clear display screen*/
    LCD_Command(0x0c);     /*display on cursor off*/
    LCD_Command(0x06);     /*increment cursor (shift cursor to right)*/
}

void LCD_Clear()
{
    LCD_Command(0x01);     /*clear display screen*/
}

void LCD_Command(char cmd )
{
ldata= cmd;            /*Send data to PORT as a command for LCD*/   
RS = 0;                /*Command Register is selected*/
EN = 1;                /*High-to-Low pulse on Enable pin to latch data*/
NOP();
EN = 0;
MSdelay(3);
}

void LCD_Char(char dat)
{
ldata= dat;            /*Send data to LCD*/ 
RS = 1;                /*Data Register is selected*/
EN=1;                  /*High-to-Low pulse on Enable pin to latch data*/   
NOP();
EN=0;
    MSdelay(1);
}


void LCD_String(const char *msg)
{
while((*msg)!=0)
{
  LCD_Char(*msg);
  msg++;
    }
}

void LCD_String_xy(char row,char pos,const char *msg)
{
    char location=0;
    if(row<=1)
    {
        location=(0x80) | ((pos) & 0x0f); /*Print message on 1st row and desired location*/
        LCD_Command(location);
    }
    else
    {
        location=(0xC0) | ((pos) & 0x0f); /*Print message on 2nd row and desired location*/
        LCD_Command(location);   
    } 
    LCD_String(msg);
}

/*********************************Delay Function********************************/
void MSdelay(unsigned int val)
{
     unsigned int i,j;
        for(i=0;i<=val;i++)
            for(j=0;j<81;j++);      /*This count Provide delay of 1 ms for 8MHz Frequency */
 }

Here are the hiccups…

CLEAN SUCCESSFUL (total time: 78ms)
make -f nbproject/Makefile-default.mk SUBPROJECTS= .build-conf
make[1]: Entering directory 'C:/Users/t1dun/Documents/HP Compaq/Documents/Display/1602 Pic18F4550 Hello Test/PIC18F4550_LCD_16x2_8-bit_Project_File/LCD_16x2_8_bit.X'
make  -f nbproject/Makefile-default.mk dist/default/production/LCD_16x2_8_bit.X.production.hex
make[2]: Entering directory 'C:/Users/t1dun/Documents/HP Compaq/Documents/Display/1602 Pic18F4550 Hello Test/PIC18F4550_LCD_16x2_8-bit_Project_File/LCD_16x2_8_bit.X'
"C:\Program Files (x86)\Microchip\xc8\v2.10\bin\xc8-cc.exe"  -mcpu=18F4550 -c  -fno-short-double -fno-short-float -memi=wordwrite -fasmfile -maddrqual=ignore -xassembler-with-cpp -mwarn=-3 -Wa,-a -DXPRJ_default=default  -msummary=-psect,-class,+mem,-hex,-file  -ginhx032 -Wl,--data-init -mno-keep-startup -mno-download -mdefault-config-bits   -std=c99 -gdwarf-3 -mstack=compiled:auto:auto:auto     -o "build/default/production/LCD 16x2.p1" "LCD 16x2.c"
"C:\Program Files (x86)\Microchip\xc8\v2.10\bin\xc8-cc.exe"  -mcpu=18F4550 -Wl,-Map=dist/default/production/LCD_16x2_8_bit.X.production.map  -DXPRJ_default=default  -Wl,--defsym=__MPLAB_BUILD=1  -fno-short-double -fno-short-float -memi=wordwrite -fasmfile -maddrqual=ignore -xassembler-with-cpp -mwarn=-3 -Wa,-a -msummary=-psect,-class,+mem,-hex,-file  -ginhx032 -Wl,--data-init -mno-keep-startup -mno-download -mdefault-config-bits -std=c99 -gdwarf-3 -mstack=compiled:auto:auto:auto      -Wl,--memorysummary,dist/default/production/memoryfile.xml -o dist/default/production/LCD_16x2_8_bit.X.production.elf  "build/default/production/LCD 16x2.p1"     
LCD 16x2.c:48:: warning: (520) function "_LCD_Clear" is never called
LCD 16x2.c:27:: warning: (1518) direct function call made with an incomplete prototype (LCD_Init)

Memory Summary:
    Program space        used   184h (   388) of  8000h bytes   (  1.2%)
    Data space           used     Eh (    14) of   800h bytes   (  0.7%)
    Configuration bits   used     7h (     7) of     7h words   (100.0%)
    EEPROM space         used     0h (     0) of   100h bytes   (  0.0%)
    ID Location space    used     8h (     8) of     8h bytes   (100.0%)
    Data stack space     used     0h (     0) of   7A0h bytes   (  0.0%)

make[2]: Leaving directory 'C:/Users/t1dun/Documents/HP Compaq/Documents/Display/1602 Pic18F4550 Hello Test/PIC18F4550_LCD_16x2_8-bit_Project_File/LCD_16x2_8_bit.X'
make[1]: Leaving directory 'C:/Users/t1dun/Documents/HP Compaq/Documents/Display/1602 Pic18F4550 Hello Test/PIC18F4550_LCD_16x2_8-bit_Project_File/LCD_16x2_8_bit.X'

BUILD SUCCESSFUL (total time: 6s)
Loading code from C:/Users/t1dun/Documents/HP Compaq/Documents/Display/1602 Pic18F4550 Hello Test/PIC18F4550_LCD_16x2_8-bit_Project_File/LCD_16x2_8_bit.X/dist/default/production/LCD_16x2_8_bit.X.production.hex...
Loading completed

=========================================================================
So, I see various issues/possibilities…
1) The hex code was built on slightly different code and only contains (and was only intended to contain) the word “Ewings.” Meaning, that the display that I am seeing is what was intended to be displayed by the hex that was provided, but it is different than what is in the tutorial code.

2) LCD_Init(); /*Initialize 16x2 LCD*/ LCD_Init()
The warning is that LCD_Init(); is an incomplete prototype. To correct this I should add the word “void” as follows:
LCD_Init(void);

3) As the function void LCD_Clear() was never called in main, the data might be displayed in a confused way. To correct this I should add the call to clear in main as follows:
 LCD_Init(); /*Initialize 16x2 LCD*/
 LCD_Clear(); /*Corrective addition of call of the function to clear display.*/
 LCD_String_xy(1,5,"Hello"); /*Display string at location(row,location).

Please remember that I am very much a novice. These ideas are just my thoughts. And, even if I am correct in what I suggest needs to be done to make things right, I don’t really have a complete understanding. However, that is only natural, as I am still learning.

I look forward to your thoughts and suggestions. Thank you for your help.
« Last Edit: September 08, 2019, 08:06:41 pm by t1d »
 

Offline Kilrah

  • Supporter
  • ****
  • Posts: 1852
  • Country: ch
Re: PIC18F4550 to LCD 1602 - “Hello World” Attempt - Demo program problems.
« Reply #1 on: September 07, 2019, 02:54:20 pm »
What's the actual problem? What you got are warnings, not errors and the program compiled successfully. Did you try to flash the result and did it not work? You don't even mention trying to flash it.

 

Offline t1dTopic starter

  • Super Contributor
  • ***
  • Posts: 1220
  • Country: us
Re: PIC18F4550 to LCD 1602 - “Hello World” Attempt - Demo program problems.
« Reply #2 on: September 07, 2019, 03:28:06 pm »
Kilrah, thank you for your help.

The problem is that the tutorial says the display should read
Hello
ElectronicWings

 LCD_String_xy(1,5,"Hello");             /*Display string at location(row,location).
                                             * This function passes string to display*/
    LCD_String_xy(2,0,"ElectronicWings");   /*Display string at location(row,location).
                                             * This function passes string to display*/ 
However, it only reads
Ewings

I have suggested some solutions.

No, I did not flash the written code, because it has errors. Whether just warnings, or true failures, I would like to correct them, for the sake of learning.

Thanks, again.
 

Offline MarkF

  • Super Contributor
  • ***
  • Posts: 2543
  • Country: us
Re: PIC18F4550 to LCD 1602 - “Hello World” Attempt - Demo program problems.
« Reply #3 on: September 07, 2019, 05:00:59 pm »
I would start with a "clean slate" so you know what you are working with:
  • I downloaded their source code "PIC18F4550_LCD_16x2_8-bit_Project_File.zip"
  • Create a new empty PIC18F4550 project in MPLAB X
  • Copy two files from the zip into the new project:
          "Configuration_Header_File.h"
          "LCD 16x2.c"
  • It compiled without errors for me
  • Write hex file to PIC18F4550
  • Test
Now, you should have a "known" starting point.

The MPLAB X project may not be compatible with your version (Hence, create your own blank project and add ONLY their source code).

For reference:
Code: [Select]
CLEAN SUCCESSFUL (total time: 2ms)
make -f nbproject/Makefile-default.mk SUBPROJECTS= .build-conf
make[1]: Entering directory 'D:/Users/Mark/MPLABX/eWings.X'
make  -f nbproject/Makefile-default.mk dist/default/production/eWings.X.production.hex
make[2]: Entering directory 'D:/Users/Mark/MPLABX/eWings.X'
"C:\Program Files (x86)\Microchip\xc8\v2.10\bin\xc8-cc.exe"  -mcpu=18F4550 -c  -fno-short-double -fno-short-float -memi=wordwrite -O0 -fasmfile -maddrqual=ignore -xassembler-with-cpp -mwarn=-3 -Wa,-a -DXPRJ_default=default  -msummary=-psect,-class,+mem,-hex,-file  -ginhx032 -Wl,--data-init -mno-keep-startup -mno-download -mdefault-config-bits   -std=c99 -gdwarf-3 -mstack=compiled:auto:auto:auto     -o "build/default/production/LCD 16x2.p1" "LCD 16x2.c"
"C:\Program Files (x86)\Microchip\xc8\v2.10\bin\xc8-cc.exe"  -mcpu=18F4550 -Wl,-Map=dist/default/production/eWings.X.production.map  -DXPRJ_default=default  -Wl,--defsym=__MPLAB_BUILD=1  -fno-short-double -fno-short-float -memi=wordwrite -O0 -fasmfile -maddrqual=ignore -xassembler-with-cpp -mwarn=-3 -Wa,-a -msummary=-psect,-class,+mem,-hex,-file  -ginhx032 -Wl,--data-init -mno-keep-startup -mno-download -mdefault-config-bits -std=c99 -gdwarf-3 -mstack=compiled:auto:auto:auto      -Wl,--memorysummary,dist/default/production/memoryfile.xml -o dist/default/production/eWings.X.production.elf  "build/default/production/LCD 16x2.p1"     
LCD 16x2.c:48:: warning: (520) function "_LCD_Clear" is never called
LCD 16x2.c:27:: warning: (1518) direct function call made with an incomplete prototype (LCD_Init)

Memory Summary:
    Program space        used   184h (   388) of  8000h bytes   (  1.2%)
    Data space           used     Eh (    14) of   800h bytes   (  0.7%)
    Configuration bits   used     7h (     7) of     7h words   (100.0%)
    EEPROM space         used     0h (     0) of   100h bytes   (  0.0%)
    ID Location space    used     8h (     8) of     8h bytes   (100.0%)
    Data stack space     used     0h (     0) of   7A0h bytes   (  0.0%)

make[2]: Leaving directory 'D:/Users/Mark/MPLABX/eWings.X'
make[1]: Leaving directory 'D:/Users/Mark/MPLABX/eWings.X'

BUILD SUCCESSFUL (total time: 3s)
Loading code from D:/Users/Mark/MPLABX/eWings.X/dist/default/production/eWings.X.production.hex...
Loading completed
« Last Edit: September 07, 2019, 05:06:11 pm by MarkF »
 

Offline MarkF

  • Super Contributor
  • ***
  • Posts: 2543
  • Country: us
Re: PIC18F4550 to LCD 1602 - “Hello World” Attempt - Demo program problems.
« Reply #4 on: September 07, 2019, 05:14:03 pm »
The warning:
   LCD 16x2.c:48:: warning: (520) function "_LCD_Clear" is never called
is just what it says. The "LCD_Clear" function is not used.  Ignore it.  You might want it later on.



If you want to fix the warning:
   LCD 16x2.c:27:: warning: (1518) direct function call made with an incomplete prototype (LCD_Init)

Change line 16 to:
   void LCD_Init(void);

Change line 37 to:
   void LCD_Init(void)
« Last Edit: September 07, 2019, 05:19:31 pm by MarkF »
 
The following users thanked this post: t1d

Offline t1dTopic starter

  • Super Contributor
  • ***
  • Posts: 1220
  • Country: us
Re: PIC18F4550 to LCD 1602 - “Hello World” Attempt - Demo program problems.
« Reply #5 on: September 07, 2019, 05:27:09 pm »
Thanks, Mark! I will give your suggestions a try and report back.
 

Offline StillTrying

  • Super Contributor
  • ***
  • Posts: 2850
  • Country: se
  • Country: Broken Britain
Re: PIC18F4550 to LCD 1602 - “Hello World” Attempt - Demo program problems.
« Reply #6 on: September 07, 2019, 06:24:17 pm »
I'd simplify the print strings to
LCD_String_xy(1,1,"AB");
LCD_String_xy(2,2,"CD");
until you can get
AB
  CD
on the LCD, or at least see where it's going wrong.

 
« Last Edit: September 07, 2019, 06:26:06 pm by StillTrying »
.  That took much longer than I thought it would.
 

Offline Kilrah

  • Supporter
  • ****
  • Posts: 1852
  • Country: ch
Re: PIC18F4550 to LCD 1602 - “Hello World” Attempt - Demo program problems.
« Reply #7 on: September 07, 2019, 06:51:43 pm »
No, I did not flash the written code, because it has errors. Whether just warnings, or true failures, I would like to correct them, for the sake of learning.
It has warnings, not errors. They are relevant to "clean coding" and it's indeed be nice to learn about them, but are irrelevant to operation. If you want to troubleshoot you should flash your build. You do not know what the prebuilt hex contains (yes the source shows "Hello
ElectronicWings" , but you can never know if the hex really comes from that or if the author just forgot to update it from a point earlier where the source said "Ewings").

Also the hex contains chip configuration bits. If the author has a board that for example has a different clock source/speed than yours his hex won't work properly on yours (there is a significant chance that is your issue here). You need to edit/recreate the project and ensure it's properly configured for your hardware.
« Last Edit: September 07, 2019, 06:55:11 pm by Kilrah »
 

Offline ledtester

  • Super Contributor
  • ***
  • Posts: 3036
  • Country: us
Re: PIC18F4550 to LCD 1602 - “Hello World” Attempt - Demo program problems.
« Reply #8 on: September 08, 2019, 11:03:56 am »
Also the hex contains chip configuration bits. If the author has a board that for example has a different clock source/speed than yours his hex won't work properly on yours (there is a significant chance that is your issue here).

Yes - I would verify that the MSdelay function is working as expected. Just use it to toggle an LED - like 500ms on and 500ms off and check that it blinks once a second (or 15 times in 15 seconds, 30 times in 30 seconds, e.g.)
 

Offline t1dTopic starter

  • Super Contributor
  • ***
  • Posts: 1220
  • Country: us
Re: PIC18F4550 to LCD 1602 - “Hello World” Attempt - Demo program problems.
« Reply #9 on: September 08, 2019, 06:52:32 pm »


The warning:
   LCD 16x2.c:48:: warning: (520) function "_LCD_Clear" is never called
is just what it says. The "LCD_Clear" function is not used.  Ignore it.  You might want it later on.



If you want to fix the warning:
   LCD 16x2.c:27:: warning: (1518) direct function call made with an incomplete prototype (LCD_Init)

Change line 16 to:
   void LCD_Init(void);

Change line 37 to:
   void LCD_Init(void)
Mark had the perfect solution! I followed his directions and we had success! The one thing that I did different was that I just commented out the unused function.
 
I was having difficulty with the second line of the text not working. StillTrying's trick of changing the second line of the text helped me to determine that my (new) LCD has a bad second line. I changed to another one and got the full text.

I think I'll post our experience on the author's web page. The confusion about the difference in text and the small code errors...

You guys did great! Thank you so much for figuring it out.

P.S. I am posting our updated code here. The text reads "Thank You!!! on the first line and "Team EEVBLOG" on the second line.
There is a hex file: PIC18F4550_LCD_16x2_EEVB1.X/dist/default/production/(.HEX)

P.S.S. To be clear, I am not the author of the original project. I make no claim of authorship, or ownership. All rights remain with the original author.
« Last Edit: September 08, 2019, 07:32:42 pm by t1d »
 

Offline Dubbie

  • Supporter
  • ****
  • Posts: 1115
  • Country: nz
Re: PIC18F4550 to LCD 1602 - “Hello World” Attempt - Demo program problems.
« Reply #10 on: September 08, 2019, 08:01:36 pm »
The warnings are not code errors. The clear lcd function is in there because the minute you start a real project, you’ll need that function.
 

Offline MarkF

  • Super Contributor
  • ***
  • Posts: 2543
  • Country: us
Another thing you can do is replace the MSdelay() function with the built-in delay routine __delay_ms(milliseconds)
You also need to define the clock frequency (_XTAL_FREQ) for the routine to work.
See lines 9, 44, 64 and 74 below.

Usage:
   -Define _XTAL_FREQ
   -Use __delay_ms(x) for milliseconds
   -Use __delay_us(x) for microseconds

Code: [Select]
/*
 * Interfacing 16x2 LCD with PIC18F4550
 * [url=http://www.electronicwings.com]www.electronicwings.com[/url]
 */

//#include <pic18f4550.h>
#include "Configuration_Header_File.h"

#define _XTAL_FREQ 8000000L

#define RS LATD0                    /*PORTD 0 pin is used for Register Select*/
#define EN LATD1                    /*PORTD 1 pin is used for Enable*/
#define ldata LATB                  /*PORTB is used for transmitting data to LCD*/
#define LCD_Port TRISB              /*define macros for PORTB Direction Register*/
#define LCD_Control TRISD           /*define macros for PORTD Direction Register*/


void LCD_Init(void);
void LCD_Clear(void);
void LCD_Command(char);
void LCD_Char(char x);
void LCD_String(const char*);
void LCD_String_xy(char, char, const char*);

/*****************************Main Program*******************************/
void main(void)
{
   OSCCON = 0x72;                          /*Use Internal Oscillator with Frequency 8 MHZ*/

   LCD_Init();                             /*Initialize 16x2 LCD*/

   LCD_String_xy(1,5,"Hello");             /*Display string at location(row,location).
                                            * This function passes string to display*/

   LCD_String_xy(2,0,"ElectronicWings");   /*Display string at location(row,location).
                                            * This function passes string to display*/

   while(1);
}

/****************************Functions********************************/
void LCD_Init(void)
{
   __delay_ms(15);        /*15ms,16x2 LCD Power on delay*/
   LCD_Port = 0x00;       /*Set PORTB as output PORT for LCD data(D0-D7) pins*/
   LCD_Control = 0x00;    /*Set PORTD as output PORT LCD Control(RS,EN) Pins*/
   LCD_Command(0x38);     /*uses 2 line and initialize 5*7 matrix of LCD*/
   LCD_Command(0x01);     /*clear display screen*/
   LCD_Command(0x0c);     /*display on cursor off*/
   LCD_Command(0x06);     /*increment cursor (shift cursor to right)*/
}

void LCD_Clear(void)
{
   LCD_Command(0x01);     /*clear display screen*/
}

void LCD_Command(char cmd)
{
   ldata = cmd;           /*Send data to PORT as a command for LCD*/
   RS = 0;                /*Command Register is selected*/
   EN = 1;                /*High-to-Low pulse on Enable pin to latch data*/
   NOP();
   EN = 0;
   __delay_ms(3);
}

void LCD_Char(char dat)
{
   ldata = dat;           /*Send data to LCD*/
   RS = 1;                /*Data Register is selected*/
   EN = 1;                /*High-to-Low pulse on Enable pin to latch data*/
   NOP();
   EN = 0;
   __delay_ms(1);
}

void LCD_String(const char *msg)
{
   while((*msg)!=0)
   {
      LCD_Char(*msg);
      msg++;
   }
}

void LCD_String_xy(char row, char pos, const char *msg)
{
   char location = 0;

   if(row<=1)
   {
      location = (0x80) | ((pos) & 0x0f); /*Print message on 1st row and desired location*/
      LCD_Command(location);
   }
   else
   {
      location = (0xC0) | ((pos) & 0x0f); /*Print message on 2nd row and desired location*/
      LCD_Command(location);
   }
   LCD_String(msg);
}

« Last Edit: September 08, 2019, 08:51:26 pm by MarkF »
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf