Pic18f4550 LCD 4x20 not working

Thread Starter

Geid D

Joined Jun 28, 2015
36
Try this code and see what it prints.

Code:
char i = 0;
for(i = 1; i < 21; i++)  {
LCD_Chr(1,i,'A');
LCD_Chr(2,i,'A');
LCD_Chr(3,i,'A');
LCD_Chr(4,i,'A');
}
you code works with this modification:

Code:
int c='A';
char i = 0;
for(i = 1; i < 21; i++)  {
LCD_Chr(1,i,c);
LCD_Chr(2,i,c);
LCD_Chr(3,i,c);
LCD_Chr(4,i,c);
}
 

JohnInTX

Joined Jun 26, 2012
4,787
I cleaned up some of the implied type conversions and changed XC8 ver 2.10 to compile and link as C90 (not C99). This cleaned up a lot of compiler complaints.
Properties->XC8 Global Options-C standard = C90
Properties->XC8 Linker Link in C Library = C90

It wouldn't hurt to clean things up more to satisfy the more rigid standards but I ran it in the simulator and it correctly passes "Test" to the LCD character out routines. I didn't investigate the delays etc. but if you can write one character, the string should work.

One rule of thumb: never use a build with compiler warnings. Just because they're not elevated to fatal errors doesn't mean they're not significant and it's likely they will cause problems at run-time. My personal view is that compiler warnings are run-time errors that haven't happened yet.

Good Luck!
C:
#define _XTAL_FREQ 48000000
// 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: /2][96 MHz PLL Src: /3])
#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 = HSPLL_HS  // Oscillator Selection bits (HS oscillator, PLL enabled (HSPLL))
#pragma config FCMEN = OFF  // Fail-Safe Clock Monitor Enable bit (Fail-Safe Clock Monitor disabled)
#pragma config IESO = OFF  // Internal/External Oscillator Switchover bit (Oscillator Switchover mode disabled)
// CONFIG2L
#pragma config PWRT = OFF  // Power-up Timer Enable bit (PWRT disabled)
#pragma config BOR = ON  // 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 = OFF  // Stack Full/Underflow Reset Enable bit (Stack full/underflow will not 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>
#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_STROBE_DELAY 100
#define LCD_RS LATBbits.LATB0
#define LCD_EN LATBbits.LATB2
#define LCD_D4 LATBbits.LATB3
#define LCD_D5 LATBbits.LATB5
#define LCD_D6 LATBbits.LATB6
#define LCD_D7 LATBbits.LATB7
#define LCD_RS_Direction TRISBbits.TRISB0
#define LCD_EN_Direction TRISBbits.TRISB2
#define LCD_D4_Direction TRISBbits.TRISB3
#define LCD_D5_Direction TRISBbits.TRISB5
#define LCD_D6_Direction TRISBbits.TRISB6
#define LCD_D7_Direction TRISBbits.TRISB7

