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

#1 Message par francknvs » dim. 25 nov. 2018 12:45

Bonjour à Tous,

Depuis qqs temps , je bloque sur l'affichage des caractères sur LCD
Je travaille sur la réception de msg SMS via module GSM-808
Le format de la trame de reception SMS est de la forme:
CRLF
+CMT: "+336xxxxxxxx","","18/11/25,21:03:44+08"CRLF
le msg sms CRFL CRFL

Je fais une lecture UART sur l'ensemble de la trame que l'envoie dans 2 tableaux
le 1er-> pour le "msg" comprenant le numéro de l’émetteur, l'heure, la date....jusqu'au premier CR
le 2me->pour le corps du SMS recu ,dans le tableau SMS

Mon probleme etant de devoir connaitre le nombre de caractere du SMS pour pouvoir l'afficher sinon ça plante
dans mon code joint, mon SMS doit contenir STRICTEMENT 9 caractères ( de 50 à 58).
Si je reçois un SMS d'une longueur de caractere differents, j'ai des incoherences d'affichage (un decalage de caractère) et je suis obligé de reseter mon PIC.

Je souhaiterai pouvoir afficher l'ensemble du SMS reçu quelque soit sa longueur ( 16 caracteres max)

merci pour vos réponses.

Nota:
pour le moment je ne veux pas passer par l'inter UART
n'etant pas à l'aise avec les tableaux, je ne me suis pas risqué à utiliser les pointeurs...
apres compréhension, je m y attaquerai....etape par etape..

Mon code projet:

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
    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
{
  
}

//*****************************************************************
//-------------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)
        {
                            //-------------------------Lecture du Numero & date----------
                                j=0;
                                do    // boucle do  
                                    {
                                      Data_lue = UART_Read();
                                    MSG[j] = Data_lue;// ici on place dans NUM [j] la valeur de recept pour, j=2 jusqu'à j<14
                                    } while( ++j<50);

                            //-------------------------Lecture du SMS----------
                                j=50;
                                do    // boucle do  
                                    {
                                      Data_lue = UART_Read();
                                    SMS[j] = Data_lue;// ici on place dans NUM [j] la valeur de recept pour, j=2 jusqu'à j<14
                                    } while( ++j<61);  //TANT QUE N EST PAS EGALE A CR???


    //**************************************AFFICHAGE SUR 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<59);

        }// 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("+336xxxxxxx");
    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 :

#2 Message par paulfjujo » dim. 25 nov. 2018 13:20

bonjour,


Tout baser sur la reception asynchrone d'un nombre exact de characteres ( bytes) est perillieux et non fiable
il te faut passer par l'interrupt UART ! pour ne pas rater des bytes.
ensuite dans l'interrupt soit tu passes par une table de reception et un flag monté sur detection de CR
en fait il faudra monter le flage Apres le 2em CR
Flag=0 en attente
Flag=1 tiens j'ai vu passer un CR
Flag=2 voila le 2em CR .. je vide le buffer UART pour enlever le LF qui suit !
et je traite le contenu de la table
test GSM + GPS avec 18F87J50


ou via une state-machine (decodage en ligne byte par byte)
voir appli GSM2 click de Jeremy

nota: avec un affichage LCD ou terminal, attention aux LF qui trainent et peuvent effacer le message affiché!
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

#3 Message par francknvs » dim. 25 nov. 2018 13:52

bonjour paul et merci pour ta réactivité

j'avais également pensé qu'il fallait passer par l interruption UART
merci pour ton lien que j'avais déja visité
je m y perd un peu car tu traites plusieurs solutions (4)
moi je cherche une solution de reception SMS

je vais adapter mon code précedemment joint dans l'interruption UART
Quant à la création de flag1,flag2,...je ne sais pas trop comment faire...je vais essayer


je laisse ce post ouvert tant que je n y suis pas arrivé

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 :

#4 Message par Jérémy » dim. 25 nov. 2018 14:01

 ! Message de modération :
Hello francknvs,

J'ai déplacé ton message dans la bonne catégorie


J'ai traite un peu ce sujet ici :
viewtopic.php?f=10&t=272

De quoi te faire un peu de lecture. Il faut absolument que tu traites la reception avec une INT .?
La méthode de Paul est bien . Je trouve la mienne bien aussi. lol .

Si je devais refaire quelques choses avec un GSM, je penche je choisirais une autre façon encore .
JE récupère tout mon message dans un buffer. Ensuite je compare les chaines de caracteres dans mon buffer , avec ce que je veux trouver !
Qu'elle que chose dans ce genre .

Bon courage
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

#5 Message par francknvs » dim. 25 nov. 2018 14:46

Bonjour jeremy

oui c'est ce que j'ai fais
j'ai tout récupéré dans un tableau MSG[80] et puis je me sers de ce que j'ai besoin
mais il y a le pbm de la longueur du sms qui peut etre aleatoire
je peux recevoir 5,10,15 caracteres, ce n 'est pas une chose que je peux savoir ou alors dire à mes correspondant:
attention le sms que tu m'envois ne peux execeder ou etre inferieur à 5,10 ou 15 caracteres


Dans mon code j'envoie un sms de 9 caracteres
et je suis obligé de scinder ma variable aux CR LF en comptant le nbre de caratere pour connaitre le de debut et la fin de mon sms

j'ai essayé d'utiliser l'interruption UART
je dois avoir un soucis sur la declaration des variables ( dans le main ou en dehors...)
la condition de l'interruption UART
l'affichage sur le LCD
BREF, je ne m'en sord pas avec cette interruption
je n'arrive pas à trouver qqc de propre
-où dois remettre à zero mon flag d'inter?
-l'affichage peut il se faire en dehors de l'interruption?,
-mes variables doivent elles etre déclarées avant le main ou dans le main?
-etc...

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 Data_lue; 
//---Définitions des Variables Compteurs
    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
{


   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)

     {

//       UART_Read();    //je lis le buffer 
                
//        while ((MSG[j] != 0x0D));  //tant que l'indice i de RECU n'est ps egale à CR !!!

             while (UART_Read() != '+');//tant que la lecture l'UART n'est pas egale à '+' on reste là!!!
                Data_lue= UART_Read(); // lecture de RC7 et placer la valeur dans recept 
                    if (Data_lue == 'C')    // si la valeur de recept et strictement egale à 'C'
                     {
                        Data_lue = UART_Read(); // on continue la lecture de RC7....
                        if (Data_lue == 'M')    // si la valeur de recept et strictement egale à 'M'    
                         {
                             Data_lue = UART_Read(); // on continue la lecture de RC7....
                            if (Data_lue == 'T')    // si la valeur de recept et strictement egale à 'T'
                             {
                                 Data_lue = UART_Read(); // on continue la lecture de RC7 pour sauter le ':'....
                                 Data_lue = UART_Read(); // on continue la lecture de RC7 pour sauter le ' '....
                                 Data_lue = UART_Read(); // on continue la lecture de RC7 pour sauter le '"'....
                            //-------------------------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();
                                    MSG[j] = Data_lue;// ici on place dans SMS [j] la valeur de Data_lue pour, j=50 jusqu'à j<61
                                                      // A partir de 50-> 9 caracteres + CR + LF= 50+9+2=61
                                    } while( ++j<61);  //TANT QUE N EST PAS EGALE A CR???
 
                            
}//Fin du 4me if
                          }//Fin du 3me if
                    }//Fin du 2me if    
    }//Fin du 1er if




    //----------------------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 = MSG[j];
                                       lcd_putch(Data_lue);    //affichage de 9 caracteres sur LCD 
                                    }while( ++j<59);


 
        RCIF
=0; // Effacer le flag pour clarifier l'interruption

}// 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("+33683316094");
    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
satinas
Expert
Expert
Messages : 1225
Enregistré en : novembre 2015

#6 Message par satinas » dim. 25 nov. 2018 15:25

Bonjour dominical,

Ce type de module envoie des tas de réponses différentes selon le contexte. Il ne faut pas essayer de traiter les octets qu'il envoie dès leur réception. Il est plus simple de lui envoyer une commande, puis d'avaler tout ce qu'il répond en le stockant dans un buffer.
Selon la commande, on attend un certain temps et ensuite on traite tranquillement le contenu du buffer. Si la réponse se termine toujours par "OK", on peut le détecter et arrêter aussitôt la réception.
Ainsi tu devrais pouvoir récupérer les SMS reçus sans problème.

Pour recevoir, c'est plus propre par interruption, mais si le pic ne fait que ça, la réception par polling, ça marche bien aussi hein :) Surtout au début quand on cherche à comprendre comment le module marche ...

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

#7 Message par francknvs » dim. 25 nov. 2018 16:34

Bonjour Satinas,
Merci pour tes réponses
effectivement le module envoi des tas de réponses differentes selon sa config
moi, je trouvais plus simple de ne pas lui poser de question et de traiter l'interrupt qd un SMS arrivait....
sinon on a la solution de lui demander d'afficher la commande AT en faisant passer le SMS par la SIM (fct de la config CNMI...)
+CMTI:"SM",x puis demander de lire le sms par :AT+CMGR=x
Mais je me retrouve toujours avec une réponse à traiter :
+CMT: "+336xxxxxxxxxxxx",,"01/03/22,16:33:31+00" [OD-OA]
texte bla bla bla [OD-OA]


Quant à la réception par polling,....je ne sais pas ce que c'est

Pbm d'affichage de caractere sur LCD
satinas
Expert
Expert
Messages : 1225
Enregistré en : novembre 2015

#8 Message par satinas » dim. 25 nov. 2018 16:51

La réception par polling, c'est celle que tu as utilisée dans la fonction UART1_Read(). On sonde le bit RCIF pour détecter une réception.

Pour la longueur du SMS, si la réponse record+SMS est dans le tableau MSG[], en utilisant la fonction strchr() qui cherche un caractère dans une chaîne, et retourne un pointeur si elle le trouve. On peut aussi faire la même chose en utilisant un pointeur qui scrute toute la chaîne. Il faut gérer le cas ou le caractère n'est pas trouvé, car le pointeur retourné est alors nul.

char *p = strchr(MSG, 13);
p = p+2;
int len_sms = strchr(p, 13) - p;

Et si tu ne veux pas utiliser les pointeurs, tu comptes les octets reçus, pour scinder le SMS en plusieurs morceaux, j'ai du mal à comprendre la question

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

#9 Message par francknvs » dim. 25 nov. 2018 17:33

oups, je me suis mal exprimé.
je scinde le msg reçu par le module:
[OD-OA]+CMT: "+336xxxxxxxxxxxx",,"01/03/22,16:33:31+00" [OD-OA]texte bla bla bla [OD-OA]
voila comment je vois les choses ou tout du moins ce que j'ai voulu faire faute de savoir:
j'initie une variable de type
char MSG[80]="";------> Celle-ci contient tout le msg reçu
l'indice [0 à 49] est toujours de la meme longueur car il contient: [OD-OA]+CMT: "+336xxxxxxxxxxxx",,"01/03/22,16:33:31+00" [OD-OA]
l'indice [50 à xxxxxx jusqu'à OD] contient le sms reçu, mais ne connaissant pas la longueur du SMS reçu c'est compliqué
raison pour laquelle je me suis obligé de pouvoir recevoir 9 caracteres pas 1 de plus et pas 1 de moins pour que cela fonctionne

je n'arrive pas à faire une fonction:
lis les caractères de l'indice [50] jusqu à trouver OD et affiche ces caracteres au lcd

Pbm d'affichage de caractere sur LCD
satinas
Expert
Expert
Messages : 1225
Enregistré en : novembre 2015

#10 Message par satinas » dim. 25 nov. 2018 18:00

Si on affiche sur une seule ligne, c'est ça, sinon tu adapteras, le modulo (%) est très utile dans ce cas de figure.
A la fin n contient la longueur du SMS.
Si le modulo est trop gourmand en cycles cpu, on le remplace par une variable qui compte de 0 à 9.

Code : Tout sélectionner

DisplaySms()
{
  int n=0, j=50;
  do {
    if (Msg[j] == 0x0d) break;
    if ((n%9) == 0)
    {
      lcd_pos(0x03,0x04);
      lcd_puts("         ");
      lcd_pos(0x03,0x04);
    }
    lcd_putch(Msg[j]);
    n++;
  } while (++j<80);
}


Retourner vers « Langage C »

Qui est en ligne

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