PIC18F4550 Interfacing with LCD using XC8 compiler

Thread Starter

devilarm123

Joined Dec 26, 2017
33
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);
}

nope,LCD still doesn't display anything. Code is runnable the main culprit should be the delay then
 

Ian Rogers

Joined Dec 12, 2012
820
I'll send the code I used soon.... Sorry about my slow response, but my world has been upended and I have bigger issues to deal with right now...
 

jayanthd

Joined Jul 4, 2015
904
My Lcd library.

Try it.

C:
//HD44780 or compatible Lcd (16x2, 20x2, 20x4) library
//Copyright (c) Jayanth D, 2016

#define _LCD_FIRST_ROW          0x80     //Move cursor to the 1st row
#define _LCD_SECOND_ROW         0xC0     //Move cursor to the 2nd row
#define _LCD_THIRD_ROW          0x94     //Move cursor to the 3rd row
#define _LCD_FOURTH_ROW         0xD4     //Move cursor to the 4th row
#define _LCD_CLEAR              0x01     //Clear display
#define _LCD_RETURN_HOME        0x02     //Return cursor to home position, returns a
                                         //shifted display to its original position.
                                         //Display data RAM is unaffected.
#define _LCD_CURSOR_OFF         0x0C     //Turn off cursor
#define _LCD_UNDERLINE_ON       0x0E     //Underline cursor on
#define _LCD_BLINK_CURSOR_ON    0x0F     //Blink cursor on
#define _LCD_MOVE_CURSOR_LEFT   0x10     //Move cursor left without changing
                                         //display data RAM
#define _LCD_MOVE_CURSOR_RIGHT  0x14     //Move cursor right without changing
                                         //display data RAM
#define _LCD_TURN_ON            0x0C     //Turn Lcd display on
#define _LCD_TURN_OFF           0x08     //Turn Lcd display off
#define _LCD_SHIFT_LEFT         0x18     //Shift display left without changing
                                         //display data RAM
#define _LCD_SHIFT_RIGHT        0x1E     //Shift display right without changing
                                         //display data RAM

#define LCD_RS at LATBbits.LATB0
#define LCD_EN at LATBbits.LATB2
#define LCD_D4 at LATBbits.LATB4
#define LCD_D5 at LATBbits.LATB3
#define LCD_D6 at LATBbits.LATB7
#define LCD_D7 at LATBbits.LATB1

#define LCD_RS_Direction TRISBbits.TRISB0
#define LCD_EN_Direction TRISBbits.TRISB2
#define LCD_D4_Direction TRISBbits.TRISB4
#define LCD_D5_Direction TRISBbits.TRISB3
#define LCD_D6_Direction TRISBbits.TRISB7
#define LCD_D7_Direction TRISBbits.TRISB1

#define EN_DELAY 200
#define LCD_STROBE {LCD_EN = 1; __delay_us(EN_DELAY); LCD_EN = 0; __delay_us(EN_DELAY);};

void LCD_Cmd(char out_char) {
    LCD_RS = 0;

    LCD_D4 = (out_char & 0x10)?1:0;
    LCD_D5 = (out_char & 0x20)?1:0;
    LCD_D6 = (out_char & 0x40)?1:0;
    LCD_D7 = (out_char & 0x80)?1:0;
    LCD_STROBE

    LCD_D4 = (out_char & 0x01)?1:0;
    LCD_D5 = (out_char & 0x02)?1:0;
    LCD_D6 = (out_char & 0x04)?1:0;
    LCD_D7 = (out_char & 0x08)?1:0;
    LCD_STROBE

    if(out_char == 0x01)__delay_ms(2);
}

void LCD_Chr(char row, char column, char out_char) {
    switch(row) {
        case 1:
            LCD_Cmd(0x80 + (column - 1));
            break;
        case 2:
            LCD_Cmd(0xC0 + (column - 1));
            break;
        case 3:
            LCD_Cmd(0x94 + (column - 1));
            break;
        case 4:
            LCD_Cmd(0xD4 + (column - 1));
            break;
    }

    LCD_RS = 1;

    LCD_D4 = (out_char & 0x10)?1:0;
    LCD_D5 = (out_char & 0x20)?1:0;
    LCD_D6 = (out_char & 0x40)?1:0;
    LCD_D7 = (out_char & 0x80)?1:0;
    LCD_STROBE

    LCD_D4 = (out_char & 0x01)?1:0;
    LCD_D5 = (out_char & 0x02)?1:0;
    LCD_D6 = (out_char & 0x04)?1:0;
    LCD_D7 = (out_char & 0x08)?1:0; 
    LCD_STROBE
}

void LCD_Chr_Cp(char out_char) {
    LCD_RS = 1;

    LCD_D4 = (out_char & 0x10)?1:0;
    LCD_D5 = (out_char & 0x20)?1:0;
    LCD_D6 = (out_char & 0x40)?1:0;
    LCD_D7 = (out_char & 0x80)?1:0;
    LCD_STROBE

    LCD_D4 = (out_char & 0x01)?1:0;
    LCD_D5 = (out_char & 0x02)?1:0;
    LCD_D6 = (out_char & 0x04)?1:0;
    LCD_D7 = (out_char & 0x08)?1:0; 
    LCD_STROBE
}

void LCD_Init() {
    Delay_ms(200);

    LCD_RS_Direction = 0;
    LCD_EN_Direction = 0;
    LCD_D4_Direction = 0;
    LCD_D5_Direction = 0;
    LCD_D6_Direction = 0;
    LCD_D7_Direction = 0;
 
    LCD_RS = 0;
    LCD_EN = 0;
    LCD_D4 = 0;
    LCD_D5 = 0;
    LCD_D6 = 0;
    LCD_D7 = 0; 
 
    __delay_ms(30);

    LCD_D4 = 1;
    LCD_D5 = 1;
    LCD_D6 = 0;
    LCD_D7 = 0;

    LCD_STROBE

    __delay_ms(30);

    LCD_D4 = 1;
    LCD_D5 = 1;
    LCD_D6 = 0;
    LCD_D7 = 0;

    LCD_STROBE

    __delay_ms(30);

    LCD_D4 = 1;
    LCD_D5 = 1;
    LCD_D6 = 0;
    LCD_D7 = 0;

    LCD_STROBE

    __delay_ms(30);

    LCD_D4 = 0;
    LCD_D5 = 1;
    LCD_D6 = 0;
    LCD_D7 = 0;

    LCD_STROBE

    __delay_ms(30);

    LCD_Cmd(0x28);
    LCD_Cmd(0x06);
}

void LCD_Out(char row, char col, char *text) {
    while(*text)
         LCD_Chr(row, col++, *text++);
}

void LCD_Out_Cp(char *text) {
    while(*text)
         LCD_Chr_Cp(*text++);
}

