PIC18F4550 to LCD 1602 - “Hello World” Attempt - Demo program problems. *Solved* - Page 1
Forum section: electronics / general

author: t1d
author_rank: Super Contributor
timestamp: September 07, 2019, 02:50:40 pm
content: 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-pic18f4550See 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:/** Interfacing 16x2 LCD with PIC18F4550* [url=http://www.electronicwings.com]www.electronicwings.com*/#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-confmake: 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.hexmake: 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 calledLCD 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: 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: 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.

author: Kilrah
author_rank: Unknown
timestamp: September 07, 2019, 02:54:20 pm
content: 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.

author: t1d
author_rank: Super Contributor
timestamp: September 07, 2019, 03:28:06 pm
content: Kilrah, thank you for your help.The problem is that the tutorial says the display should readHelloElectronicWingsLCD_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 readsEwingsI 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.

author: MarkF
author_rank: Super Contributor
timestamp: September 07, 2019, 05:00:59 pm
content: 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 XCopy two files from the zip into the new project:"Configuration_Header_File.h""LCD 16x2.c"It compiled without errors for meWrite hex file to PIC18F4550TestNow, 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:CLEAN SUCCESSFUL (total time: 2ms)make -f nbproject/Makefile-default.mk SUBPROJECTS= .build-confmake: Entering directory 'D:/Users/Mark/MPLABX/eWings.X'make -f nbproject/Makefile-default.mk dist/default/production/eWings.X.production.hexmake: 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 calledLCD 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: Leaving directory 'D:/Users/Mark/MPLABX/eWings.X'make: 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

author: MarkF
author_rank: Super Contributor
timestamp: September 07, 2019, 05:14:03 pm
content: The warning:LCD 16x2.c:48:: warning: (520) function "_LCD_Clear" is never calledis 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)

author: t1d
author_rank: Super Contributor
timestamp: September 07, 2019, 05:27:09 pm
content: Thanks, Mark! I will give your suggestions a try and report back.

author: StillTrying
author_rank: Super Contributor
timestamp: September 07, 2019, 06:24:17 pm
content: I'd simplify the print strings toLCD_String_xy(1,1,"AB");LCD_String_xy(2,2,"CD");until you can getABCDon the LCD, or at least see where it's going wrong.

author: Kilrah
author_rank: Unknown
timestamp: September 07, 2019, 06:51:43 pm
content: Quote from: t1d on September 07, 2019, 03:28:06 pmIt 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 "HelloElectronicWings" , 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.

author: ledtester
author_rank: Super Contributor
timestamp: September 08, 2019, 11:03:56 am
content: Quote from: Kilrah on September 07, 2019, 06:51:43 pmYes - 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.)

author: t1d
author_rank: Super Contributor
timestamp: September 08, 2019, 06:52:32 pm
content: Quote from: MarkF on September 07, 2019, 05:14:03 pmMark 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.

author: Dubbie
author_rank: Unknown
timestamp: September 08, 2019, 08:01:36 pm
content: 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.

author: MarkF
author_rank: Super Contributor
timestamp: September 08, 2019, 08:39:57 pm
content: 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 microsecondsCode:/** Interfacing 16x2 LCD with PIC18F4550* [url=http://www.electronicwings.com]www.electronicwings.com*///#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);}