Bienvenue aux nouveaux arrivants sur FantasPic !

- Pensez à lire les règles durant votre visite, il n'y en a pas beaucoup, mais encore faut-il les respecter .
- N’hésitez pas à faire des remarques et/ou suggestions sur le Forum, dans le but de l'améliorer et de rendre vos prochaines visites plus agréables.
- Vous pouvez regarder votre "panneau de l'utilisateur" afin de configurer vos préférences.
- Un passage par "l'utilisation du forum" est recommandé pour connaître les fonctionnalités du forum.

--- L’équipe FantasPic ---
Forum général sur le langage C !

Modérateur : Jérémy

Pbm d'affichage de caractere sur LCD
francknvs
Débutant
Débutant
Messages : 82
Enregistré en : septembre 2017
Localisation : Paca-toulon

#11 Message par francknvs » dim. 2 déc. 2018 19:09

Bonsoir à tous,
j'ai vraiment beaucoup de mal avec la fonction UART_Read () utilisée dans interrup:

j'ecume les tuto, les conseils, les exemples...je n'y arrive pas

j'ai bien compris l'utilisation de la fct : strchr(MSG, 13);
mais je ne sais où la placer dans mon code:
-->dans le main?, en dehors du main?
-->dans la fct UART_Read()?
--->dans l'interruption?
j'ai déclaré un tabeau de caractere char SMS[80]
Mon sms reçu traité par l'uart rempli bien ce tableau à partir de l'indice [50]
mais je n'arrive pas à afficher sur le Lcd l'ensemble du Message SMS reçu par le Module
Je n'arrive pas à lui faire detecter la fin du SMS se terminant par OD-OA
La seule façon pour afficher l'ensemble du sms et de connaitre à l'avance le nombre de caractere envoyer:
En dehors de ce nombre de caractere j'ai un decalage sur l'ensemble des lignes de l'afficheur.

Quelqu'un peut il modifier mon code source ci-joint,afin que je puisse comprendre comment cela fonctionne après compilation?
Par avance merci,..je galere vraiment :mur: :mur: :mur:

Code : Tout sélectionner

 //******************************************************************************
// microcontroller : P16F877a
// Compilateur: hi-Tech
// IDE: MPLAB IDE-V8.92
// Programmateur: ICD3
//
// Project:GSM808_lcd_Gps_V1
/*
Protocole de com UART/
    -Mode: Asynchro
    -Bit: 8
    -Parité: Aucune
    -Vitesse:9600 Bauds

Ce projet consiste à:
    --> envoyer un SMS via 16f877a:        ok
    --> Génération d'interruption uart:    ok
        ---> Lire UART via une condition if '+' : ok
        ---> Envoyé la lecture selon condition sur LCD: ok
        ---> Présenter la lecture sur LCD dans bon ordre: ok            


/* Les essais de reception sont visualisés sur RealTime*/

/* exemple de trame de reception SMS */
/*+CMT: "+336xxxxxxxx","","18/11/25,21:03:44+08"*/
/* Essai*/


//*****************************************************************
//--------------INCLUSION DES FICHIERS HEADER----------------------
//*****************************************************************

#include <htc.h> //chargement des en-tete issu du compilateur lors de la compilation
#include <pic16f877a.h> //chargement des en-tete issu du compilateur lors de la compilation
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//*****************************************************************
//-------------definition des registres Systemes-------------------
//*****************************************************************


//*****************************************************************
//------------definition des fichiers temporels--------------------
//*****************************************************************

// valeur du Quartz en Hz utilisé sur le pic
 #define _XTAL_FREQ 20000000
// on pourra utilser les fonctions declarées dans <pic.h> pointé par <htc.h> apres compilation
// __delay_us(1)-> valeur imprecise verifiée à l'oscillo (tjrs +4µs mesuré)
// __delay_ms(1)-> valeur precise verifiée à l'oscillo
// __delay_s(1) -> valeur precise verifiée à l'oscillo


//*****************************************************************
//------------definition des fusibles de configuration-------------
//             PIC16F876A Configuration Bit Settings
//*****************************************************************

__CONFIG(FOSC_HS & WDTE_OFF & PWRTE_OFF & BOREN_OFF & LVP_OFF & CPD_OFF & WRT_OFF & CP_OFF);

//*****************************************************************
//---------------------VARIABLES GENERALES-------------------------
//*****************************************************************
//---Définitions des Bits

#define LCD_RS    RA0 
#define    LCD_E  RA1 
#define    VERT  RD0
#define    RED  RD1
#define    ORANGE  RD2
//---Définitions des Variables Tableaux
    char MSG[80]="";
    char SMS[80]="";

    char Data_lue; 
//---Définitions des Variables Compteurs
static    int    j=0;
 
//*****************************************************************
//--------------PROTOTYPE DES FONCTIONS LOCALES--------------------
//*****************************************************************
//---Fct_UART---
void UART_Init();
char UART_Read();    // Fct lecture de caractere
void UART_Read_Text(char *Output, unsigned int length);
void UART_Write(char caractere);// Fct d'ecriture de caractere
void UART_Write_Text(char* text);


//---fct_LCD---
void LCD_Init(void);

void lcd_enable(void);
void lcd_write_4bit(unsigned char c);//Routine d'ecriture 4bit sur PORTB_DATA
void lcd_write_cmd(unsigned char c);// Ecriture d'une commande
void lcd_putch(char c); // Ecriture d'1 caractere
void lcd_puts(const unsigned char *chaine);// Ecriture d'1 chaine de caractere
void lcd_pos(unsigned char ligne,unsigned char pos);