void main() {

    LCD_Init();
    LCD_Cmd(_LCD_CURSOR_OFF);
    LCD_Cmd(_LCD_CLEAR);

    LCD_Out(1,1,"LCD 20X4"); 
    LCD_Out(2,1,"MCU ?");
    LCD_Out(3,1,"PIC ?");
    LCD_Out(4,1,"Working For You ?");

    while(1) {

    }
}
 

Thread Starter

devilarm123

Joined Dec 26, 2017
33
My Lcd library.

Try it.

C:
//HD44780 or compatible Lcd (16x2, 20x2, 20x4) library
//Copyright (c) Jayanth D, 2016

#define _LCD_FIRST_ROW          0x80     //Move cursor to the 1st row
#define _LCD_SECOND_ROW         0xC0     //Move cursor to the 2nd row
#define _LCD_THIRD_ROW          0x94     //Move cursor to the 3rd row
#define _LCD_FOURTH_ROW         0xD4     //Move cursor to the 4th row
#define _LCD_CLEAR              0x01     //Clear display
#define _LCD_RETURN_HOME        0x02     //Return cursor to home position, returns a
                                         //shifted display to its original position.
                                         //Display data RAM is unaffected.
#define _LCD_CURSOR_OFF         0x0C     //Turn off cursor
#define _LCD_UNDERLINE_ON       0x0E     //Underline cursor on
#define _LCD_BLINK_CURSOR_ON    0x0F     //Blink cursor on
#define _LCD_MOVE_CURSOR_LEFT   0x10     //Move cursor left without changing
                                         //display data RAM
#define _LCD_MOVE_CURSOR_RIGHT  0x14     //Move cursor right without changing
                                         //display data RAM
#define _LCD_TURN_ON            0x0C     //Turn Lcd display on
#define _LCD_TURN_OFF           0x08     //Turn Lcd display off
#define _LCD_SHIFT_LEFT         0x18     //Shift display left without changing
                                         //display data RAM
#define _LCD_SHIFT_RIGHT        0x1E     //Shift display right without changing
                                         //display data RAM

#define LCD_RS at LATBbits.LATB0
#define LCD_EN at LATBbits.LATB2
#define LCD_D4 at LATBbits.LATB4
#define LCD_D5 at LATBbits.LATB3
#define LCD_D6 at LATBbits.LATB7
#define LCD_D7 at LATBbits.LATB1

#define LCD_RS_Direction TRISBbits.TRISB0
#define LCD_EN_Direction TRISBbits.TRISB2
#define LCD_D4_Direction TRISBbits.TRISB4
#define LCD_D5_Direction TRISBbits.TRISB3
#define LCD_D6_Direction TRISBbits.TRISB7
#define LCD_D7_Direction TRISBbits.TRISB1

#define EN_DELAY 200
#define LCD_STROBE {LCD_EN = 1; __delay_us(EN_DELAY); LCD_EN = 0; __delay_us(EN_DELAY);};

void LCD_Cmd(char out_char) {
    LCD_RS = 0;

    LCD_D4 = (out_char & 0x10)?1:0;
    LCD_D5 = (out_char & 0x20)?1:0;
    LCD_D6 = (out_char & 0x40)?1:0;
    LCD_D7 = (out_char & 0x80)?1:0;
    LCD_STROBE

    LCD_D4 = (out_char & 0x01)?1:0;
    LCD_D5 = (out_char & 0x02)?1:0;
    LCD_D6 = (out_char & 0x04)?1:0;
    LCD_D7 = (out_char & 0x08)?1:0;
    LCD_STROBE

    if(out_char == 0x01)__delay_ms(2);
}

void LCD_Chr(char row, char column, char out_char) {
    switch(row) {
        case 1:
            LCD_Cmd(0x80 + (column - 1));
            break;
        case 2:
            LCD_Cmd(0xC0 + (column - 1));
            break;
        case 3:
            LCD_Cmd(0x94 + (column - 1));
            break;
        case 4:
            LCD_Cmd(0xD4 + (column - 1));
            break;
    }

    LCD_RS = 1;

    LCD_D4 = (out_char & 0x10)?1:0;
    LCD_D5 = (out_char & 0x20)?1:0;
    LCD_D6 = (out_char & 0x40)?1:0;
    LCD_D7 = (out_char & 0x80)?1:0;
    LCD_STROBE

    LCD_D4 = (out_char & 0x01)?1:0;
    LCD_D5 = (out_char & 0x02)?1:0;
    LCD_D6 = (out_char & 0x04)?1:0;
    LCD_D7 = (out_char & 0x08)?1:0;
    LCD_STROBE
}

void LCD_Chr_Cp(char out_char) {
    LCD_RS = 1;

    LCD_D4 = (out_char & 0x10)?1:0;
    LCD_D5 = (out_char & 0x20)?1:0;
    LCD_D6 = (out_char & 0x40)?1:0;
    LCD_D7 = (out_char & 0x80)?1:0;
    LCD_STROBE

    LCD_D4 = (out_char & 0x01)?1:0;
    LCD_D5 = (out_char & 0x02)?1:0;
    LCD_D6 = (out_char & 0x04)?1:0;
    LCD_D7 = (out_char & 0x08)?1:0;
    LCD_STROBE
}

void LCD_Init() {
    Delay_ms(200);

    LCD_RS_Direction = 0;
    LCD_EN_Direction = 0;
    LCD_D4_Direction = 0;
    LCD_D5_Direction = 0;
    LCD_D6_Direction = 0;
    LCD_D7_Direction = 0;

    LCD_RS = 0;
    LCD_EN = 0;
    LCD_D4 = 0;
    LCD_D5 = 0;
    LCD_D6 = 0;
    LCD_D7 = 0;

    __delay_ms(30);

    LCD_D4 = 1;
    LCD_D5 = 1;
    LCD_D6 = 0;
    LCD_D7 = 0;

    LCD_STROBE

    __delay_ms(30);

    LCD_D4 = 1;
    LCD_D5 = 1;
    LCD_D6 = 0;
    LCD_D7 = 0;

    LCD_STROBE

    __delay_ms(30);

    LCD_D4 = 1;
    LCD_D5 = 1;
    LCD_D6 = 0;
    LCD_D7 = 0;

    LCD_STROBE

    __delay_ms(30);

    LCD_D4 = 0;
    LCD_D5 = 1;
    LCD_D6 = 0;
    LCD_D7 = 0;

    LCD_STROBE

    __delay_ms(30);

    LCD_Cmd(0x28);
    LCD_Cmd(0x06);
}

void LCD_Out(char row, char col, char *text) {
    while(*text)
         LCD_Chr(row, col++, *text++);
}

void LCD_Out_Cp(char *text) {
    while(*text)
         LCD_Chr_Cp(*text++);
}

void main() {

    LCD_Init();
    LCD_Cmd(_LCD_CURSOR_OFF);
    LCD_Cmd(_LCD_CLEAR);

    LCD_Out(1,1,"LCD 20X4");
    LCD_Out(2,1,"MCU ?");
    LCD_Out(3,1,"PIC ?");
    LCD_Out(4,1,"Working For You ?");

    while(1) {

    }
}

