IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

 C Discussion :

Reformatage d'une chaine de caractère : je suis vraiment bloqué


Sujet :

C

  1. #1
    Membre du Club
    Inscrit en
    Septembre 2008
    Messages
    384
    Détails du profil
    Informations forums :
    Inscription : Septembre 2008
    Messages : 384
    Points : 52
    Points
    52
    Par défaut Reformatage d'une chaine de caractère : je suis vraiment bloqué
    Bonjour,

    J'ai besoin de votre d'aide car je n'en sort pas seul ...

    Je recois sur le port série des bytes uns à uns.

    Il s'agit d'une communication entre un PIC ( µC avec C embarqué ) et un modem.

    Le modem commence et fini systématiquement ses communications par le couple de caractères \r\n

    Mon but est de capturer chaque réponse du modem dans un buffer sans les caractères \r\n et d'insérer en fin de réponse le caractère \0 afin que la chaine de caractère soit exploitable.

    Le modem va par exemple envoyer ceci pour répondre "OK"
    \r\nOK\r\n\

    Si le modem reçoit un appel il envoi ceci:
    \r\nRING\r\n\r\n+CLIP:"0102030000"\r\n\

    Je voudrai pouvoir récuperer chaque réponse : RING et +CLIP:"0102030000" dans un (ou deux) buffer(s).

    J'ai essayé pas mal de choses, mais je n'y arrive vraiment pas.
    Pourriez vous m'aider svp ?

    Voici mon code, il recoit bien chaque byte mais la mise en forme n'est pas celle espérée et l'index de reception, qui compte les byte reçus, ne semble pas se remettre à zero au bon moment, je ne sais pas pourquoi.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    #define UART_BUFFER_SIZE	80  // chaque réponse reçue sera toujours < à 80 caractères
     
    static unsigned char c;
    static unsigned char UART1_RCX[UART_BUFFER_SIZE];
    unsigned char uart_buffer[UART_BUFFER_SIZE];
    BYTE i;
    ...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    //	Début de boucle d'interruption dès reception d'un byte sur le port série
    	if(PIR1bits.RC1IF)	
    		{
    		// --- On capture byte par byte --- ///
    		c = RCREG1;		// lecture du registre de reception -> met dans 'c' 
    		UART1_RCX[index_uart] = c;			// chaque byte recu constitue la chaine UART1_RCX
    		if (index_uart++ == UART_BUFFER_SIZE) index_uart=0;	// avance l'index et vérifie un éventuel dépassement
    		}
    		// --- Fin de la capture dans UART1_RCX --- ///
     
     
    		for(i=2;i<UART_BUFFER_SIZE;i++)		// on recopie la reception dans un nouveau buffer en décalant 2 rangs 	
    							// vers la gauche ( suppression du 1er couple de \r\n
    			uart_buffer[i-2] = UART1_RCX[i];			
     
    				if (uart_buffer[i-2]== '\r')	// on parcours la suite de la chaine, si on rencontre \r on termine la chaine
    		        {
    		        uart_buffer[i-2] = '\0';      		// on remplace \r par \0 pour obtenir le 1er buffer
    				index_uart=0;			// remise de l'index à 0 afin de démarrer une nouvelle chaine
    				}

  2. #2
    Membre éclairé
    Avatar de Elijha
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Avril 2003
    Messages
    314
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : Bâtiment Travaux Publics

    Informations forums :
    Inscription : Avril 2003
    Messages : 314
    Points : 742
    Points
    742
    Par défaut
    Bonsoir,

    Pourquoi ne pas "bypasser" les octets dont tu ne désires pas mettre dans ton buffer ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    unsigned char buffer[80] ;
    int index = 0 ;
     
    // Début de boucle d'interruption dès reception d'un byte sur le port série
    if(PIR1bits.RC1IF)    
    {
        // --- On capture byte par byte --- ///
        c = RCREG1 ;        // lecture du registre de reception -> met dans 'c' 
        if(c!='\r') {       // Tous les octets sauf '\r'
            buffer[index] = c ;
            // Traitement particulier pour le '\n'
            if(c=='\n') buffer[index] = 0 ;  // Remplace '\n' par '\0'
            // Nouvel octet en attente
            index ++ ;
        }
    }
    Pour mettre tes chaînes de caractères dans un tableau à plusieurs dimensions, cela ne doit pas être bien difficile (et je te laisse le faire )
    Attention, je n'ai pas testé le risque de dépassement de capacité du buffer.

  3. #3
    Membre confirmé Avatar de Flow_75
    Femme Profil pro
    Ingénieure
    Inscrit en
    Mai 2005
    Messages
    1 096
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 41
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieure
    Secteur : Transports

    Informations forums :
    Inscription : Mai 2005
    Messages : 1 096
    Points : 633
    Points
    633
    Par défaut
    Salut

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    #define UART_BUFFER_SIZE	80  // chaque réponse reçue sera toujours < à 80 caractères
     
    static unsigned char c;
    static unsigned char UART1_RCX[UART_BUFFER_SIZE];
    unsigned char uart_buffer[UART_BUFFER_SIZE];
    BYTE i;
    ...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    //	Début de boucle d'interruption dès reception d'un byte sur le port série
    	if(PIR1bits.RC1IF)	
    		{
    		// --- On capture byte par byte --- ///
    		c = RCREG1;		// lecture du registre de reception -> met dans 'c' 
    		UART1_RCX[index_uart++] = c;			// chaque byte recu constitue la chaine UART1_RCX incrémentes ici, tu es sur d'avoir le bon nombre d'octets recus.
    		if (index_uart == UART_BUFFER_SIZE) index_uart=0;	// avance l'index et vérifie un éventuel dépassement
    		}
    		// --- Fin de la capture dans UART1_RCX --- ///
    
    ici, tu vérifies que ton buffer commence par \r\n au début du buffer.
    
    Si tu as trouvé \r\n, alors tu recuperes les octets tant que tu ne recois pas un \r, si tu en recois un, alors :
    1 - tu regardes si tu as un \n après (alors fin de buffer, tu le traites)
    2 - Si c'est un caractère comme un autre, alors dans ce cas, tu mets ton \r et celui que tu as recu dans le buffer pour attendre le caractère suivant 

  4. #4
    Membre du Club
    Inscrit en
    Septembre 2008
    Messages
    384
    Détails du profil
    Informations forums :
    Inscription : Septembre 2008
    Messages : 384
    Points : 52
    Points
    52
    Par défaut
    Merci à vous,

    En suivant le code de Elijha, si je ne me trompe pas, l'index n'est jamais remis à 0.

    De ce fait, ça pose probleme pour capturer 2 réponses successives.
    Aussi, comme chaque réponse commence par /r/n le buffer va être immédiatement débuter et terminer par buffer[0] = '\0'

    Pour y remedier, tout en suivant l'idée de Elijha, ne faut il pas, lors du test de c='n' s'assurer que l'index est différent de 0 ?

    L'idée serait celle ci :

    On recoit c
    c = '\r' ?
    oui : on ne fait rien, l'index reste identique et on a attend la reception c suivante
    non : on copie c dans le buffer ayant comme position l'index actuel

    on teste le contenu de c
    c = '\n' ?
    oui : on verifie si index = 0
    --> oui : on ne fait rien, l'index reste identique et on a attend la reception c suivante
    --> non : on termine la chaine en remplacant c = `\0 ' et on remet index = 0

    non : on avance index++ pour la prochaine reception


    Que pensez vous de ce code svp ? :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    if(PIR1bits.RC1IF)    
    {
        // --- On capture byte par byte --- ///
        c = RCREG1 ;        // lecture du registre de reception -> met dans 'c' 
        if(c!='\r') 
        {       // Tous les octets sauf '\r'
            buffer[index] = c ;
            // Traitement particulier pour le '\n'
            if(c=='\n') 
            {
                  if(index!==0) 
                        {
                         buffer[index] = '\0' ;  // Remplace '\n' par '\0'
                         index = 0;               // Remise à 0 de l'index
                        }
            }
     
        }
     
             if(c!=='\n') index ++ ;           // Nouvel octet en attente
             if (index_uart == UART_BUFFER_SIZE) index_uart=0;
    }

  5. #5
    Membre éclairé
    Avatar de Elijha
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Avril 2003
    Messages
    314
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : Bâtiment Travaux Publics

    Informations forums :
    Inscription : Avril 2003
    Messages : 314
    Points : 742
    Points
    742
    Par défaut
    Bonsoir,
    Citation Envoyé par lcoulon Voir le message
    En suivant le code de Elijha, si je ne me trompe pas, l'index n'est jamais remis à 0.
    Effectivement, je n'ai pas fait attention que la réponse du périphérique commençait par "\r\n". L'idée était là tous de même
    Le but étant de ne pas tenir compte des octets "inutiles", autant ne pas les enregistrer.

    En espérant que cette solution te convienne.

  6. #6
    Membre du Club
    Inscrit en
    Septembre 2008
    Messages
    384
    Détails du profil
    Informations forums :
    Inscription : Septembre 2008
    Messages : 384
    Points : 52
    Points
    52
    Par défaut
    Désolé mais non ça n'ira pas ...

    Il faut absolument que je parvienne à supprimer le couple de \r\n du début de la réponse et le double couple de \r\n qui termine la réponse et qui de nouveau débute une nouvelle .

    Je n'y arrive définitivement pas.
    Si quelqu'un peut m'aider, ça serait sympa.

  7. #7
    Membre éclairé
    Avatar de Elijha
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Avril 2003
    Messages
    314
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : Bâtiment Travaux Publics

    Informations forums :
    Inscription : Avril 2003
    Messages : 314
    Points : 742
    Points
    742
    Par défaut
    Bonsoir,

    Un autre moyen, c'est d'utiliser des tableaux de chaines de caractères. Une petite simulation de la réception série du micro-contrôleur
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    int main(int argc, char *argv[])
    {   char *UART1_RCXSerial = "\r\nRING\r\n\r\n+CLIP:\"0102030000\"\r\n" ;
        char *RCREG1 = UART1_RCXSerial ;
     
        int i ;
        char c = 0 ;
        char UART1_RCX[10][80] = {{0}} ;
        int indBuff = 0 ;
        int cptChar = 0 ;
     
        while(*RCREG1) {
            c = *RCREG1++ ;
            // Autres caractères que '\n' et '\r'
            if(c!='\r' && c!='\n') {
                UART1_RCX[indBuff][cptChar++] = c ;
                // Saturation du compteur d'octets
                if(cptChar>79) cptChar = 79 ;
            }
            // Si '\n' et qu'il y a des caractères enregistrés
            // on incrémente l'index du buffer
            else if(cptChar && c=='\n') {
                UART1_RCX[indBuff++][cptChar] = 0 ;
                if(indBuff>9) indBuff = 0 ;     // Tableau tournant
                cptChar = 0 ;
            }
        }
     
        // Affiche tous les buffers non vide
        for(i=0; i<10 && UART1_RCX[i][0]; i++)
            printf("UART1_RCX[%d] = \"%s\"\n", i, UART1_RCX[i]) ;
     
        return 0 ;
    }

Discussions similaires

  1. Réponses: 9
    Dernier message: 23/12/2013, 16h40
  2. Crypter une chaine de caractères
    Par Yabo dans le forum Réseau
    Réponses: 18
    Dernier message: 19/11/2004, 23h04
  3. Réponses: 9
    Dernier message: 17/01/2003, 11h45
  4. Lire Une Chaine De Caractères
    Par Jonathan_Korvitch dans le forum C
    Réponses: 12
    Dernier message: 07/01/2003, 05h37
  5. Réponses: 2
    Dernier message: 06/12/2002, 07h50

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo