Hello,
I'm an electronics student and for my final project I'm trying to display data from a GPS (nemo 6m) operating via RS232 communication on an LCD screen with my PIC18F452. I had made a code for the LCD without a library, which worked without a hitch and which I used in this code.
The code for displaying data from an RS232 communication is relatively simple and works very well with a TTL to USB card.
The code below for displaying GPS data on the LCD works, but only once. When I run the program, it displays the time correctly, but I have to press the reset button to refresh. It seems that the code is stuck somewhere....
After many tests, I don't understand why and that's why I'm coming to you. 
Thanks in advance for taking a look.
Technical specification: 
16MHz quartz
// Pour les commandes du LCD : https://binaryupdates.com/interface-lcd-with-lpc2148-arm7/jhd162a-lcd-command-codes/
// Voir datasheet p174 et p176 : https://ww1.microchip.com/downloads/aemDocuments/documents/MCU08/ProductDocuments/DataSheets/39564c.pdf
#include <p18f452.h> 
#include <delays.h>
#include <stdio.h>
 
#pragma config OSC = HS   // Travailler à 16MHz
#pragma config PWRT = ON 
#pragma config BOR = OFF 
#pragma config WDT = OFF  
#pragma config LVP = OFF  
 
// ****************************** Déclarations des PINs de sortie ***************************************
// ****************************** Output PIN declarations ***************************************
// Définition pour broches en sortie
// Definition for output pins
#define data4DEF TRISBbits.TRISB4
#define data5DEF TRISBbits.TRISB5
#define data6DEF TRISBbits.TRISB6
#define data7DEF TRISBbits.TRISB7
#define RSDEF TRISCbits.TRISC0
#define RWDEF TRISCbits.TRISC1
#define EDEF TRISCbits.TRISC2
// Définition pour l'état des broches (même que pour TRIS)
// Definition of pin status (same as TRIS)
#define data4 PORTBbits.RB4
#define data5 PORTBbits.RB5
#define data6 PORTBbits.RB6
#define data7 PORTBbits.RB7
#define RS PORTCbits.RC0
#define RW PORTCbits.RC1
#define E PORTCbits.RC2
// Paramètre interne (pas toucher)
// Internal parameter (do not touch)
int delai = 1;
// ****************************************** Toutes les fonctions *****************************************************
void LCD_Cmnd (unsigned char cmnd)
{
    // Permet d'appliquer les bits de la commande sur les bonnes PINs de sortie (en fonction des define)
    // Enables command bits to be applied to the correct output PINs (depending on define)
    data4 = (cmnd & 0x10) >> 4;
    data5 = (cmnd & 0x20) >> 5;
    data6 = (cmnd & 0x40) >> 6;
    data7 = (cmnd & 0x80) >> 7;
    
    RS = 0;                     // Mode commande
    E = 1;
    Delay10KTCYx (delai);
    E = 0;
    
    data4 = cmnd & 0x01;
    data5 = (cmnd & 0x02) >> 1;
    data6 = (cmnd & 0x04) >> 2;
    data7 = (cmnd & 0x08) >> 3;
    
    E = 1;
    Delay10KTCYx (delai);
    E = 0;
}
void LCD_Charact (unsigned char charact)
{
    // Permet d'appliquer les bits du caractère sur les bonnes PINs de sortie (en fonction des define)
    // Enables character bits to be applied to the correct output PINs (depending on define)
    data4 = (charact & 0x10) >> 4;
    data5 = (charact & 0x20) >> 5;
    data6 = (charact & 0x40) >> 6;
    data7 = (charact & 0x80) >> 7;
    
    RS = 1;                         // mode caractère
    E = 1;
    Delay10KTCYx (delai); 
    E = 0;
    
    data4 = charact & 0x01;
    data5 = (charact & 0x02) >> 1;
    data6 = (charact & 0x04) >> 2;
    data7 = (charact & 0x08) >> 3;
    
    E = 1;
    Delay10KTCYx (delai); 
    E = 0;
}
void init_LCD (void)
{
    // Mise en sortie des PINs choisis en sortie
    // Output selected PINs
    data4DEF = 0;
    data5DEF = 0;
    data6DEF = 0;
    data7DEF = 0;
    RSDEF = 0;
    RWDEF = 0;
    EDEF = 0;
    RW = 0;
    LCD_Cmnd(0x28);           // Mode 4bits, 2 lignes 
    LCD_Cmnd(0x01);           // Clear l'écran
    LCD_Cmnd(0x0C);           // Display on, cursor off (0x0F - Display on, cursor clignotant)
}
void init_UART(void) {
    SPBRG = 25;                 // Basé sur la formule (((4000000/9600)/64)-1) //Mettre la trensmition sur 2400 si SPBRG=25
    TXSTAbits.SYNC = 0;         // Mode asynchrone
    TXSTAbits.BRGH = 0;         // Mode low speed
    RCSTAbits.SPEN = 1;         // Activer le port série (TX et RX)
    RCSTAbits.CREN = 1;         // Activer la réception               
}
// ********************************************* Code Principal *********************************************
void main (void) 
{  
    char tabGPS[100];
    int i;
    int y;
    
    init_UART();
    init_LCD();
    
    while (1){
        
        // Charger le tableau avec les données du GPS
        // Load table with GPS data
        for (i=0;i<100;i++){
            while (PIR1bits.RCIF == 0);         // Attendre qu'un caractère soit reçu
            tabGPS[i]= RCREG; 
        }
        
        // Parcouir le tableau et afficher ce qui nous interesse 
        // Browse the table and display what interests us 
        for (y=0;y<100;y++){
           if (tabGPS[y] == 'G' && tabGPS[y+1] == 'P' && tabGPS[y+2] == 'R'&& tabGPS[y+3] == 'M'&& tabGPS[y+4] == 'C'){
                LCD_Cmnd(0x80);
                LCD_Charact(tabGPS[y+6]);
                LCD_Charact(tabGPS[y+7]);
                LCD_Charact(':');
                LCD_Charact(tabGPS[y+8]);
                LCD_Charact(tabGPS[y+9]);
                LCD_Charact(':');
                LCD_Charact(tabGPS[y+10]);
                LCD_Charact(tabGPS[y+11]);
                }
            } 
    }
} 
								 
			     
             
					