Encountered error message, which I will post below. btw I'm using MPlab xIDE v3.2 & xc 8 compiler.
Is there any file I should include?

dolan.c:54: error: (192) undefined identifier "at"
dolan.c:54: error: (195) expression syntax
dolan.c:56: error: (195) expression syntax
dolan.c:57: error: (195) expression syntax
dolan.c:58: error: (195) expression syntax
dolan.c:59: error: (195) expression syntax
dolan.c:60: error: (195) expression syntax
dolan.c:60: error: (192) undefined identifier "_XTAL_FREQ"
dolan.c:60: error: (195) expression syntax
dolan.c:62: error: (195) expression syntax
dolan.c:63: error: (195) expression syntax
dolan.c:64: error: (195) expression syntax
dolan.c:65: error: (195) expression syntax
dolan.c:66: error: (195) expression syntax
dolan.c:66: error: (192) undefined identifier "_XTAL_FREQ"
dolan.c:66: error: (195) expression syntax
dolan.c:68: error: (192) undefined identifier "_XTAL_FREQ"
dolan.c:87: error: (192) undefined identifier "at"
dolan.c:87: error: (195) expression syntax
dolan.c:89: error: (195) expression syntax
dolan.c:90: advisory: (1) too many errors (21)
(908) exit status = 1
nbproject/Makefile-default.mk:94: recipe for target 'build/default/production/dolan.p1' failed
make[2]: Leaving directory 'C:/Users/Angus/Desktop/unchanged default.X/unchanged default.X'
nbproject/Makefile-default.mk:78: recipe for target '.build-conf' failed
make[1]: Leaving directory 'C:/Users/Angus/Desktop/unchanged default.X/unchanged default.X'
make[2]: *** [build/default/production/dolan.p1] Error 1
make[1]: *** [.build-conf] Error 2
make: *** [.build-impl] Error 2
nbproject/Makefile-impl.mk:39: recipe for target '.build-impl' failed

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

Ian Rogers

Joined Dec 12, 2012
820
Main:
C:
// LCDKeypad.c
// Program to test LCD and keypad.
// For project using USB interface with Bootloader
#define _XTAL_FREQ 20000000
#include <xc.h>
#include "lcd.h" 
unsigned char key,outchar;
char Message1 [ ] = "Enter PIN number :  ";  // Defining a 20 char string
const char Rommessage[] = "Wrong Pin Entry";
// ---- Main Program ---------------------------------------------------------------
void main(void)
{
 int i;
 lcd_init(); // Initialise LCD module
 while(1)
 {
  lcd_write_cmd(0x80); // Move cursor to line 1 position 1
  lcd_printRam(Message1);
  lcd_write_cmd(0x01); // 00000001 Clear Display instruction
  __delay_ms(1000);    // wait 1 second
 }
}
Then the header
C:
/*  file : lcd.h 
 * LCD interface header file
 * See lcd.c for more info
 */
 /* intialize the LCD - call before anything else */
void lcd_init(void);
/* write a byte to the LCD in 4 bit mode */
void lcd_write_cmd(unsigned char cmd);
//extern void lcd_write(unsigned char i);
void lcd_write_data(char data);
void lcd_printRam( char* str) ;
Utilities..
C:
/*
 * File:  lcd utilities.c
 *
 * Created on 13 January, 2016, 10:28 AM
 */
#include "LCD.H" // Include file is located in the project directory
#include <xc.h>
#include<string.h>
#define _XTAL_FREQ 20000000
#define LCD_RS PORTDbits.RD6  //  Register Select on LCD
#define LCD_EN PORTDbits.RD4  //  Enable on LCD controller
#define LCD_WR PORTDbits.RD5  //  Write on LCD controller
void lcd_strobe(void);
//--- Function for writing a command byte to the LCD in 4 bit mode -------------
void lcd_write_cmd(unsigned char cmd)
{
  unsigned char temp2;
  temp2 = cmd;
  temp2 = temp2 >> 4; // Output upper 4 bits, by shifting out lower 4 bits
  PORTD = temp2 & 0x0F; // Output to PORTD which is connected to LCD
  LCD_RS = 0; // Select LCD for command mode
  lcd_strobe();
  temp2 = cmd; // Re-initialise temp2 
  PORTD = temp2 & 0x0F; // Mask out upper 4 bits
  LCD_RS = 0; // Select LCD for command mode
  lcd_strobe();
}
//---- Function to write a character data to the LCD ---------------------------
void lcd_write_data(char data)
{
  char temp1;
  temp1 = data;
  temp1 = temp1 >> 4;
  PORTD = temp1 & 0x0F;
  LCD_RS = 1;
  lcd_strobe();
  temp1 = data;
  PORTD = temp1 & 0x0F;
  LCD_RS = 1;
  lcd_strobe(); 
  __delay_ms(5);
}
//-- Function to print a null terminated stringr----------
void lcd_printRam(char* str) // Generate the E pulse
{
  while(*str != 0)
  lcd_write_data(*str++);
}

//-- Function to generate the strobe signal for command and character----------
void lcd_strobe(void) // Generate the E pulse
{
  LCD_EN = 1; // E = 0
  __delay_ms(1); // 10ms delay for LCD_EN to settle
  LCD_EN = 0; // E = 1
}

//---- Function to initialise LCD module ----------------------------------------
void lcd_init(void)
{
  int i;
  TRISD = 0x00;
  PORTD = 0x00; // PORTD is connected to LCD data pin
  LCD_EN = 0;
  LCD_RS = 0; // Select LCD for command mode
  LCD_WR = 0; // Select LCD for write mode
  
  // finish its own internal initialisation
  /* The data sheets warn that the LCD module may fail to initialise properly when
  power is first applied. This is particularly likely if the Vdd
  supply does not rise to its correct operating voltage quickly enough.
  It is recommended that after power is applied, a command sequence of
  3 bytes of 30h be sent to the module. This will ensure that the module is in
  8-bit mode and is properly initialised. Following this, the LCD module can be
  switched to 4-bit mode.
  */
  lcd_write_cmd(0x33);
  lcd_write_cmd(0x32);
  
  lcd_write_cmd(0x28); // 001010xx – Function Set instruction
   // DL=0 :4-bit interface,N=1 :2 lines,F=0 :5x7 dots
  
  lcd_write_cmd(0x0E); // 00001110 – Display On/Off Control instruction
   // D=1 :Display on,C=1 :Cursor on,B=0 :Cursor Blink on
  
  lcd_write_cmd(0x06); // 00000110 – Entry Mode Set instruction
   // I/D=1 :Increment Cursor position
   // S=0 : No display shift
  
  lcd_write_cmd(0x01); // 00000001 Clear Display instruction
 
  __delay_ms(5); // 5 ms delay
}
Works for me...
 

Ian Rogers

Joined Dec 12, 2012
820
I tried to do a memcpy so there would be a rom string routine.. but I need to check out how I did it last time..
memcpypgm2ram() but it throws an error... I'll need to check it out..
 

