PIC18F4550 Interfacing with LCD using XC8 compiler

Thread Starter

devilarm123

Joined Dec 26, 2017
33
Here is a new 'init' routine. Note that I do not have your hardware so this is untested code.
C:
void lcd_init(void)
{
TRISD = 0x00;
LATD = 0x00;

LCD_RS = 0; // write control bytes
__delay_ms(15); // power on delay
lcd_write_cmd(0x30);
__delay_ms(5);
lcd_write_cmd(0x30);
__delay_us(100);
lcd_write_cmd(0x30);
__delay_ms(5);
lcd_write_cmd(0x20);// set 4 bit mode
__delay_us(40);
lcd_write_cmd(0x28); // 4 bit mode, 1/16 duty, 5x8 font
lcd_write_cmd(0x08); // display off
lcd_write_cmd(0x0F); // display on, blink curson on
lcd_write_cmd(0x06); // entry mode
}

make -f nbproject/Makefile-default.mk SUBPROJECTS= .build-conf
make[1]: Entering directory 'C:/Users/Angus/Desktop/draft2.X'
make -f nbproject/Makefile-default.mk dist/default/production/draft2.X.production.hex
make[2]: Entering directory 'C:/Users/Angus/Desktop/draft2.X'
"C:\Program Files (x86)\Microchip\xc8\v1.35\bin\xc8.exe" --pass1 --chip=18F4550 -Q -G --double=24 --float=24 --emi=wordwrite --opt=default,+asm,+asmfile,-speed,+space,-debug --addrqual=ignore --mode=free -P -N255 --warn=-3 --asmlist --summary=default,-psect,-class,+mem,-hex,-file --codeoffset=100 --output=default,-inhx032 --runtime=default,+clear,+init,-keep,-no_startup,-download,+config,+clib,-plib --output=-mcof,+elf:multilocs --stack=compiled:auto:auto:auto "--errformat=%f:%l: error: (%n) %s" "--warnformat=%f:%l: warning: (%n) %s" "--msgformat=%f:%l: advisory: (%n) %s" -obuild/default/production/lcd_utilities.p1 lcd_utilities.c
lcd_utilities.c:21: error: (255) not a member of the struct/union ""
lcd_utilities.c:21: error: (182) illegal conversion between types
int -> volatile union S271
lcd_utilities.c:51: error: (255) not a member of the struct/union ""
lcd_utilities.c:51: error: (182) illegal conversion between types
make[2]: *** [build/default/production/lcd_utilities.p1] Error 1
make[1]: *** [.build-conf] Error 2
int -> volatile union S271
(908) exit status = 1
nbproject/Makefile-default.mk:126: recipe for target 'build/default/production/lcd_utilities.p1' failed
make[2]: Leaving directory 'C:/Users/Angus/Desktop/draft2.X'
nbproject/Makefile-default.mk:78: recipe for target '.build-conf' failed
make[1]: Leaving directory 'C:/Users/Angus/Desktop/draft2.X'
make: *** [.build-impl] Error 2
nbproject/Makefile-impl.mk:39: recipe for target '.build-impl' failed

BUILD FAILED (exit value 2, total time: 613ms)


I tried and I got this error code, Im also currently testing the lcd_write_string
 

Thread Starter

devilarm123

Joined Dec 26, 2017
33
Which lines did it indicate were wrong?
Looks like lines 21 and 51 of lcd_utilities.c
C:
void lcd_write_cmd(unsigned char cmd)
{
    unsigned char temp2;
    LCD_RS = 0;                    // Select LCD for command mode  [B]<-- line 21[/B]
    __delay_ms(4);                // 40us delay for LCD to settle down
    temp2 = cmd;
    temp2 = temp2 >> 4;            // Output upper 4 bits, by shifting out lower 4 bits
    temp2 = temp2 & 0x0f;
    LATD = LATD & 0xf0;
    LATD = LATD | temp2;        // Output to PORTD which is connected to LCD

    __delay_ms(8);            // 10ms - Delay at least 1 ms before strobing
    lcd_strobe();
  
    __delay_ms(8);            // 10ms - Delay at least 1 ms after strobing

    temp2 = cmd;                // Re-initialise temp2
    LATD = LATD & 0xf0;
    LATD = LATD | temp2;        // Mask out upper 4 bits

    __delay_ms(8);            // 10ms - Delay at least 1 ms before strobing
    lcd_strobe();
    __delay_ms(8);            // 10ms - Delay at least 1 ms before strobing

}

//---- Function to write a character data to the LCD ---------------------------

void lcd_init(void)
{
TRISD = 0x00;
LATD = 0x00;

LCD_RS = 0; // write control bytes [B]<-----51[/B]
__delay_ms(15); // power on delay
lcd_write_cmd(0x30);
__delay_ms(5);
lcd_write_cmd(0x30);
__delay_us(100);
lcd_write_cmd(0x30);
__delay_ms(5);
lcd_write_cmd(0x20);// set 4 bit mode
__delay_us(40);
lcd_write_cmd(0x28); // 4 bit mode, 1/16 duty, 5x8 font
lcd_write_cmd(0x08); // display off
lcd_write_cmd(0x0F); // display on, blink curson on
lcd_write_cmd(0x06); // entry mode
}
Moderators note : Please use code tags for code=c to annotate C code.
 

Thread Starter

devilarm123

Joined Dec 26, 2017
33
If the LCD is displaying single characters correctly then the lcd_init( ) is supposedly working.
You cannot write a string to the LCD using lcd_write_data(i) on its own. You need another function to write an entire string.

Check the lcd.h file for the appropriate function. If it does not have the string function you can write your own.
C:
void lcd_write_string(char *s)
{
  while (*s) lcd_write_data(*s++);
}

I added the code like you said in the lcd.h
I just dont know why the lcd doesnt initiate properly, could delay be the problem?

C:
void main(void)
{
char *s="mapp";

        
  lcd_init();
  lcd_write_cmd(0x01);
  lcd_write_cmd(0x80);
  lcd_write_string(*s);
}
 

MrChips

Joined Oct 2, 2009
30,720
You need to take one step at a time.
Is the lcd_init( ) function working?
C:
void main(void)
{
  lcd_init();
  lcd_write_data('A');
}
 

MrChips

Joined Oct 2, 2009
30,720
If that code works, you can try repeatedly sending the same character forever.
C:
void main(void)
{
  lcd_init();
  while (1)
  {
    lcd_write_data('A');
    __delay_ms(500);
  }
}
 

MrChips

Joined Oct 2, 2009
30,720
Next, you can try outputting a string.
C:
char message[] = "Hello World!";

void lcd_write_string(char *s)
{
  while(*s) lcd_write_data(*s++);
}

void main(void)
{
  lcd_init();
  lcd_write_string(message);
}
 

Thread Starter

devilarm123

Joined Dec 26, 2017
33
Next, you can try outputting a string.
C:
char message[] = "Hello World!";

void lcd_write_string(char *s)
{
  while(*s) lcd_write_data(*s++);
}

void main(void)
{
  lcd_init();
  lcd_write_string(message);
}

while the first two code works without a problem, the 3rd one is runnable, but lcd is constantly displaying spaces and not the message[]
 

Attachments

MrChips

Joined Oct 2, 2009
30,720
Try the following:
C:
#include <string.h>

void lcd_write_string(char *s)
{
  while(*s) lcd_write_data(*s++);
}

void main(void)
{
  char message [20];
  strcpy(message, "Hello World!"];

  lcd_init();
  lcd_write_string(message);
}
 

MrChips

Joined Oct 2, 2009
30,720
How do you know that the LCD does not initialize?
If the codes that I posted in post #25 and #26 are working then your LCD is initialized.
 

Thread Starter

devilarm123

Joined Dec 26, 2017
33
How do you know that the LCD does not initialize?
If the codes that I posted in post #25 and #26 are working then your LCD is initialized.
I've tried a number of times,

This is what I observed:

  1. #include <string.h>

  2. void lcd_write_string(char *s)
  3. {
  4. while(*s) lcd_write_data(*s++);
  5. }

  6. void main(void)
  7. {
  8. char message [20];
  9. strcpy(message, "Hello World!");

  10. lcd_init();
  11. lcd_write_string(message);
  12. }
Above code is runnable but the lcd doesnt show or display.

But,
  1. #include <string.h>

  2. void lcd_write_string(char *s)
  3. {
  4. while(*s) lcd_write_data(*s++);
  5. }

  6. void main(void)
  7. {
  8. char message [20];
  9. strcpy(message, 'c' );

  10. lcd_init();
  11. lcd_write_string(message);
  12. }
Above code is runnable and lcd displays something(as attached).
It's always the ' ' and " " being an issue, is it possible that lcd cant read strings directly? or something wrong with the delay
 

Attachments

Ian Rogers

Joined Dec 12, 2012
1,136
I just simulated the "unchanged" code at 20Mhz REMOVED the "delay utilities" (Not needed ) changed the delay in main to __delay_ms(1000)and it runs fine..
 

AlbertHall

Joined Jun 4, 2014
12,345
I just simulated the "unchanged" code at 20Mhz REMOVED the "delay utilities" (Not needed ) changed the delay in main to __delay_ms(1000)and it runs fine..
Did you check that when data is being written to the display that RS retains its value?
The init routine is wrong so I don't think that will work with the actual display.
 

Ian Rogers

Joined Dec 12, 2012
1,136
In his "unchanged code" RS is reset after the temp shift so it works.... The 48Mhz was an issue and there was a problem with all the delay reconfiguration…. I deleted the utilities code as it was superfluous.. Works as expected..
 

AlbertHall

Joined Jun 4, 2014
12,345
In his "unchanged code" RS is reset after the temp shift so it works.... The 48Mhz was an issue and there was a problem with all the delay reconfiguration…. I deleted the utilities code as it was superfluous.. Works as expected..
And the LCD is correctly initialised?
 

MrChips

Joined Oct 2, 2009
30,720
Add the while(1); statement to your code.
C:
#include <string.h>

void lcd_write_string(char *s)
{
  while(*s) lcd_write_data(*s++);
}

void main(void)
{
  char message [20];
  strcpy(message, "Hello World!"];

  lcd_init();
  lcd_write_string(message);
  while(1);
}
 

Thread Starter

devilarm123

Joined Dec 26, 2017
33
In his "unchanged code" RS is reset after the temp shift so it works.... The 48Mhz was an issue and there was a problem with all the delay reconfiguration…. I deleted the utilities code as it was superfluous.. Works as expected..
man if it works, I'm really thankful.
Could you tell me how exactly u did it? do I add a configuration file to my code?
 
Top