void LCD_Strobe(void);
void LCD_Send_Data(unsigned char out_char);
void LCD_Cmd(unsigned char out_char);
void LCD_Chr(unsigned char row, unsigned char column,unsigned char out_char);
void LCD_Chr_Cp(unsigned char out_char);
void LCD_Init(void);
void LCD_Out(unsigned char row, unsigned char col,const unsigned char *text);
void LCD_Out_Cp(const unsigned char *text);
void main(void)
{

ADCON1 = 0x0F;

ADCON0bits.ADON = 0;
ADCON1bits.PCFG0 = 1;
ADCON1bits.PCFG1 = 1;
ADCON1bits.PCFG2 = 1;
ADCON1bits.PCFG3 = 1;
TRISA = 0x00;
TRISB = 0x00;
TRISD = 0x00;
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;
LATAbits.LATA5 = 1; // led on
LCD_Init();
LCD_Cmd(_LCD_CURSOR_OFF);
LCD_Cmd(_LCD_CLEAR);

LCD_Out(2,1,"Test");

unsigned char c='K';
LCD_Chr(1,1,c);

while(1) {

  // blink led
  LATAbits.LATA5 = 0;
  __delay_ms(1000);
  LATAbits.LATA5 = 1;
  __delay_ms(1000);


}
}
// FUNCTIONS
void LCD_Strobe(void) {
  LCD_EN = 1;
  __delay_us(100); // 100
  LCD_EN = 0;

}
void LCD_Send_Data(char out_char) {
  if(out_char & 0x10) LCD_D4 = 1; else LCD_D4 = 0;
  if(out_char & 0x20) LCD_D5 = 1; else LCD_D5 = 0;
  if(out_char & 0x40) LCD_D6 = 1; else LCD_D6 = 0;
  if(out_char & 0x80) LCD_D7 = 1; else LCD_D7 = 0;
  LCD_Strobe();
  if(out_char & 0x01) LCD_D4 = 1; else LCD_D4 = 0;
  if(out_char & 0x02) LCD_D5 = 1; else LCD_D5 = 0;
  if(out_char & 0x04) LCD_D6 = 1; else LCD_D6 = 0;
  if(out_char & 0x08) LCD_D7 = 1; else LCD_D7 = 0;
  LCD_Strobe();
}
void LCD_Cmd(unsigned char out_char) {
  LCD_RS = 0;
  LCD_Send_Data(out_char);
  if(out_char == 0x01)__delay_ms(2);
}
void LCD_Chr(unsigned char row, unsigned char column,unsigned char out_char) {
  switch(row) {
  case 1:
  LCD_Cmd((unsigned char)(0x80 + column - 1));
  break;
  case 2:
  LCD_Cmd((unsigned char) (0xC0 + column - 1));
  break;
  case 3:
  LCD_Cmd((unsigned char) (0x94 + column - 1));
  break;
  case 4:
  LCD_Cmd((unsigned char) (0xD4 + column - 1));
  break;
  }
  LCD_RS = 1;
  LCD_Send_Data(out_char);
}
void LCD_Chr_Cp(char out_char) {
  LCD_RS = 1;
  LCD_Send_Data(out_char);
}
void LCD_Init(void) {
  __delay_ms(200);
  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,const char *text) {
  while(*text)
  LCD_Chr(row, col++, *text++);
}
void LCD_Out_Cp(const char *text) {
  while(*text)
  LCD_Chr_Cp(*text++);
}
EDIT: C90, not C99
 
Last edited:

Thread Starter

Geid D

Joined Jun 28, 2015
36
Set the XC8 optimization to 0 (off), also set compiler to C90 mode and updated functions code as JohnInTX provided.....

all the same... enabling LCD_out() stops code, nothing works...
 

jayanthd

Joined Jul 4, 2015
945
Set the XC8 optimization to 0 (off), also set compiler to C90 mode and updated functions code as JohnInTX provided.....

all the same... enabling LCD_out() stops code, nothing works...
Zip and send your complete MPLAB X XC8 project file and also the Proteus simulation file.
 

MrChips

Joined Oct 2, 2009
30,807
Have you considered that there could be a hardware fault?

1) Is Vcc and GND wired correctly?
2) Is VEE set properly?
3) Are all data and control pins correct?
4) Are your interface cables of proper length?
5) Do you have decoupling capacitors between Vcc and GND at the LCD module?
6) Do you know that the LCD module is not damaged?
 

Thread Starter

Geid D

Joined Jun 28, 2015
36
USB Bootloader has nothing to do with it.
its seems that the problem was indeed related to Bootloader :)
today i googled this thread: https://www.microchip.com/forums/m733764.aspx

XC8-compiler,
No linker file in the project, no vector remapping in the main file - the appropriate settings are done in the project properties XC8 linker options: codeoffset = 0x1000
so adding this line in linker options solved the problem. now pointers dont halt the code. everything works!
thank you all a lot for your help and patience :)
 
Top