jayanthd

Joined Jul 4, 2015
904
Here it is. If you still get errors with my code then simply zip and post your XC8 project and I will fix it and repost it.

As the first line of your XC8 code you have to define Crystal freuency or Fosc like

C:
#define _XTAL_FREQ 4000000UL
C:
const char msg1[] = "Got it Working?";
char msg[23];

// copy const to ram string
char *CopyConst2Ram(char *dest, const char *src) {
  char *d;
  d = dest;

  for(;*dest++ = *src++;);

  return d;
}

void main(){
...
  Lcd_Out(1,1,CopyConst2Ram(msg,msg1));
...
}
C:
//HD44780 or compatible Lcd (16x2, 20x2, 20x4) library
//Copyright (c) Jayanth D, 2016

#define _LCD_FIRST_ROW          0x80     //Move cursor to the 1st row
#define _LCD_SECOND_ROW         0xC0     //Move cursor to the 2nd row
#define _LCD_THIRD_ROW          0x94     //Move cursor to the 3rd row
#define _LCD_FOURTH_ROW         0xD4     //Move cursor to the 4th row
#define _LCD_CLEAR              0x01     //Clear display
#define _LCD_RETURN_HOME        0x02     //Return cursor to home position, returns a
                                         //shifted display to its original position.
                                         //Display data RAM is unaffected.
#define _LCD_CURSOR_OFF         0x0C     //Turn off cursor
#define _LCD_UNDERLINE_ON       0x0E     //Underline cursor on
#define _LCD_BLINK_CURSOR_ON    0x0F     //Blink cursor on
#define _LCD_MOVE_CURSOR_LEFT   0x10     //Move cursor left without changing
                                         //display data RAM
#define _LCD_MOVE_CURSOR_RIGHT  0x14     //Move cursor right without changing
                                         //display data RAM
#define _LCD_TURN_ON            0x0C     //Turn Lcd display on
#define _LCD_TURN_OFF           0x08     //Turn Lcd display off
#define _LCD_SHIFT_LEFT         0x18     //Shift display left without changing
                                         //display data RAM
#define _LCD_SHIFT_RIGHT        0x1E     //Shift display right without changing
                                         //display data RAM

#define LCD_RS LATBbits.LATB0
#define LCD_EN LATBbits.LATB2
#define LCD_D4 LATBbits.LATB4
#define LCD_D5 LATBbits.LATB3
#define LCD_D6 LATBbits.LATB7
#define LCD_D7 LATBbits.LATB1

#define LCD_RS_Direction TRISBbits.TRISB0
#define LCD_EN_Direction TRISBbits.TRISB2
#define LCD_D4_Direction TRISBbits.TRISB4
#define LCD_D5_Direction TRISBbits.TRISB3
#define LCD_D6_Direction TRISBbits.TRISB7
#define LCD_D7_Direction TRISBbits.TRISB1

#define EN_DELAY 200
#define LCD_STROBE {LCD_EN = 1; __delay_us(EN_DELAY); LCD_EN = 0; __delay_us(EN_DELAY);};const char msg1[] = "Got it Working?"


const char msg1[] = "Got it working?";
char msg[23];

// copy const to ram string
char *CopyConst2Ram(char *dest, const char *src){
  char *d;

  d = dest;

  for(;*dest++ = *src++;);

  return d;
}

void LCD_Cmd(char out_char) {
    LCD_RS = 0;

    LCD_D4 = (out_char & 0x10)?1:0;
    LCD_D5 = (out_char & 0x20)?1:0;
    LCD_D6 = (out_char & 0x40)?1:0;
    LCD_D7 = (out_char & 0x80)?1:0;
    LCD_STROBE

    LCD_D4 = (out_char & 0x01)?1:0;
    LCD_D5 = (out_char & 0x02)?1:0;
    LCD_D6 = (out_char & 0x04)?1:0;
    LCD_D7 = (out_char & 0x08)?1:0;
    LCD_STROBE

    if(out_char == 0x01)__delay_ms(2);
}

void LCD_Chr(char row, char column, char out_char) {
    switch(row) {
        case 1:
            LCD_Cmd(0x80 + (column - 1));
            break;
        case 2:
            LCD_Cmd(0xC0 + (column - 1));
            break;
        case 3:
            LCD_Cmd(0x94 + (column - 1));
            break;
        case 4:
            LCD_Cmd(0xD4 + (column - 1));
            break;
    }

    LCD_RS = 1;

    LCD_D4 = (out_char & 0x10)?1:0;
    LCD_D5 = (out_char & 0x20)?1:0;
    LCD_D6 = (out_char & 0x40)?1:0;
    LCD_D7 = (out_char & 0x80)?1:0;
    LCD_STROBE

    LCD_D4 = (out_char & 0x01)?1:0;
    LCD_D5 = (out_char & 0x02)?1:0;
    LCD_D6 = (out_char & 0x04)?1:0;
    LCD_D7 = (out_char & 0x08)?1:0;
    LCD_STROBE
}

void LCD_Chr_Cp(char out_char) {
    LCD_RS = 1;

    LCD_D4 = (out_char & 0x10)?1:0;
    LCD_D5 = (out_char & 0x20)?1:0;
    LCD_D6 = (out_char & 0x40)?1:0;
    LCD_D7 = (out_char & 0x80)?1:0;
    LCD_STROBE

    LCD_D4 = (out_char & 0x01)?1:0;
    LCD_D5 = (out_char & 0x02)?1:0;
    LCD_D6 = (out_char & 0x04)?1:0;
    LCD_D7 = (out_char & 0x08)?1:0;
    LCD_STROBE
}

void LCD_Init() {
    Delay_ms(200);

    LCD_RS_Direction = 0;
    LCD_EN_Direction = 0;
    LCD_D4_Direction = 0;
    LCD_D5_Direction = 0;
    LCD_D6_Direction = 0;
    LCD_D7_Direction = 0;

    LCD_RS = 0;
    LCD_EN = 0;
    LCD_D4 = 0;
    LCD_D5 = 0;
    LCD_D6 = 0;
    LCD_D7 = 0;

    __delay_ms(30);

    LCD_D4 = 1;
    LCD_D5 = 1;
    LCD_D6 = 0;
    LCD_D7 = 0;

    LCD_STROBE

    __delay_ms(30);

    LCD_D4 = 1;
    LCD_D5 = 1;
    LCD_D6 = 0;
    LCD_D7 = 0;

    LCD_STROBE

    __delay_ms(30);

    LCD_D4 = 1;
    LCD_D5 = 1;
    LCD_D6 = 0;
    LCD_D7 = 0;

    LCD_STROBE

    __delay_ms(30);

    LCD_D4 = 0;
    LCD_D5 = 1;
    LCD_D6 = 0;
    LCD_D7 = 0;

    LCD_STROBE

    __delay_ms(30);

    LCD_Cmd(0x28);
    LCD_Cmd(0x06);
}