//---fct_SMS---
void GSM_Init();
void SendSms();


//*****************************************************************
//-----------SOUS-PROGRAMME D INTERRUPTION-------------------------
//*****************************************************************

/*    Fonction: Interruption UART

Si une Data est reçu dans le registre RCREG, 
    -->un Flag de reception RCIF==1 du registre PIR1 est positionné
    -->Il faut imperativement faire une lecture UART du registre RCREG pour le vider
    -->Apres lecture, ce flag est remis à 0 Automatiquement
*/



void interrupt UART()    //Pas besoin de la prototyper puisque non utlisée dans le main
{


// mettre ici les declaration?

   if(RCIF==1)    // //test le buffer RCREG si plein
                  // RCIF=1---> signifie que le buffer de reception est plein (donnée reçu)
                  // RCIF=0---> signifie que le buffer de Reception est vide (rien reçu)
     {


                            //-------------------------Lecture du Numero date----------
                                j=0;
                                do    // boucle do  
                                    {
                                      Data_lue = UART_Read();
                                    MSG[j] = Data_lue;// ici on place dans MSG [j] la valeur de Data_lue pour, j=0 jusqu'à j<50
                                    } while( ++j<50);
                            //-------------------------Lecture du sms----------
                            

                                j
=50;
                                do    // boucle do  
                                    {
                                      Data_lue = UART_Read();
                                    SMS[j] = Data_lue;// ici on place dans MSG [j] la valeur de Data_lue pour, j=0 jusqu'à j<57
                                                      // 57 car 5 caracteres + 2 autres (OD et OA)
                                    } while(++j<57);                            

                                
                        


//----------------------FIN DU TRAITEMENT PAR UART??????----------------------------------------------------------
    //----------------------AFFICHAGE SUR ECRAN LCD-------------------------------------------------------------------
                            //-------------------------Affichage du Numero----------    
                                lcd_pos(0x01,0x03);
                                j=9;
                                do
                                    
{
                                     Data_lue = MSG[j];
                                       lcd_putch(Data_lue);    //affichage sur LCD  ou lcd_puts
                                    }while( ++j<21);                                

                            
//-------------------------Affichage de l'Heure----------    
                                lcd_pos(0x02,0x04);
                                j=27;
                                do
                                    
{
                                     Data_lue = MSG[j];
                                       lcd_putch(Data_lue);    //affichage sur LCD  ou lcd_puts
                                    }while( ++j<35);

                            //-------------------------Affichage du SMS----------lcd_putch
                                lcd_pos(0x03,0x04);
                        

                                j
=50;
                                do
                                    
{
                                     Data_lue = SMS[j];
                                       lcd_putch(Data_lue);    //affichage de 9 caracteres sur LCD 
                                    }while( ++j<55);

                            

    
}//Fin du 1er if




    

 


}// JE SORS DE L INTERRUPTION UART

//*****************************************************************
//-------------DEBUT DU PROGRAMME PRINCIPAL Main()-----------------
//*****************************************************************


void main()
{
    
//---Déclartion des variables Locales


/**************INITIALISATION DES REGISTRES*****************/
   
    ADCON1 
=    0b00000110; // Tout PORTA en Numerique
    CMCON =     0b00000111; // Désactivation du Module Comparateur            
    OPTION_REG= 0b10000000; // Resistances de tirage à +VCC du PORTB désactivées 
//    INTCON=     0b00000000; // Tout Interruption de controle déactivées
//---DIRECTION DES PORTS
    TRISA = 0b00000000; // --RA5-RA4-RA3-RA2-RS-E      
    TRISB = 0b11000000; //PGM-PGC-RB5-RB4-D7-D6-D5-D4
    TRISC = 0b10111111; // Configuration RX=RC7 en Entrée & TX=RC6 en Sortie
    TRISD = 0b00000000; // Tout en Sortie
//---INITIALISATION DES PORTS
    PORTA = 0b00000000;    
       PORTB 
= 0b00000000;             
      PORTD 
= 0b00000000;
//---INITIALISATION DES FONCTIONS
//--UART
    UART_Init();        //Initialize UART
//--LCD
    LCD_Init();            //Initialize LCD
//--GSM
    GSM_Init();            //Initialize GSM
/****************************************************/

lcd_pos(0x00,0x03);
lcd_puts("GSM 808");    
lcd_pos
(0x01,0x00);
lcd_puts("Du:");
lcd_pos(0x02,0x00);             
lcd_puts
("Dte:");                
lcd_pos
(0x03,0x00);                                                                
lcd_puts
("Msg:");

    while (1)
        {
            VERT=1;
            
        
}// fin du while

}// fin du main

/**************************************************************************************************
*--1-- Fonction: UART
**************************************************************************************************/

            /*---ECRITURE---*/

// Ecriture d'un caractere
void UART_Write(char caractere)
{
 while(!TXIF);  //Reste ici, Tant que le buffer TXREG est
                // RCIF=1---> signifie que le buffer de Transmission est vide (on peut le remplir)
                // RCIF=0---> signifie que le buffer de Transmission est plein (on peut le remplir)
 
    TXREG 
= caractere; //chargement du buffer avec la valeur TX reçue
}

// Ecriture d'une Chaine de caractere
void UART_Write_Text(char* text)
{
    while(*text) //Si il y a un Char
        UART_Write(*text++); //proceder comme une donnée d'octet
}

/**************************************************************************************************
* Fonction: Lecture d'un caractere et d'une chaine de caractere dans UART
**************************************************************************************************/

            /*---LECTURE---*/