void LCD_Out(char row, char col, char *text) {
    while(*text)
         LCD_Chr(row, col++, *text++);
}

void LCD_Out_Cp(char *text) {
    while(*text)
         LCD_Chr_Cp(*text++);
}

void main() {

    LCD_Init();
    LCD_Cmd(_LCD_CURSOR_OFF);
    LCD_Cmd(_LCD_CLEAR);

    Lcd_Out(1,1,CopyConst2Ram(msg,msg1));

    while(1) {

    }
}
 
Last edited:

jayanthd

Joined Jul 4, 2015
904
The code was for XC8 only but while porting the code from mikroC PRO code to XC8 I had forgotten to change few #define lines.

I have fixed them in my previous post.

mikroC PRO syntax is

Code:
sbit LCD_RS at RA5_bit;
 
Last edited:

Thread Starter

devilarm123

Joined Dec 26, 2017
33
Here it is. If you still get errors with my code then simply zip and post your XC8 project and I will fix it and repost it.

As the first line of your XC8 code you have to define Crystal freuency or Fosc like

C:
#define _XTAL_FREQ 4000000UL
C:
const char msg1[] = "Got it Working?";
char msg[23];

// copy const to ram string
char *CopyConst2Ram(char *dest, const char *src) {
  char *d;
  d = dest;

  for(;*dest++ = *src++;);

  return d;
}

void main(){
...
  Lcd_Out(1,1,CopyConst2Ram(msg,msg1));
...
}
C:
//HD44780 or compatible Lcd (16x2, 20x2, 20x4) library
//Copyright (c) Jayanth D, 2016

#define _LCD_FIRST_ROW          0x80     //Move cursor to the 1st row
#define _LCD_SECOND_ROW         0xC0     //Move cursor to the 2nd row
#define _LCD_THIRD_ROW          0x94     //Move cursor to the 3rd row
#define _LCD_FOURTH_ROW         0xD4     //Move cursor to the 4th row
#define _LCD_CLEAR              0x01     //Clear display
#define _LCD_RETURN_HOME        0x02     //Return cursor to home position, returns a
                                         //shifted display to its original position.
                                         //Display data RAM is unaffected.
#define _LCD_CURSOR_OFF         0x0C     //Turn off cursor
#define _LCD_UNDERLINE_ON       0x0E     //Underline cursor on
#define _LCD_BLINK_CURSOR_ON    0x0F     //Blink cursor on
#define _LCD_MOVE_CURSOR_LEFT   0x10     //Move cursor left without changing
                                         //display data RAM
#define _LCD_MOVE_CURSOR_RIGHT  0x14     //Move cursor right without changing
                                         //display data RAM
#define _LCD_TURN_ON            0x0C     //Turn Lcd display on
#define _LCD_TURN_OFF           0x08     //Turn Lcd display off
#define _LCD_SHIFT_LEFT         0x18     //Shift display left without changing
                                         //display data RAM
#define _LCD_SHIFT_RIGHT        0x1E     //Shift display right without changing
                                         //display data RAM

#define LCD_RS LATBbits.LATB0
#define LCD_EN LATBbits.LATB2
#define LCD_D4 LATBbits.LATB4
#define LCD_D5 LATBbits.LATB3
#define LCD_D6 LATBbits.LATB7
#define LCD_D7 LATBbits.LATB1

#define LCD_RS_Direction TRISBbits.TRISB0
#define LCD_EN_Direction TRISBbits.TRISB2
#define LCD_D4_Direction TRISBbits.TRISB4
#define LCD_D5_Direction TRISBbits.TRISB3
#define LCD_D6_Direction TRISBbits.TRISB7
#define LCD_D7_Direction TRISBbits.TRISB1

#define EN_DELAY 200
#define LCD_STROBE {LCD_EN = 1; __delay_us(EN_DELAY); LCD_EN = 0; __delay_us(EN_DELAY);};const char msg1[] = "Got it Working?"


const char msg1[] = "Got it working?";
char msg[23];

// copy const to ram string
char *CopyConst2Ram(char *dest, const char *src){
  char *d;

  d = dest;

  for(;*dest++ = *src++;);

  return d;
}

void LCD_Cmd(char out_char) {
    LCD_RS = 0;

    LCD_D4 = (out_char & 0x10)?1:0;
    LCD_D5 = (out_char & 0x20)?1:0;
    LCD_D6 = (out_char & 0x40)?1:0;
    LCD_D7 = (out_char & 0x80)?1:0;
    LCD_STROBE

    LCD_D4 = (out_char & 0x01)?1:0;
    LCD_D5 = (out_char & 0x02)?1:0;
    LCD_D6 = (out_char & 0x04)?1:0;
    LCD_D7 = (out_char & 0x08)?1:0;
    LCD_STROBE

    if(out_char == 0x01)__delay_ms(2);
}

void LCD_Chr(char row, char column, char out_char) {
    switch(row) {
        case 1:
            LCD_Cmd(0x80 + (column - 1));
            break;
        case 2:
            LCD_Cmd(0xC0 + (column - 1));
            break;
        case 3:
            LCD_Cmd(0x94 + (column - 1));
            break;
        case 4:
            LCD_Cmd(0xD4 + (column - 1));
            break;
    }

    LCD_RS = 1;

    LCD_D4 = (out_char & 0x10)?1:0;
    LCD_D5 = (out_char & 0x20)?1:0;
    LCD_D6 = (out_char & 0x40)?1:0;
    LCD_D7 = (out_char & 0x80)?1:0;
    LCD_STROBE

    LCD_D4 = (out_char & 0x01)?1:0;
    LCD_D5 = (out_char & 0x02)?1:0;
    LCD_D6 = (out_char & 0x04)?1:0;
    LCD_D7 = (out_char & 0x08)?1:0;
    LCD_STROBE
}

void LCD_Chr_Cp(char out_char) {
    LCD_RS = 1;

    LCD_D4 = (out_char & 0x10)?1:0;
    LCD_D5 = (out_char & 0x20)?1:0;
    LCD_D6 = (out_char & 0x40)?1:0;
    LCD_D7 = (out_char & 0x80)?1:0;
    LCD_STROBE

    LCD_D4 = (out_char & 0x01)?1:0;
    LCD_D5 = (out_char & 0x02)?1:0;
    LCD_D6 = (out_char & 0x04)?1:0;
    LCD_D7 = (out_char & 0x08)?1:0;
    LCD_STROBE
}

void LCD_Init() {
    Delay_ms(200);

    LCD_RS_Direction = 0;
    LCD_EN_Direction = 0;
    LCD_D4_Direction = 0;
    LCD_D5_Direction = 0;
    LCD_D6_Direction = 0;
    LCD_D7_Direction = 0;

    LCD_RS = 0;
    LCD_EN = 0;
    LCD_D4 = 0;
    LCD_D5 = 0;
    LCD_D6 = 0;
    LCD_D7 = 0;

    __delay_ms(30);

    LCD_D4 = 1;
    LCD_D5 = 1;
    LCD_D6 = 0;
    LCD_D7 = 0;

    LCD_STROBE

    __delay_ms(30);

    LCD_D4 = 1;
    LCD_D5 = 1;
    LCD_D6 = 0;
    LCD_D7 = 0;

    LCD_STROBE

    __delay_ms(30);

    LCD_D4 = 1;
    LCD_D5 = 1;
    LCD_D6 = 0;
    LCD_D7 = 0;

    LCD_STROBE

    __delay_ms(30);

    LCD_D4 = 0;
    LCD_D5 = 1;
    LCD_D6 = 0;
    LCD_D7 = 0;

    LCD_STROBE

    __delay_ms(30);

    LCD_Cmd(0x28);
    LCD_Cmd(0x06);
}

void LCD_Out(char row, char col, char *text) {
    while(*text)
         LCD_Chr(row, col++, *text++);
}

void LCD_Out_Cp(char *text) {
    while(*text)
         LCD_Chr_Cp(*text++);
}

void main() {

    LCD_Init();
    LCD_Cmd(_LCD_CURSOR_OFF);
    LCD_Cmd(_LCD_CLEAR);

    Lcd_Out(1,1,CopyConst2Ram(msg,msg1));

    while(1) {

    }
}
yes,i still encounter errors. just wanna say thanks for spending time to help me.
 

Attachments

Thread Starter

devilarm123

Joined Dec 26, 2017
33
Main:
C:
// LCDKeypad.c
// Program to test LCD and keypad.
// For project using USB interface with Bootloader
#define _XTAL_FREQ 20000000
#include <xc.h>
#include "lcd.h"
unsigned char key,outchar;
char Message1 [ ] = "Enter PIN number :  ";  // Defining a 20 char string
const char Rommessage[] = "Wrong Pin Entry";
// ---- Main Program ---------------------------------------------------------------
void main(void)
{
int i;
lcd_init(); // Initialise LCD module
while(1)
{
  lcd_write_cmd(0x80); // Move cursor to line 1 position 1
  lcd_printRam(Message1);
  lcd_write_cmd(0x01); // 00000001 Clear Display instruction
  __delay_ms(1000);    // wait 1 second
}
}
Then the header
C:
/*  file : lcd.h
* LCD interface header file
* See lcd.c for more info
*/
/* intialize the LCD - call before anything else */
void lcd_init(void);
/* write a byte to the LCD in 4 bit mode */
void lcd_write_cmd(unsigned char cmd);
//extern void lcd_write(unsigned char i);
void lcd_write_data(char data);
void lcd_printRam( char* str) ;
Utilities..
C:
/*
* File:  lcd utilities.c
*
* Created on 13 January, 2016, 10:28 AM
*/
#include "LCD.H" // Include file is located in the project directory
#include <xc.h>
#include<string.h>
#define _XTAL_FREQ 20000000
#define LCD_RS PORTDbits.RD6  //  Register Select on LCD
#define LCD_EN PORTDbits.RD4  //  Enable on LCD controller
#define LCD_WR PORTDbits.RD5  //  Write on LCD controller
void lcd_strobe(void);
//--- Function for writing a command byte to the LCD in 4 bit mode -------------
void lcd_write_cmd(unsigned char cmd)
{
  unsigned char temp2;
  temp2 = cmd;
  temp2 = temp2 >> 4; // Output upper 4 bits, by shifting out lower 4 bits
  PORTD = temp2 & 0x0F; // Output to PORTD which is connected to LCD
  LCD_RS = 0; // Select LCD for command mode
  lcd_strobe();
  temp2 = cmd; // Re-initialise temp2
  PORTD = temp2 & 0x0F; // Mask out upper 4 bits
  LCD_RS = 0; // Select LCD for command mode
  lcd_strobe();
}
//---- Function to write a character data to the LCD ---------------------------
void lcd_write_data(char data)
{
  char temp1;
  temp1 = data;
  temp1 = temp1 >> 4;
  PORTD = temp1 & 0x0F;
  LCD_RS = 1;
  lcd_strobe();
  temp1 = data;
  PORTD = temp1 & 0x0F;
  LCD_RS = 1;
  lcd_strobe();
  __delay_ms(5);
}
//-- Function to print a null terminated stringr----------
void lcd_printRam(char* str) // Generate the E pulse
{
  while(*str != 0)
  lcd_write_data(*str++);
}

//-- Function to generate the strobe signal for command and character----------
void lcd_strobe(void) // Generate the E pulse
{
  LCD_EN = 1; // E = 0
  __delay_ms(1); // 10ms delay for LCD_EN to settle
  LCD_EN = 0; // E = 1
}

//---- Function to initialise LCD module ----------------------------------------
void lcd_init(void)
{
  int i;
  TRISD = 0x00;
  PORTD = 0x00; // PORTD is connected to LCD data pin
  LCD_EN = 0;
  LCD_RS = 0; // Select LCD for command mode
  LCD_WR = 0; // Select LCD for write mode
 
  // finish its own internal initialisation
  /* The data sheets warn that the LCD module may fail to initialise properly when
  power is first applied. This is particularly likely if the Vdd
  supply does not rise to its correct operating voltage quickly enough.
  It is recommended that after power is applied, a command sequence of
  3 bytes of 30h be sent to the module. This will ensure that the module is in
  8-bit mode and is properly initialised. Following this, the LCD module can be
  switched to 4-bit mode.
  */
  lcd_write_cmd(0x33);
  lcd_write_cmd(0x32);
 
  lcd_write_cmd(0x28); // 001010xx – Function Set instruction
   // DL=0 :4-bit interface,N=1 :2 lines,F=0 :5x7 dots
 
  lcd_write_cmd(0x0E); // 00001110 – Display On/Off Control instruction
   // D=1 :Display on,C=1 :Cursor on,B=0 :Cursor Blink on
 
  lcd_write_cmd(0x06); // 00000110 – Entry Mode Set instruction
   // I/D=1 :Increment Cursor position
   // S=0 : No display shift
 
  lcd_write_cmd(0x01); // 00000001 Clear Display instruction

  __delay_ms(5); // 5 ms delay
}
Works for me...

*scratches my head* The lcd still doesn't display anything...Even thou the code is running fine.
the only error I encountered is


IN THE LAST LINE OF MAIN
code(c):
__delay_ms(1000);

which gives me a error code of
LCD2Lines.c:28: error: (1355) in-line delay argument too large

But after changing to a smaller value
code(c):
__delay_ms(39);

Code runs well but lcd still doesnt display anything.
 

Ian Rogers

Joined Dec 12, 2012
820
The only thing still to do is put your Config bits in.. Only you know what these need to be..

Are you using the USB???

#pragma config FOSC = HS <<-- required for external 20Mhz crystal
#pragma config PLLDIV = 5 << -- the USB must be driven by 4 Mhz

There are many more, but I don't know what you need.. CPUDIV, USBDIV etc..

WDT = ON/OFF
BOR = ON/OFF
PWRT = ON/OFF