// Lecture d'un caractere
char UART_Read()
{
  if(OERR==1) // Verification d'Erreur du registre de reception RCSTA avec OERR=1
             //Si erreur, on procede à l'affacement du Bit OERR par le passage du Bit CREN de 0 à 1
    {
       CREN = 0; 
       CREN 
= 1; 
    
}
  while(RCIF==0);  //Reste ici, Tant que le buffer RCREG est vide
                  // RCIF=1---> signifie que le buffer de reception est plein (donnée reçu)
                  // RCIF=0---> signifie que le buffer de Reception est vide (rien reçu)
 
return RCREG 
; //Reception de la DATA et envoie à la fonction principale (main)
}

// Lecture d'une chaine de caractere
void UART_Read_Text(char *Output, unsigned int length)
{
    int i;
    for(int i=0;i<length;i++)
        Output[i] = UART_Read();
}

//****************************************************************
//----------------FONCTIONS RELATIVES AU LCD 4X20----------------
//****************************************************************

//--------Fonction de validation de donnée du bus
void lcd_enable(void)
{
__delay_us(100);
    LCD_E = 1;
__delay_us(100);
    LCD_E = 0;
__delay_us(100);
}

// Procédure d'initialisation de l'afficheur LCD en mode 4 bits 
void LCD_Init(void)
{
      

__delay_ms
(15);            // Attente après l'établissement de la tension d'alim

//-----------Initialisation du Mode 4bit------------
    lcd_write_cmd(0x33);// envoi 2 fois le MSB du Mode 8bit
    lcd_write_cmd(0x32);// envoi des MSB du Mode 8bit et MSB du Mode 4bit
    lcd_write_cmd(0x28);// envoi des MSB et LSB du Mode 4bit

//-----------Initialisation des Parametres du LCD---
    lcd_write_cmd(0x01);// effacer l'ecran
__delay_ms(5);            // Attente 
    lcd_write_cmd(0x0c);//incre gauche vers droite
__delay_ms(5);            // Attente 
    lcd_write_cmd(0x06);//incre sans decalage
__delay_ms(15);            // Attente 

}

// Ecriture d'un octet dans le LCD en mode 4 bits
void lcd_write_4bit(unsigned char c)
{
//---Trame d'envoi de MSB sur LCD
    PORTB =(c>>4);// Msb de rb3à rb0
    lcd_enable();
//---Trame d'envoi de LSB sur LCD 
    PORTB =(c);// lsb de rb3à rb0
    lcd_enable();
}

// Ecrit une instruction dans LCD
void lcd_write_cmd(unsigned char c)
{
    LCD_RS = 0; // Mode commande du lcd
    lcd_write_4bit(c);
}

// Ecriture d'un caractere
void lcd_putch(char c)
{
    LCD_RS = 1;// Mode affichage du lcd
    lcd_write_4bit(c);
}

// Ecriture d'une chaine de caracteres
void lcd_puts(const unsigned char *chaine)
{
while(*
chaine)
    lcd_putch(*chaine++);
}

// Positionne le curseur ligne, position EN 4X20
// la premiere ligne est la ligne 0
void lcd_pos(unsigned char ligne,unsigned char pos)
{


if(
ligne<=0x01)
        {
        lcd_write_cmd(((ligne * 0x40)+pos)+0x80);
        }    
    else
        
{
        lcd_write_cmd(((ligne * 0x40)+pos)+0x14);
        }    
}
/**************************************************************************************************
* Fonction: Initialisation UART: 8Bits/Asyn/9600Bds
**************************************************************************************************/
void UART_Init()
{
 // Registre associé à l' emission (TX)
    TXSTAbits.TX9 = 0;        //9me Bit de la data transmise ou le bit de parité
    TXSTAbits.TXEN = 1;        //Validation de la transmission
    TXSTAbits.SYNC = 0;        //Selection du Mode Asynchrone 
    TXSTAbits.BRGH = 0;        // choix de la vitesse du Baud rate

 // Registre associé à la Reception (RX)
    RCSTAbits.SPEN = 1;        //Validation du port Serie
//    RCSTAbits.RX9 = 1;        //9me Bit Autorisé pour eviter l erreur de FERR
    RCSTAbits.CREN = 1;        //Validation de la Reception en Continue

//    Registre de config transmission
    SPBRG = 31;                //Vitesse du Baudrate en fct de SPBRG= Fosc/[64(X+1)] ==>20000000/[64(4800+1)]=31 pour 9600bds et 65 pour 4800
//---------------------------------------------------------------------    
    INTCONbits.GIE = 1;        //Validation des Interruptions Générales
    INTCONbits.PEIE = 1;    //Validation des Interruptions Péripheriques
    PIE1bits.RCIE = 1;        //Validation de l'interruption sur Recepetion du Bit RC
    PIR1bits.RCIF = 0;        //Effacement du Flag d'interruption sur Recption du Bit RC (par securité) 
}

/**************************************************************************************************
* Fonction: Initialisation GSM_808
**************************************************************************************************/
void GSM_Init()
    {
 //   __delay_ms(2000);
    UART_Write_Text("ATE0");   // AT command for Echo OFF
    UART_Write(13);
    UART_Write(10);
    __delay_ms(500);
    UART_Write_Text("AT+CMGF = 1");
    UART_Write(13);
    UART_Write(10);
    __delay_ms(500);
    UART_Write_Text("AT+CNMI=1,2,0,0,0");// ("AT+CNMI=1,2,0,0,0")---> ça marche avec
    UART_Write(13);
    UART_Write(10);
    __delay_ms(500);
    }

/**************************************************************************************************
*--2-- Fonction: Module GSM_808
**************************************************************************************************/