Loads..
 

jayanthd

Joined Jul 4, 2015
904
I guess XC8 doesn't allow more than

C:
__delay_ms(500);
Change #defines as required. I just posted my Lcd library. I didn't change the #defines according to your connections.
See if you need to disable analog function on the Lcd pins that you have used if any.

Your attachment is not downloading. So, just copy and paste your full XC8 code.

Change these according to your connections.

C:
#define LCD_RS at LATBbits.LATB0
#define LCD_EN at LATBbits.LATB2
#define LCD_D4 at LATBbits.LATB4
#define LCD_D5 at LATBbits.LATB3
#define LCD_D6 at LATBbits.LATB7
#define LCD_D7 at LATBbits.LATB1

#define LCD_RS_Direction TRISBbits.TRISB0
#define LCD_EN_Direction TRISBbits.TRISB2
#define LCD_D4_Direction TRISBbits.TRISB4
#define LCD_D5_Direction TRISBbits.TRISB3
#define LCD_D6_Direction TRISBbits.TRISB7
#define LCD_D7_Direction TRISBbits.TRISB1
 

jayanthd

Joined Jul 4, 2015
904
Here is mine.

C:
/* 
 * File:   main.c
 * Author: Jayanth D
 *
 * Created on 6 February, 2019, 7:22 AM
 */

#define _XTAL_FREQ 20000000UL


// PIC18F4550 Configuration Bit Settings

// 'C' source line config statements

// CONFIG1L
#pragma config PLLDIV = 5       // PLL Prescaler Selection bits (Divide by 5 (20 MHz oscillator input))
#pragma config CPUDIV = OSC1_PLL2// System Clock Postscaler Selection bits ([Primary Oscillator Src: /1][96 MHz PLL Src: /2])
#pragma config USBDIV = 2       // USB Clock Selection bit (used in Full-Speed USB mode only; UCFG:FSEN = 1) (USB clock source comes from the 96 MHz PLL divided by 2)

// CONFIG1H
#pragma config FOSC = HS        // Oscillator Selection bits (HS oscillator (HS))
#pragma config FCMEN = ON       // Fail-Safe Clock Monitor Enable bit (Fail-Safe Clock Monitor enabled)
#pragma config IESO = OFF       // Internal/External Oscillator Switchover bit (Oscillator Switchover mode disabled)

// CONFIG2L
#pragma config PWRT = ON        // Power-up Timer Enable bit (PWRT enabled)
#pragma config BOR = OFF        // Brown-out Reset Enable bits (Brown-out Reset disabled in hardware and software)
#pragma config BORV = 3         // Brown-out Reset Voltage bits (Minimum setting 2.05V)
#pragma config VREGEN = OFF     // USB Voltage Regulator Enable bit (USB voltage regulator disabled)

// CONFIG2H
#pragma config WDT = OFF        // Watchdog Timer Enable bit (WDT disabled (control is placed on the SWDTEN bit))
#pragma config WDTPS = 32768    // Watchdog Timer Postscale Select bits (1:32768)

// CONFIG3H
#pragma config CCP2MX = ON      // CCP2 MUX bit (CCP2 input/output is multiplexed with RC1)
#pragma config PBADEN = OFF     // PORTB A/D Enable bit (PORTB<4:0> pins are configured as digital I/O on Reset)
#pragma config LPT1OSC = OFF    // Low-Power Timer 1 Oscillator Enable bit (Timer1 configured for higher power operation)
#pragma config MCLRE = OFF      // MCLR Pin Enable bit (RE3 input pin enabled; MCLR pin disabled)

// CONFIG4L
#pragma config STVREN = ON      // Stack Full/Underflow Reset Enable bit (Stack full/underflow will cause Reset)
#pragma config LVP = OFF        // Single-Supply ICSP Enable bit (Single-Supply ICSP disabled)
#pragma config ICPRT = OFF      // Dedicated In-Circuit Debug/Programming Port (ICPORT) Enable bit (ICPORT disabled)
#pragma config XINST = OFF      // Extended Instruction Set Enable bit (Instruction set extension and Indexed Addressing mode disabled (Legacy mode))

// CONFIG5L
#pragma config CP0 = OFF        // Code Protection bit (Block 0 (000800-001FFFh) is not code-protected)
#pragma config CP1 = OFF        // Code Protection bit (Block 1 (002000-003FFFh) is not code-protected)
#pragma config CP2 = OFF        // Code Protection bit (Block 2 (004000-005FFFh) is not code-protected)
#pragma config CP3 = OFF        // Code Protection bit (Block 3 (006000-007FFFh) is not code-protected)

// CONFIG5H
#pragma config CPB = OFF        // Boot Block Code Protection bit (Boot block (000000-0007FFh) is not code-protected)
#pragma config CPD = OFF        // Data EEPROM Code Protection bit (Data EEPROM is not code-protected)

// CONFIG6L
#pragma config WRT0 = OFF       // Write Protection bit (Block 0 (000800-001FFFh) is not write-protected)
#pragma config WRT1 = OFF       // Write Protection bit (Block 1 (002000-003FFFh) is not write-protected)
#pragma config WRT2 = OFF       // Write Protection bit (Block 2 (004000-005FFFh) is not write-protected)
#pragma config WRT3 = OFF       // Write Protection bit (Block 3 (006000-007FFFh) is not write-protected)

// CONFIG6H
#pragma config WRTC = OFF       // Configuration Register Write Protection bit (Configuration registers (300000-3000FFh) are not write-protected)
#pragma config WRTB = OFF       // Boot Block Write Protection bit (Boot block (000000-0007FFh) is not write-protected)
#pragma config WRTD = OFF       // Data EEPROM Write Protection bit (Data EEPROM is not write-protected)

// CONFIG7L
#pragma config EBTR0 = OFF      // Table Read Protection bit (Block 0 (000800-001FFFh) is not protected from table reads executed in other blocks)
#pragma config EBTR1 = OFF      // Table Read Protection bit (Block 1 (002000-003FFFh) is not protected from table reads executed in other blocks)
#pragma config EBTR2 = OFF      // Table Read Protection bit (Block 2 (004000-005FFFh) is not protected from table reads executed in other blocks)
#pragma config EBTR3 = OFF      // Table Read Protection bit (Block 3 (006000-007FFFh) is not protected from table reads executed in other blocks)

// CONFIG7H
#pragma config EBTRB = OFF      // Boot Block Table Read Protection bit (Boot block (000000-0007FFh) is not protected from table reads executed in other blocks)

// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.

#include <xc.h>

//HD44780 or compatible Lcd (16x2, 20x2, 20x4) library
//Copyright (c) Jayanth D, 2016

#define _LCD_FIRST_ROW          0x80     //Move cursor to the 1st row
#define _LCD_SECOND_ROW         0xC0     //Move cursor to the 2nd row
#define _LCD_THIRD_ROW          0x94     //Move cursor to the 3rd row
#define _LCD_FOURTH_ROW         0xD4     //Move cursor to the 4th row
#define _LCD_CLEAR              0x01     //Clear display
#define _LCD_RETURN_HOME        0x02     //Return cursor to home position, returns a 
                                         //shifted display to its original position.
                                         //Display data RAM is unaffected.