//--- Envoi d'un  SMS via la fct UART_Write_Text
void SendSms()
    {
 
    UART_Write_Text
("AT+CMGS=");
    UART_Write(0x22);// ouverture des guillements pour entrer le numero
    UART_Write_Text("+33612345678");
    UART_Write(0x22);// ouverture des guillements pour entrer le numero
    UART_Write(0x0D);
    __delay_ms(500);
    UART_Write_Text("envoi Reussi");
    UART_Write(26);// Ctrl+Z


    }
 

Pbm d'affichage de caractere sur LCD
Jérémy
Administrateur du site
Administrateur du site
Messages : 2722
Âge : 44
Enregistré en : juillet 2015
Localisation : Dans le sud
Contact :

#12 Message par Jérémy » dim. 2 déc. 2018 21:53

Hello,

Plusieurs problèmes .

Tu ne peux pas faire de boucle dans une interruption ! Ton interruption doit être le plus court possible !
Ton interruption se déclenche à chaque caractère reçus tu dois enregistrer ce caractère et ressortir !

dans ton Interruption tu récupérer et stocker ton message . Une fois que c'est finis! tu léves un Flag pour qui signaler a ton Main que tu as un message un afficher.

Attention un chaine de caractère doit ce terminer un terminateur de chaine un zéro "/0 " si tu veux utilsier des fonctions traitant des chaines de caractères.

Juste en faisant des copier/coller , un verrais plus un truc dans ce genre !

Code : Tout sélectionner