#define _LCD_CURSOR_OFF         0x0C     //Turn off cursor
#define _LCD_UNDERLINE_ON       0x0E     //Underline cursor on
#define _LCD_BLINK_CURSOR_ON    0x0F     //Blink cursor on
#define _LCD_MOVE_CURSOR_LEFT   0x10     //Move cursor left without changing 
                                         //display data RAM
#define _LCD_MOVE_CURSOR_RIGHT  0x14     //Move cursor right without changing 
                                         //display data RAM
#define _LCD_TURN_ON            0x0C     //Turn Lcd display on
#define _LCD_TURN_OFF           0x08     //Turn Lcd display off
#define _LCD_SHIFT_LEFT         0x18     //Shift display left without changing 
                                         //display data RAM
#define _LCD_SHIFT_RIGHT        0x1E     //Shift display right without changing 
                                         //display data RAM

#define LCD_RS LATDbits.LATD4
#define LCD_EN LATDbits.LATD5
#define LCD_D4 LATDbits.LATD0
#define LCD_D5 LATDbits.LATD1
#define LCD_D6 LATDbits.LATD2
#define LCD_D7 LATDbits.LATD3

#define LCD_RS_Direction TRISDbits.TRISD4
#define LCD_EN_Direction TRISDbits.TRISD5
#define LCD_D4_Direction TRISDbits.TRISD0
#define LCD_D5_Direction TRISDbits.TRISD1
#define LCD_D6_Direction TRISDbits.TRISD2
#define LCD_D7_Direction TRISDbits.TRISD3

#define EN_DELAY 200
#define LCD_STROBE {LCD_EN = 1; __delay_us(EN_DELAY); LCD_EN = 0; __delay_us(EN_DELAY);};

const char msg1[] = "Got it Working?";
char msg[23];

void LCD_Cmd(char out_char) {
    LCD_RS = 0;

    LCD_D4 = (out_char & 0x10)?1:0;
    LCD_D5 = (out_char & 0x20)?1:0;
    LCD_D6 = (out_char & 0x40)?1:0;
    LCD_D7 = (out_char & 0x80)?1:0;
    LCD_STROBE

    LCD_D4 = (out_char & 0x01)?1:0;
    LCD_D5 = (out_char & 0x02)?1:0;
    LCD_D6 = (out_char & 0x04)?1:0;
    LCD_D7 = (out_char & 0x08)?1:0;
    LCD_STROBE

    if(out_char == 0x01)__delay_ms(2);
}

void LCD_Chr(char row, char column, char out_char) {
    switch(row) {
        case 1:
            LCD_Cmd(0x80 + (column - 1));
            break;
        case 2:
            LCD_Cmd(0xC0 + (column - 1));
            break;
        case 3:
            LCD_Cmd(0x94 + (column - 1));
            break;
        case 4:
            LCD_Cmd(0xD4 + (column - 1));
            break;
    }

    LCD_RS = 1;

    LCD_D4 = (out_char & 0x10)?1:0;
    LCD_D5 = (out_char & 0x20)?1:0;
    LCD_D6 = (out_char & 0x40)?1:0;
    LCD_D7 = (out_char & 0x80)?1:0;
    LCD_STROBE

    LCD_D4 = (out_char & 0x01)?1:0;
    LCD_D5 = (out_char & 0x02)?1:0;
    LCD_D6 = (out_char & 0x04)?1:0;
    LCD_D7 = (out_char & 0x08)?1:0;   
    LCD_STROBE
}

void LCD_Chr_Cp(char out_char) {
    LCD_RS = 1;

    LCD_D4 = (out_char & 0x10)?1:0;
    LCD_D5 = (out_char & 0x20)?1:0;
    LCD_D6 = (out_char & 0x40)?1:0;
    LCD_D7 = (out_char & 0x80)?1:0;
    LCD_STROBE

    LCD_D4 = (out_char & 0x01)?1:0;
    LCD_D5 = (out_char & 0x02)?1:0;
    LCD_D6 = (out_char & 0x04)?1:0;
    LCD_D7 = (out_char & 0x08)?1:0;   
    LCD_STROBE
}

void LCD_Init() {
    __delay_ms(200);

    LCD_RS_Direction = 0;
    LCD_EN_Direction = 0;
    LCD_D4_Direction = 0;
    LCD_D5_Direction = 0;
    LCD_D6_Direction = 0;
    LCD_D7_Direction = 0;
   
    LCD_RS = 0;
    LCD_EN = 0;
    LCD_D4 = 0;
    LCD_D5 = 0;
    LCD_D6 = 0;
    LCD_D7 = 0;   
   
    __delay_ms(30);

    LCD_D4 = 1;
    LCD_D5 = 1;
    LCD_D6 = 0;
    LCD_D7 = 0;

    LCD_STROBE

    __delay_ms(30);

    LCD_D4 = 1;
    LCD_D5 = 1;
    LCD_D6 = 0;
    LCD_D7 = 0;

    LCD_STROBE

    __delay_ms(30);

    LCD_D4 = 1;
    LCD_D5 = 1;
    LCD_D6 = 0;
    LCD_D7 = 0;

    LCD_STROBE

    __delay_ms(30);

    LCD_D4 = 0;
    LCD_D5 = 1;
    LCD_D6 = 0;
    LCD_D7 = 0;

    LCD_STROBE

    __delay_ms(30);

    LCD_Cmd(0x28);
    LCD_Cmd(0x06);
}

void LCD_Out(char row, char col, char *text) {
    while(*text)
         LCD_Chr(row, col++, *text++);
}

void LCD_Out_Cp(char *text) {
    while(*text)
         LCD_Chr_Cp(*text++);
}

// copy const to ram string
char *CopyConst2Ram(char *dest, const char *src) {
    char *d;
    d = dest;

    for(;(*dest++ = *src++););

    return d;
}

int main(int argc, char** argv) {

    LCD_Init();
    LCD_Cmd(_LCD_CURSOR_OFF);
    LCD_Cmd(_LCD_CLEAR);

    LCD_Out(1,1,"LCD 20X4");   
    LCD_Out(2,1,"PIC18F4550?");
    LCD_Out(3,1,"20 MHz HS OSC");
    LCD_Out(4,1,CopyConst2Ram(msg,msg1));

    while(1) {

    }
   
    return (EXIT_SUCCESS);
}
Driving_LCD.png
 

Attachments

Thread Starter

devilarm123

Joined Dec 26, 2017
33
okay guys, I just solved the problem by changing the code offset in the properties section, from 100 to 1000.
Now "unchanged default works well and LCD displays just fine.

I feel bad for not checking this ahead and wasted so much of you guys time. But I still appreciate those who helped me in the process!
 

Attachments

Top