void interrupt UART()    //Pas besoin de la prototyper puisque non utlisée dans le main
{


// mettre ici les declaration? ---> surtout pas 


   if(RCIF==1)    // //test le buffer RCREG si plein
                  // RCIF=1---> signifie que le buffer de reception est plein (donnée reçu)
                  // RCIF=0---> signifie que le buffer de Reception est vide (rien reçu)
     {
        
        
DATA_LUE UART_READ();

                            //-------------------------LECTURE DU NUMERO DATE----------
                             if  J < 50  
                                    MSG
[J] = DATA_LUE;// ICI ON PLACE DANS MSG [J] LA VALEUR DE DATA_LUE POUR, J=0 JUSQU'À J<50
                                 ++J;
                          
                            
                            
//-------------------------LECTURE DU SMS----------                  
                  if 50    
                                    SMS
[J] = DATA_LUE;// ICI ON PLACE DANS MSG [J] LA VALEUR DE DATA_LUE POUR, J=0 JUSQU'À J<57
                                                      // 57 CAR 5 CARACTERES + 2 AUTRES (OD ET OA)
                                 ++J
                                 
                            if j 
> 57 ---> fin du message je leve un drapeau et je RAZ JE
                                DRAPEAU 
= 1 ;
                                J = 0  

}// JE SORS DE L INTERRUPTION UART

MAIN {

 if drapeau == 1{        -----> MAJ de l'écran
                            //----------------------FIN DU TRAITEMENT PAR UART??????----------------------------------------------------------
                            //----------------------AFFICHAGE SUR ECRAN LCD-------------------------------------------------------------------
                            //-------------------------AFFICHAGE DU NUMERO----------    
                                LCD_POS(0X01,0X03);
                                J=9;
                                DO
                                    {
                                     DATA_LUE = MSG[J];
                                       LCD_PUTCH(DATA_LUE);    //AFFICHAGE SUR LCD  OU LCD_PUTS
                                    }WHILE( ++J<21);                                

                            //-------------------------AFFICHAGE DE L'
HEURE----------    
                                LCD_POS
(0X02,0X04);
                                J=27;
                                DO
                                    
{
                                     DATA_LUE = MSG[J];
                                       LCD_PUTCH(DATA_LUE);    //AFFICHAGE SUR LCD  OU LCD_PUTS
                                    }WHILE( ++J<35);

                            //-------------------------AFFICHAGE DU SMS----------LCD_PUTCH
                                LCD_POS(0X03,0X04);
                        

                                J
=50;
                                DO
                                    
{
                                     DATA_LUE = SMS[J];
                                       LCD_PUTCH(DATA_LUE);    //AFFICHAGE DE 9 CARACTERES SUR LCD 
                                    }WHILE( ++J<55);                           

    
}//Fin du 1er if  



Un truc du genre
C'est en faisant des erreurs, que l'on apprend le mieux !!!

Pbm d'affichage de caractere sur LCD
francknvs
Débutant
Débutant
Messages : 82
Enregistré en : septembre 2017
Localisation : Paca-toulon

#13 Message par francknvs » ven. 28 déc. 2018 18:00

Bonsoir à tous,
Je profite d'un peu de temps pour réactualiser mon programme par la richesse et l'utilité de vos conseils.
J'ai enfin réussi à afficher les chaines de caractère provenant de ma réception UART via l'interruption UART.

Avant de poursuivre mon projet (emission d'un SMS....),
j'ai toujours la fameuse question...


A/Question sur la déclaration du tableau MSG[80]

    1- J'ai déclaré ce tableau de caractère dans les variables Globales par : unsigned char MSG[80];
là aussi, ce n'est pas tres propre, je devrai le déclarer comme pointer pour des raisons de stabilité et de facilité
j'ai compris le mecanisque: on pointe vers une adresse qui contient la valeur,etc...

- mais j'ai beaucoup de mal à le mettre en œuvre pour comprendre concrètement son fonctionnement:
comment le déclarer?
où le déclarer?
comment initialiser?
etc...


En attendant je vous mets le code de réception SMS qui fonctionne à merveille en y mettant un Max de commentaire

Code : Tout sélectionner

//******************************************************************************
// microcontroller : P16F877a
// Compilateur: hi-Tech
// IDE: MPLAB IDE-V8.92
// Programmateur: ICD3
//
// Project:GSM808_lcd_Gps_V1
/*
Protocole de com UART/
    -Mode: Asynchro
    -Bit: 8
    -Parité: Aucune
    -Vitesse:9600 Bauds
les caracteres et correspondances/
    CR=0x0D=13=\r 
    LF=0x0A=10=\n

Ce projet consiste à:

A/Configuration du Module GSM SIM808/
    -Config Protocole UART:Ok (via QNavigator et doc)
    -Désactivation du Mode Echo: Ok
    -Selection du Mode Texte: Ok
    -Selection du Format des SMS: Ok

B/RECEPTION SMS
    --> Recevoir un SMS via 16f877a: ok
    --> Génération d'interruption uart:    ok
        ---> Lire le MSG reçu via UART : ok
        ---> Envoyé le MSG reçu sur LCD
             via une Boucle (Flag)de Condition (CR et LF): ok
        ---> Mise à jour du LCD entre chaque lecture: ok

C/EMISSION SMS
    --> Envoyer un SMS via 16f877a: en cours et à verifier
            
*/
//********************************************************************************************************************************
//--------------INCLUSION DES FICHIERS HEADER-------------------------------------------------------------------------------------
//********************************************************************************************************************************

#include <htc.h> //chargement des en-tete issu du compilateur lors de la compilation
#include <pic16f877a.h> //chargement des en-tete issu du compilateur lors de la compilation
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//********************************************************************************************************************************
//-------------definition des registres Systemes----------------------------------------------------------------------------------
//********************************************************************************************************************************


//********************************************************************************************************************************
//------------definition des fichiers temporels-----------------------------------------------------------------------------------
//********************************************************************************************************************************

// valeur du Quartz en Hz utilisé sur le pic
 #define _XTAL_FREQ 20000000
// on pourra utilser les fonctions declarées dans <pic.h> pointé par <htc.h> apres compilation
// __delay_us(1)-> valeur imprecise verifiée à l'oscillo (tjrs +4µs mesuré)
// __delay_ms(1)-> valeur precise verifiée à l'oscillo
// __delay_s(1) -> valeur precise verifiée à l'oscillo


//********************************************************************************************************************************
//------------definition des fusibles de configuration du PIC---------------------------------------------------------------------
//********************************************************************************************************************************

__CONFIG(FOSC_HS & WDTE_OFF & PWRTE_OFF & BOREN_OFF & LVP_OFF & CPD_OFF & WRT_OFF & CP_OFF);

//********************************************************************************************************************************
//---------------------VARIABLES GLOBALES-----------------------------------------------------------------------------------------
//********************************************************************************************************************************
//---Définitions des Bits
//PORTA:
#define LCD_RS    RA0 
#define    LCD_E  RA1 
#define    Inter  RA5

//PORTD:
#define    VERT  RD0
#define    RED  RD1
#define    ORANGE  RD2

//---Définitions des Variables Tableaux
unsigned char MSG[80];

//---Définitions des Variables & Compteurs
    int    j=0;
    int    flag=0; 
    int Drapeau
=0;

//********************************************************************************************************************************
//--------------PROTOTYPE DES FONCTIONS LOCALES-----------------------------------------------------------------------------------
//********************************************************************************************************************************
//---Fct_UART---
void UART_Init();
char UART_Read();    
void UART_Read_Text
(char *Output, unsigned int length);
void UART_Write(char caractere);// Fct d'ecriture de caractere
void UART_Write_Text(char* text);

//---fct_LCD---
void LCD_Init(void);
void lcd_enable(void);
void lcd_write_4bit(unsigned char c);
void lcd_write_cmd(unsigned char c);
void lcd_putch(char c);
void lcd_puts(const unsigned char *chaine);
void lcd_pos(unsigned char ligne,unsigned char pos);

//---fct_SMS---
void GSM_Init();
void SendSms();

//********************************************************************************************************************************
//-----------SOUS-PROGRAMME D INTERRUPTION----------------------------------------------------------------------------------------
//********************************************************************************************************************************

/*    Fonction: Interruption UART*/

void interrupt UART()    //Pas besoin de la prototyper puisque non utlisée dans le main
{
   if(RCIF==1)    // //test le buffer RCREG si plein
                  // RCIF=1---> signifie que le buffer de reception est plein (donnée reçu)
                  // RCIF=0---> signifie que le buffer de Reception est vide (rien reçu)
     {

                                  
                        
//-------------------------Lecture du MSG---------------
/*    Trame du MSG Reçu:    CrLf+CMT: "+336xxxxxxxx","","18/11/25,21:03:44+08"CrLf12345CrLf    */

        while (flag!=3)                // Tant que la valeur du compteur FLAG est different de 3 faire la boucle
        {
            MSG[j]= UART_Read();    // ici on place dans MSG [j] la valeur lue par UART
                if ((MSG[j]=='\n'))    // Si le caractere \n de la trame est détecté
                    {        
                    flag
++ ;        // j'incremente le compteur de Flag à +1
                    }
                j++;                // j'incremente le compteur d'indice de Lecture de MSG[j]
        }                            // le compteur Flag est egale à 3
        flag=0;                        // Je remets le compteur Flag à 0                            
        Drapeau=1;                    // Mise à 1 du Drapeau conditionnel    
        
                                    
                        
//----------------------AFFICHAGE SUR ECRAN LCD---------
        // Routine permettant de visuliser l'arrivée d'un SMS                       
        RED=~RED;
        __delay_ms(50);
        RED=~RED;
        __delay_ms(50);
        RED=~RED;
        __delay_ms(50);
        RED=~RED;

        // Effacement des lignes du LCD        
        lcd_pos(0x03,0x04);                                                                
        lcd_puts
("                ");

    }

}
//********************************************************************************************************************************
//-------------DEBUT DU PROGRAMME PRINCIPAL Main()--------------------------------------------------------------------------------
//********************************************************************************************************************************


void main()
{
    
//*********************Début des Déclaration des variables Locales**********************//


//---INITIALISATION DES REGISTRES 
    ADCON1 =    0b00000110; // Tout PORTA en Numerique
    CMCON =     0b00000111; // Désactivation du Module Comparateur            
    OPTION_REG= 0b10000000; // Resistances de tirage à +VCC du PORTB désactivées 
//    INTCON=     0b00000000; // Tout Interruption de controle déactivées

//---DIRECTION DES PORTS
    TRISA = 0b00100000; // --RA5-RA4-RA3-RA2-RS-E      
    TRISB = 0b11000000; //PGM-PGC-RB5-RB4-D7-D6-D5-D4
    TRISC = 0b10111111; // Configuration RX=RC7 en Entrée & TX=RC6 en Sortie
    TRISD = 0b00000000; // Tout en Sortie

//---INITIALISATION DES PORTS
    PORTA = 0b00000000;    
       PORTB 
= 0b00000000;             
      PORTD 
= 0b00000000;

//---INITIALISATION DES FONCTIONS
//--UART
    UART_Init();        //Initialize UART

//--LCD
    LCD_Init();            //Initialize LCD

//--GSM
//    GSM_Init();            //Initialize GSM

//*********************Fin des Déclarations des variables Locales*********************//

lcd_pos(0x00,0x03);
lcd_puts("GSM 808");    
lcd_pos
(0x01,0x00);
lcd_puts("Du:");
lcd_pos(0x02,0x00);             
lcd_puts
("Hrs:");                
lcd_pos
(0x03,0x00);                                                                
lcd_puts
("Msg:");

    while (1)
        {
        
            switch 
(Drapeau)
            {
            case 0: // Si la valeur du Drapeau conditionnel est à 0
                VERT=1;    
                break
;
            
            case 1
:// Si la valeur du Drapeau conditionnel est à 1

                        //------------------------Affichage du Numero-----------
                lcd_pos(0x01,0x03);
                j=9;                 // A partir l'indice de MSG[9]
                do
                
{
                lcd_putch(MSG[j]);     // Affichage sur LCD
                }while( ++j<21);      // J'incremente le compteur d'indice de MSG[j] tant que celui-ci est inferieur à 21--> MSG[20]
                                                                                
                        
//-------------------------Affichage de l'Heure----------    
                lcd_pos(0x02,0x04);
                j=36;
                do
                
{
                lcd_putch(MSG[j]);    
                
}while( ++j<44);

                        //-------------------------Affichage du SMS--------------
                lcd_pos(0x03,0x04);
                j=50;                  // A partir l'indice de MSG[50]--> Debut du SMS (voir trame)
                while((MSG[j]!='\r')) // Tant que le contenu de MSG[j] est different de \r --> Fin du SMS (voir trame)
                {
                lcd_putch(MSG[j]);      // Affichage sur LCD
                  j++;                  // J'incremente le compteur d'indice de MSG[j]
                }
                j=0;                  // Je remets le compteur à 0
                Drapeau=0;              // Mise à 0 du Drapeau conditionnel
                break;
            }
            

        
}// fin du while

}// fin du main

//********************************************************************************************************************************
// Fonction: Ecriture dans UART---------------------------------------------------------------------------------------------------
//********************************************************************************************************************************

// Fonction d'écriture d'un caractere
void UART_Write(char caractere)
{
 while(!TXIF);  //Reste ici, Tant que le buffer TXREG est
                // RCIF=1---> signifie que le buffer de Transmission est vide (on peut le remplir)
                // RCIF=0---> signifie que le buffer de Transmission est plein (on peut le remplir)
   
    TXREG 
= caractere; //chargement du buffer avec la valeur TX reçue
}

// Fonction d'écriture d'une Chaine de caractere
void UART_Write_Text(char* text)
{
    while(*text) //Si il y a un Char
        UART_Write(*text++); //proceder comme une donnée d'octet
}

//********************************************************************************************************************************
// Fonction: Lecture dans UART----------------------------------------------------------------------------------------------------
//********************************************************************************************************************************

// Fonction de Lecture d'un caractere
char UART_Read()
{
  if(OERR==1) // Verification d'Erreur du registre de reception RCSTA avec OERR=1
             //Si erreur, on procede à l'affacement du Bit OERR par le passage du Bit CREN de 0 à 1
    {
       CREN = 0; 
       CREN 
= 1; 
    
}
  while(RCIF==0);  // ou bien while(!RCIF)  Reste ici, Tant que le buffer RCREG est vide
                  // RCIF=1---> signifie que le buffer de reception est plein (donnée reçu)
                  // RCIF=0---> signifie que le buffer de Reception est vide (rien reçu)

return RCREG ; //Reception de la DATA et envoie à la fonction principale (main)
}

// Fonction de Lecture d'une chaine de caractere
void UART_Read_Text(char *Output, unsigned int length)
{
    int i;
    for(int i=0;i<length;i++)
        Output[i] = UART_Read();
}

//********************************************************************************************************************************
//----------------FONCTIONS RELATIVES AU LCD 4X20---------------------------------------------------------------------------------
//********************************************************************************************************************************

// Fonction de validation de donnée sur bus
void lcd_enable(void)
{
__delay_us(100);
    LCD_E = 1;
__delay_us(100);
    LCD_E = 0;
__delay_us(100);
}

// Fonction d'initialisation de l'afficheur LCD en mode 4 bits 
void LCD_Init(void)
{
      
__delay_ms
(15);            // Attente après l'établissement de la tension d'alim

//-----------Initialisation du Mode 4bit------------
    lcd_write_cmd(0x33);// envoi 2 fois le MSB du Mode 8bit
    lcd_write_cmd(0x32);// envoi des MSB du Mode 8bit et MSB du Mode 4bit
    lcd_write_cmd(0x28);// envoi des MSB et LSB du Mode 4bit

//-----------Initialisation des Parametres du LCD---
    lcd_write_cmd(0x01);// effacer l'ecran
__delay_ms(5);            // Attente 
    lcd_write_cmd(0x0c);//incre gauche vers droite
__delay_ms(5);            // Attente 
    lcd_write_cmd(0x06);//incre sans decalage
__delay_ms(15);            // Attente 

}

// Fonction d'écriture d'un octet dans le LCD en mode 4 bits
void lcd_write_4bit(unsigned char c)
{
//---Trame d'envoi de MSB sur LCD
    PORTB =(c>>4);// Msb de rb3à rb0
    lcd_enable();
//---Trame d'envoi de LSB sur LCD 
    PORTB =(c);// lsb de rb3à rb0
    lcd_enable();
}

// Fonction d'écriture d'une Commande dans LCD
void lcd_write_cmd(unsigned char c)
{
    LCD_RS = 0; // Mode commande du lcd
    lcd_write_4bit(c);
}

// Fonction d'écriture d'un caractere
void lcd_putch(char c)
{
    LCD_RS = 1;// Mode affichage du lcd
    lcd_write_4bit(c);
}

// Fonction d'écriture d'une chaine de caracteres
void lcd_puts(const unsigned char *chaine)
{
while(*
chaine)
    lcd_putch(*chaine++);
}

// Fonction de Positionnement du curseur: ligne, position 
void lcd_pos(unsigned char ligne,unsigned char pos)
{
if(
ligne<=0x01)
        {
        lcd_write_cmd(((ligne * 0x40)+pos)+0x80);
        }    
    else
        
{
        lcd_write_cmd(((ligne * 0x40)+pos)+0x14);
        }    
}
//********************************************************************************************************************************
// Fonction: Initialisation UART: 8Bits/Asyn/9600Bds------------------------------------------------------------------------------
//********************************************************************************************************************************
void UART_Init()
{
 // Registre associé à l' emission (TX)
    TXSTAbits.TX9 = 0;        //9me Bit de la data transmise ou le bit de parité
    TXSTAbits.TXEN = 1;        //Validation de la transmission
    TXSTAbits.SYNC = 0;        //Selection du Mode Asynchrone 
    TXSTAbits.BRGH = 0;        // choix de la vitesse du Baud rate

 // Registre associé à la Reception (RX)
    RCSTAbits.SPEN = 1;        //Validation du port Serie
    RCSTAbits.RX9 = 0;        //9me Bit Autorisé pour eviter l erreur de FERR
    RCSTAbits.CREN = 1;        //Validation de la Reception en Continue

//    Registre de config transmission
    SPBRG = 31;                //Vitesse du Baudrate en fct de SPBRG= Fosc/[64(X+1)] ==>20000000/[64(4800+1)]=31 pour 9600bds et 65 pour 4800

//  Controle des Interrptions    
    INTCONbits.PEIE = 1;    //Validation des Interruptions Péripheriques
    INTCONbits.GIE = 1;        //Validation des Interruptions Générales
    PIR1bits.RCIF = 0;        //Effacement du Flag d'interruption sur Recption du Bit RC (par securité) 
    PIE1bits.RCIE = 1;        //Validation de l'interruption sur Recepetion du Bit RC

}

//********************************************************************************************************************************
// Fonction: Initialisation GSM_808-----------------------------------------------------------------------------------------------
//********************************************************************************************************************************
void GSM_Init()
    {
 //   __delay_ms(2000);
    UART_Write_Text("ATE0");   // AT command for Echo OFF
    UART_Write(13);
    UART_Write(10);
    __delay_ms(500);
    UART_Write_Text("AT+CMGF = 1"); // Mode Texte
    UART_Write(13);
    UART_Write(10);
    __delay_ms(500);
    UART_Write_Text("AT+CNMI=1,2,0,0,0"); // Format des SMS
    UART_Write(13);
    UART_Write(10);
    __delay_ms(500);
    }

//********************************************************************************************************************************
//--2-- Fonction: Module GSM_808--------------------------------------------------------------------------------------------------
//********************************************************************************************************************************

//--- Envoi d'un  SMS via la fct UART_Write_Text
void SendSms()
    {
 
    UART_Write_Text
("AT+CMGS=");
    UART_Write(0x22);// ouverture des guillements pour entrer le numero
    UART_Write_Text("+336xxxxxxxxx");
    UART_Write(0x22);// ouverture des guillements pour entrer le numero
    UART_Write(0x0D);
    __delay_ms(500);
    UART_Write_Text("envoi Reussi");
    UART_Write(26);// Ctrl+Z


    }

 

Pbm d'affichage de caractere sur LCD
paulfjujo
Avatar de l’utilisateur
Expert
Expert
Messages : 2589
Âge : 73
Enregistré en : juillet 2015
Localisation : 01800
Contact :

#14 Message par paulfjujo » sam. 29 déc. 2018 12:30

francknvs a écrit : ... J'ai déclaré ce tableau de caractère dans les variables Globales par : unsigned char MSG[80];
là aussi, ce n'est pas tres propre, je devrai le déclarer comme pointer pour des raisons de stabilité et de facilité
....


l'emploi de pointeur n'est pas INDISPENSABLE ..

comment le déclarer?

le tableau est declaré comme d'habitude, pour reserver l'espace RAM
unsigned char MSG[80];
on declare un pointeur p1 sur type charactere
unsigned char * p1;

comment initialiser?

et dans le main on l'initialise pour pointer sur le 1er caractere du tableau
p1=&MSG[0];
ou p1=MSG; // mais pour ma part, je préfere la précedente init, plus explicite.

Code : Tout sélectionner

while (flag!=3)                // Tant que la valeur du compteur FLAG est different de 3 faire la boucle
        
{
            *(
p1+j)= UART_Read();    // ici on place dans MSG [j] la valeur lue par UART
                
if ((*(p1+j)=='\n'))    // Si le caractere \n de la trame est détecté
                    
{        
                    
flag++ ;        // j'incremente le compteur de Flag à +1
                    
}
                
j++;                // j'incremente le compteur d'indice de Lecture de MSG[j]
        
}              

 


l'avantage d'utiliser un pointeur n'est pas evident dans cet exemple precis..
mais plus utile dans le cas de comparaison de chaine :
exemple , tiré d'une trame compteur EDF contenant "IINST 007"
pour extirper la valeur AMps

Code : Tout sélectionner

// buffer_Analyse  = buffer de reception UART
  
char p3;  // déclaré,mais non initialisé

  
p3=strstr(Buffer_Analyse,"IINST"); // affectation du pointeur  
  
if (p3>0)
             {  
p3=p3+6;    // se positionne apres "IINST "
                
*(p3+9)=0;  // un zero terminateur de string pour ne pas prendre ce qui suit
                 
Amps=atoi(p3);
                 
WordToStrWithZeros(Amps,CRam1);
                
// Gauge ronde (0-30 Amps)  et Text  I.Instant  (Amps)
                 
UART1_Write('*'); UART1_Write('A');
                 
UART1_Write_Text(CRam1); UART1_Write('*');UART1_Write(',') ;      
   }
 


******* remarques sur le code **************
:sifflotte: ce que j'aurais fait ... mais ce n'est pas une référence en soi !

mettre plutot cette partie là, dans le main,
Tempo et traitement LCD à eviter dans l'interrupt

Code : Tout sélectionner


                      
        
//----------------------AFFICHAGE SUR ECRAN LCD---------
        // Routine permettant de visuliser l'arrivée d'un SMS                       
        
RED=~RED;
        
__delay_ms(50);
        
RED=~RED;
        
__delay_ms(50);
        
RED=~RED;
        
__delay_ms(50);
        
RED=~RED;

        
// Effacement des lignes du LCD        
        
lcd_pos(0x03,0x04);                                                                
        
lcd_puts("                ");
            


dans le main :

Code : Tout sélectionner


  
........
      case 
1:// Si la valeur du Drapeau conditionnel est à 1
        //----------------------AFFICHAGE SUR ECRAN LCD---------
        // Routine permettant de visuliser l'arrivée d'un SMS                       
        
RED=~RED;
        
__delay_ms(50);
        
RED=~RED;
        
__delay_ms(50);
        
RED=~RED;
        
__delay_ms(50);
        
RED=~RED;

        
// Effacement des lignes du LCD        
        
lcd_pos(0x03,0x04);                                                                
        
lcd_puts("                ");
        
//------------------------Affichage du Numero-----------
  
.......         
          



on pourrait aussi , des que le flag DRAPEAU est monté dans l'interruption,
interdire toute nouvelle modification du buffer de reception MSG
en attendant que son contenu soit traité dans le main

Code : Tout sélectionner


        flag
=0;                        // Je remets le compteur Flag à 0                            
        
Drapeau=1;                    // Mise à 1 du Drapeau conditionnel    
        
PIE1bits.RCIE 0;      //  on a notre TAF de caracteres , STOP
 

et donc, dans le main , en fin de traitement case,
remettre PIE1bits.RCIE = 1;

Code : Tout sélectionner

//declarations
char Cx;
....
        ....... 
main .....
                
Drapeau=0;              // Mise à 0 du Drapeau conditionnel
                
Cx=RCREG;         // une lecture registre reception pour effacer un eventuel flag RCIF
                
PIE1bits.RCIE 1
                break;
            }
        } 
//fin du while
         
Aide toi, le ciel ou FantasPic t'aidera

Pbm d'affichage de caractere sur LCD
francknvs
Débutant
Débutant
Messages : 82
Enregistré en : septembre 2017
Localisation : Paca-toulon

#15 Message par francknvs » sam. 29 déc. 2018 18:02

Bonsoir Paul,

Un grand merci pour avoir répondu aux questions que je me posais.
de plus, tes exemples sont adaptés à mon programme, je pourrai ainsi comprendre concrètement le mécanisme.

effectivement, le traitement de l'affichage,etc ....dans l'interrup n'est pas genial, (je l'avais laissé ici pour verifier l'entrée et la sortie de l'interruption)
je vais donc l’insérer dans le main à présent.

Encore Merci...et joyeuses fêtes de fin d'année


Retourner vers « Langage C »

Qui est en ligne

Utilisateurs parcourant ce forum : Aucun utilisateur enregistré et 39 invités