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

Embarqué Discussion :

L´envoi du contenu d´un fichier texte vers le port serie RS232


Sujet :

Embarqué

  1. #81
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2012
    Messages
    110
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Allemagne

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : Mars 2012
    Messages : 110
    Points : 27
    Points
    27
    Par défaut
    Okay, j´ai saisis.

    J´ai des soucis sur les lignes 132, 135 et 138 de la fonction ISR(USART0_RX_vect).

    ligne 132 : for (i = 0; i < usart_command_size; ++i)

    Proposition: for (i = 0; i < usart_command_max_size; ++i)
    ligne 135 : if (i <= 0 || i >= usart_command_size - 1)

    Proposition: if (i <= 0 || i >= usart_command_max_size - 1)
    ligne 138: USART_Send("\x15"); /* NAK */
    ligne 139: usart_command_size = 0;

    Proposition: USART0_Send("\x15"); /* NAK */

  2. #82
    Membre expérimenté
    Inscrit en
    Août 2010
    Messages
    726
    Détails du profil
    Informations forums :
    Inscription : Août 2010
    Messages : 726
    Points : 1 645
    Points
    1 645
    Par défaut
    ligne 132 : for (i = 0; i < usart_command_size; ++i)

    Proposition: for (i = 0; i < usart_command_max_size; ++i)
    Non, c'est bien usart_command_size :
    - usart_command_size est la taille de la commande reçue
    - usart_command_max_size est la taille (- 1) du buffer contenant la commande reçue
    On lit la commande qu'on a reçue du PC. Sa taille est variable et on la connaît grâce à usart_command_size.

    ligne 135 : if (i <= 0 || i >= usart_command_size - 1)

    Proposition: if (i <= 0 || i >= usart_command_max_size - 1)
    Même chose.

    ligne 138: USART_Send("\x15"); /* NAK */
    ligne 139: usart_command_size = 0;

    Proposition: USART0_Send("\x15"); /* NAK */
    Non, quand une commande est traitée (\r), qu'elle soit valide ou pas, on vide le buffer de commande.
    C'est un peu redondant avec \n mais c'est pas grave.

  3. #83
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2012
    Messages
    110
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Allemagne

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : Mars 2012
    Messages : 110
    Points : 27
    Points
    27
    Par défaut
    Salut,

    lorsque je deboggue le programme du pc et celui du µC, j´obtiens le resultat suivant dans ma console:

    Envoi de:
    5359,6121
    ERREUR
    Envoi de:
    2756,4216
    ERREUR
    Envoi de:
    3518,4851
    ERREUR
    L´envoi echoue malgre les mofications que tu m´as suggeres au niveau du microcontrôleur.!!

  4. #84
    Membre expérimenté
    Inscrit en
    Août 2010
    Messages
    726
    Détails du profil
    Informations forums :
    Inscription : Août 2010
    Messages : 726
    Points : 1 645
    Points
    1 645
    Par défaut
    Tu peux commencer par rajouter des messages d'erreur détaillés dans la fonction EnvoieCommande, pour savoir si c'est le ReadFile qui a fait un time out (c'est le plus probable).

  5. #85
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2012
    Messages
    110
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Allemagne

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : Mars 2012
    Messages : 110
    Points : 27
    Points
    27
    Par défaut
    Bonsoir Hibernatus34,

    PC: J´ai deboggue le programme c++ du PC et helas la fonction EnvoieCommande ne fonctionne pas bien. J´ai filme les erreurs du programme c++ lors du debogge. la photographie de trouve en piece jointe.

    Microcontrôleur: J´ai lus avec attention le programme du microcontrôleur et j´aimerais te communiquer la maniere dont j´ai compris le transfert des positions.

    1er alternative: - Les positions sont transferees de la fonction ISR(USART0_RX_vect) vers la fonction USART1_Send(), car RXEN0 = 1 et RXCIE0 = 1.

    - La fonction USART1_Send transmet quant-a elle les positions dans la fonction USART1_QueueIn().

    - la fonction USART1_QueueIn() transmet a son tour les positions dans la fonction USART1_QueueOut()
    - Puis a travers l´activation de l´interruption UDRIE1, la fonction d´interruption ISR(USART1_UDRE_vect) se chargera de transmettre les positions aux moteurs de commande, car ISR(USART1_UDRE_vect) contient le contenu de la file USART1_QueueOut().

    2ieme Alternative: concernant le renvoie des reponses ACK ou NAK au pc, le procede d´envoie est selon moi semblable a la 1er alternative. Sauf qu´elle s´effectuera a travers l´USART0.

    C´est a dire: ISR(USART0_RX_vect), puis USART0_Send, puis USART0_QueueIn(), puis USART0_QueueOut et enfin ISR(USART0_UDRE_vect) se chargera de l´envoie a travers USART0.

    Cependant, j´ai compris les codes des fonctions que tu as programmes. Mais une fonction specialement me donne des maux de tête. J´ai bosse la dessus avec l´aide d´un ami. Mais on n´a pas vraiment compris en integralite le fonctionement de la fonction ISR(USART0_RX_vect).

    Peux-tu stp jetter encore un coup d´oeil sur la fonction ISR(USART0_RX_vect).

    1er question (Ligne 143 et 144): les variables usart_command[i] = 0; et usart_command[usart_command_size] = 0; seront tjs egal a zero d´apres ton code. Du coup je me dis que x possedera toujours la valeur zero en int. Qu´en penses-tu ?

    2ieme question (Ligne 130 a 140) : Je ne comprends pas ton raisonnement a ce niveau. je comprends ce que tu veux faire, mais je trouve qu´il manque quelque chose.

    3ieme question: Le buffer de l´USART0 recoit-il d´abord /r, puisY, puis X et /n ou /n, puis X, puis Y et /r. Car d´apres le programme c++, les commandes du fichier texte sont envoyees a l´USART0 comme suit: /n, puis X, puis Y et /r. Qui sait, peut-être je me trompe.

    En bref, je t´avoue que les codes de la fonction ISR(USART0_RX_vect) m´ont secoues. S´il te plaît, jette y un coup d´oeil. Je comprends ce que tu essaies de faire dans la fonction, mais pas en integralite.

    Merci pour ton aide.
    Images attachées Images attachées  

  6. #86
    Membre expérimenté
    Inscrit en
    Août 2010
    Messages
    726
    Détails du profil
    Informations forums :
    Inscription : Août 2010
    Messages : 726
    Points : 1 645
    Points
    1 645
    Par défaut
    Je comprends pas l'utilité de ta capture d'écran.
    Je n'ai pas non plus compris le début de ton message.
    Pour le reste, voici une explication de mon code :

    Principe :
    1. Les caractères reçus par l'usart0 sont stockés dans command_buffer
    2. Quand une commande est terminée (réception de "\r") une commande pour les moteurs est stockée dans usart1_tx_buffer, et ACK/NAK est stocké dans usart0_tx_buffer
    3. Tant que usart1_tx_buffer contient des données, l'interruption sur UDRE1 est active
    4. Dans l'ISR de UDRE1, on envoie 1 caractère de usart1_tx_buffer
    5. Même chose pour usart0_tx_buffer et UDRE0


    usart1_tx_buffer est une file d'attente.
    L'ISR sur UDRE1 est appelée de manière répétée, tant que :
    - UDR0 est dispo
    - UDRIE0 est vrai

    Donc cette ISR est une espèce de service permanent qui s'occupe de vider la file d'attente dès qu'il y a des données dedans. Je l'active dès que j'entre une donnée dans la file et je la désactive dès que j'ai sorti le dernier caractère de la file.

    1er question (Ligne 143 et 144): les variables usart_command[i] = 0; et usart_command[usart_command_size] = 0; seront tjs egal a zero d´apres ton code. Du coup je me dis que x possedera toujours la valeur zero en int. Qu´en penses-tu ?
    Ici je transforme un tableau de caractère en 2 chaînes avec terminateur nul.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
         v--------------------je ne sais pas ce qu'il y a à la fin de mon buffer
    42,51éàç_-'_è"éàç(
      ^--^-------------écriture de'\0' ici et là
    
    42¤51¤àç_-'_è"éàç(
     ^--^------------- 2 chaînes C compatibles avec atoi (¤ symbolise '\0')
    2ieme question (Ligne 130 a 140) : Je ne comprends pas ton raisonnement a ce niveau. je comprends ce que tu veux faire, mais je trouve qu´il manque quelque chose.
    Je viens de recevoir "\r" qui est la fin d'une commande.
    Donc je traite la commande présente dans command_buffer :
    1. Lecture du X et du Y (convertis en int)
    2. Traitement des X et des Y (pour l'instant aucun traitement)
    3. Génération des 2 commandes pour les moteurs, ajoutées à la file usart1_tx_buffer

    A la fin de cette ISR, la file usart1_tx_buffer contient les commandes pour les moteurs et l'ISR sur UDRE1 est active, donc la file va être "automatiquement" transférée via l'USART1.

    3ieme question: Le buffer de l´USART0 recoit-il d´abord /r, puisY, puis X et /n ou /n, puis X, puis Y et /r. Car d´apres le programme c++, les commandes du fichier texte sont envoyees a l´USART0 comme suit: /n, puis X, puis Y et /r. Qui sait, peut-être je me trompe.
    \r est la fin d'une commande.
    \n est envoyé au début d'une commande pour vider le buffer et être sûr de ne pas avoir des restes d'un envoi raté au début.
    Donc : \n, puis (X,Y), puis \r.

  7. #87
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2012
    Messages
    110
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Allemagne

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : Mars 2012
    Messages : 110
    Points : 27
    Points
    27
    Par défaut
    Bonjour,

    Tu peux commencer par rajouter des messages d'erreur détaillés dans la fonction EnvoieCommande, pour savoir si c'est le ReadFile qui a fait un time out (c'est le plus probable).
    Comment dois-je m´y prendre ?

    J´ai a nouveau deboggue le programme c++ du pc, mais l´envoie n´est toujours pas operationel. Je resois comme reponse : "Erreur"

    J´ai essaye d´observer les valeurs des variables et tout semble normal. Du moins je ne sais pas comment remedier au probleme de la fonction EnvoieCommande.

    Merci pour les explications de la fonction ISR(USART0_RX_vect).

  8. #88
    Membre expérimenté
    Inscrit en
    Août 2010
    Messages
    726
    Détails du profil
    Informations forums :
    Inscription : Août 2010
    Messages : 726
    Points : 1 645
    Points
    1 645
    Par défaut
    Je commence à fatiguer...
    La fonction EnvoieCommande signale une erreur, ça ne veut pas dire que c'est elle qui a un bug.
    Il y de grandes chances pour qu'il y ait des bugs dans le code du µC. Je peux aussi m'être planté sur le reste du code PC.
    Je te demande de regarder pourquoi la fonction renvoie faux, car il y a 3 cas possibles (erreur sur WriteFile, erreur sur ReadFile, réception d'autre chose que ACK).

  9. #89
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2012
    Messages
    110
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Allemagne

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : Mars 2012
    Messages : 110
    Points : 27
    Points
    27
    Par défaut
    salut,

    stp ne fatigue pas. Je vais faire des efforts considerables pour eviter de te contrarier.
    Je vais immediatement suivre tes consignes.

    Merci et bonne journee.

  10. #90
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2012
    Messages
    110
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Allemagne

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : Mars 2012
    Messages : 110
    Points : 27
    Points
    27
    Par défaut
    Bonsoir Hibernatus34,

    j´etais certes muet ces derniers jours, mais j´essayais de travailler de maniere autonome afin de deceler les problemes du programme c et c++.

    J´ai insere les messages d´erreurs sur les instructions WriteFile et ReadFile comme suit:
    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
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    static bool EnvoieCommande(HANDLE h, const char *s)
    {
    	DWORD	dummy;
    	char	c;
        char *fmsg  = NULL;
        int  error = 0;
    
    	// S'il y avait des réponses à lire depuis la dernière commande,
    	// trop tard, on les supprime.
    	PurgeComm(h, PURGE_RXCLEAR);
    	for (int i = 0; s[i] != 0; ++i)
    		if (!WriteFile(h, s + i, 1, &dummy, 0))
    		 return false;
    		error = GetLastError();
      FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
                    FORMAT_MESSAGE_FROM_SYSTEM |
                    FORMAT_MESSAGE_IGNORE_INSERTS,
                    NULL,
                    error,
                    MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
                    (LPTSTR) &fmsg,
                    0, NULL );
    
                    cout << "Error: " << GetLastError() << endl << fmsg << endl;
    
    	    if (!ReadFile(h, &c, 1, &dummy, 0))
              return false;	// Time-out
    
    	    error = GetLastError();
      FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
                    FORMAT_MESSAGE_FROM_SYSTEM |
                    FORMAT_MESSAGE_IGNORE_INSERTS,
                    NULL,
                    error,
                    MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
                    (LPTSTR) &fmsg,
                    0, NULL );
    
                    cout << "Error: " << GetLastError() << endl << fmsg << endl;
              return c == '\x06';	// ACK
    
    }
    Apres le deboggage du programme c++, j´ai obtenu comme information sur l´envoi et reception le message suivant:

    Envoie de :
    5359,6121
    Error: 0
    Le processus a ete acheve avec succes

    Error: 0
    Le processus a ete acheve avec succes

    ERREUR
    Envoie de :
    2756,4216
    Error: 0
    Le processus a ete acheve avec succes

    Error: 0
    Le processus a ete acheve avec succes

    ERREUR
    ........
    ........
    A mon avis, le probleme se trouve au niveau du µC, car l´inseration des messages d´erreur nous informe que WriteFile et ReadFile execute leur boulot avec succes. Donc le bug est sûrement cause par le µC.

    La fonction EnvoieCommande signale une erreur, ça ne veut pas dire que c'est elle qui a un bug.
    Je te demande de regarder pourquoi la fonction renvoie faux, car il y a 3 cas possibles (erreur sur WriteFile, erreur sur ReadFile, réception d'autre chose que ACK).
    C´est exactement comme tu soupconnais, le pc recoit apparement autre chose que ACK !! Je suppose qu´on s´est plante quelque part dans la programmation du µC. Qu´en penses-tu Hibernatus34 ?

    Bonne soiree.

  11. #91
    Membre expérimenté
    Inscrit en
    Août 2010
    Messages
    726
    Détails du profil
    Informations forums :
    Inscription : Août 2010
    Messages : 726
    Points : 1 645
    Points
    1 645
    Par défaut
    Salut,

    Je pensais plus à quelque chose comme :
    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
    static bool EnvoieCommande(HANDLE h, const char *s)
    {
    	DWORD	dummy;
    	char	c;
    
    	// S'il y avait des réponses à lire depuis la dernière commande,
    	// trop tard, on les supprime.
    	PurgeComm(h, PURGE_RXCLEAR);
    	for (int i = 0; s[i] != 0; ++i)
    		if (!WriteFile(h, s + i, 1, &dummy, 0))
    		{
    			cout << "!WriteFile" << endl;
    			return false;
    		}
    	if (!ReadFile(h, &c, 1, &dummy, 0))
    	{
    		cout << "!ReadFile" << endl;
    		return false;
    	}
    	if (c != '\x06')
    		cout << "Pas ACK : " << (int)c << endl;
    	return c == '\x06';	// ACK
    }
    Si ça affiche "Pas ACK : 21" ça veut dire qu'on a reçu un NAK.

    Soit dit en passant, je pense que ça sert à rien d'envoyer la chaîne caractère par caractère. J'ai laissé ça parce que tu m'avais dit que c'était nécessaire et que j'ai pas l'habitude de cette API, mais dès que tu auras quelque chose de fonctionnel il faudra essayer avec l'envoi de chaînes dans WriteFile.

    Sinon j'ai pas trop le temps de regarder en ce moment, j'essaierai avant la fin de la semaine.

  12. #92
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2012
    Messages
    110
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Allemagne

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : Mars 2012
    Messages : 110
    Points : 27
    Points
    27
    Par défaut
    Bonjour Hibernatus34,

    J´ai deboggue le programme c++ en me servant de la version modifiee de la fonction EnvoieCommande() que tu m´as suggeres et j´ai obtenu le resultat suivant:

    Envoi de :
    5359,6221
    Pas ACK : 0
    ERREUR
    Envoi de :
    2756,4216
    Pas ACK : 0
    ERREUR
    .........
    .........
    La console affiche "Pas ACK : 0" et non "Pas ACK : 21". Cela signifie que le PC ne recoit pas de NAK. Mais L´envoi echoue a nouveau, car la console affiche "ERREUR". Qu´en dis-tu ?
    Je crois que le microcontrôleur bug !!

    Soit dit en passant, je pense que ça sert à rien d'envoyer la chaîne caractère par caractère. J'ai laissé ça parce que tu m'avais dit que c'était nécessaire et que j'ai pas l'habitude de cette API, mais dès que tu auras quelque chose de fonctionnel il faudra essayer avec l'envoi de chaînes dans WriteFile.
    Comme tu l´as dit, je vais d´abord essayer d´avoir quelques choses de fonctionnel ensuite je mettrais ta proposition en application.

  13. #93
    Membre expérimenté
    Inscrit en
    Août 2010
    Messages
    726
    Détails du profil
    Informations forums :
    Inscription : Août 2010
    Messages : 726
    Points : 1 645
    Points
    1 645
    Par défaut
    Ah, j'ai zappé une chose importante. Je crois que ReadFile renvoie TRUE en cas de time-out.
    Essaie avec ce code plutôt :
    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
    static bool EnvoieCommande(HANDLE h, const char *s)
    {
    	DWORD	length;
    	char	c;
    
    	// S'il y avait des réponses à lire depuis la dernière commande,
    	// trop tard, on les supprime.
    	PurgeComm(h, PURGE_RXCLEAR);
    	for (int i = 0; s[i] != 0; ++i)
    		if (!WriteFile(h, s + i, 1, &length, 0) || length != 1)
    		{
    			cout << "!WriteFile" << endl;
    			return false;
    		}
    	if (!ReadFile(h, &c, 1, &length, 0) || length != 1)
    	{
    		cout << "!ReadFile" << endl;
    		return false;
    	}
    	if (c != '\x06')
    		cout << "Pas ACK : " << (int)c << endl;
    	return c == '\x06';	// ACK
    }

  14. #94
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2012
    Messages
    110
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Allemagne

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : Mars 2012
    Messages : 110
    Points : 27
    Points
    27
    Par défaut
    J´ai a nouveau deboggue le programme c++ avec la nouvelle version de la fonction EnvoieCommande() et la console affiche ceci:

    Envoie de :
    5359,6121
    !ReadFile
    ERREUR
    Envoie de :
    2756,4216
    !ReadFile
    ERREUR
    ........

  15. #95
    Membre expérimenté
    Inscrit en
    Août 2010
    Messages
    726
    Détails du profil
    Informations forums :
    Inscription : Août 2010
    Messages : 726
    Points : 1 645
    Points
    1 645
    Par défaut
    Voilà, maintenant tu sais que le µC n'a rien répondu.
    C'est le pire cas, puisque le bug peut être n'importe où, mais c'était aussi le plus probable.

  16. #96
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2012
    Messages
    110
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Allemagne

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : Mars 2012
    Messages : 110
    Points : 27
    Points
    27
    Par défaut
    C´est clair que le µC n´a pas repondu !!! Je m´en doutais aussi. J´ai revu le programme du µC et je pense que le probleme vient de la fonction d´interruption ISR(USART0_RX_vect). Mais j´ai pas assez d´arguments pour le prouver. sinon les autres fonctions sont ok.

  17. #97
    Membre expérimenté
    Inscrit en
    Août 2010
    Messages
    726
    Détails du profil
    Informations forums :
    Inscription : Août 2010
    Messages : 726
    Points : 1 645
    Points
    1 645
    Par défaut
    Si tu soupçonnes cette fonction, tu peux la simplifier pour ne tester que les autres : quand tu reçois '\r' retourne directement "\x06".
    Après ça, si tu ne reçois pas ACK côté PC après avoir envoyé un '\r' seul, c'est que le problème est ailleurs. Pourquoi tu ne fais pas ce genre de test de toi-même ? Remue-toi un peu ! (je dis pas ça méchamment, ne le prends pas mal surtout)

  18. #98
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2012
    Messages
    110
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Allemagne

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : Mars 2012
    Messages : 110
    Points : 27
    Points
    27
    Par défaut
    Bonjour,

    J´ai pas mal pris ta remarque et je pense que t´a tout de même raison. Je vais me remuer.

    j´ai modifie et teste la fonction ISR(USART0_RX_vect) comme ceci:

    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
    ISR(USART0_RX_vect)
    {
      char data;
      data = UDR0;
    
      if (data == '\n')
      {
        /* Démarrage d'une nouvelle commande */
        usart_command_size = 0;
        return;
      }
      /* Quand on ne reçoit ni \r ni \n, on enregistre le caractère dans la commande */
      if (usart_command_size < usart_command_max_size)
      {
        usart_command[usart_command_size] = data;
        ++usart_command_size;
      }
    
      if (data == '\r')
      {
        USART0_Send("\x06");  /* ACK */
        return;
      }
    }
    Helas la console du pc m´affiche ceci a nouveau :
    Envoie de :
    5359,6121
    !ReadFile
    ERREUR
    Envoie de :
    2756,4216
    !ReadFile
    ERREUR
    ........
    Bref le pc ne recoit pas le message "ACK".
    Comme tu l´as suppose, le probleme vient d´ailleurs. Je vais examiner la fonction USART0_Send().

  19. #99
    Membre expérimenté
    Inscrit en
    Août 2010
    Messages
    726
    Détails du profil
    Informations forums :
    Inscription : Août 2010
    Messages : 726
    Points : 1 645
    Points
    1 645
    Par défaut
    Attention à l'ordre des conditions, mon code était de la forme :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    if (...)
    {
        ...
        return;
    }
    // Le code ci-dessous ne s'exécute que si la 1ère condition était fausse
    if (...)
    {
        ...
        return;
    }
    // Le code ci-dessous ne s'exécute que si les 2 conditions étaient fausses
    ...
    C'était équivalent à :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    if (...)
    {
        ...
    }
    else if (...)
    {
        ...
    }
    else
    {
        ...
    }
    Sinon, tu vois bien que le problème est ailleurs.
    Essaie d'augmenter les time-out dans un premier temps (mets 1000 le temps des tests, on s'en fiche pour le moment).

    J'ai beaucoup de mal à voir les bugs à travers tes tests. Déjà quand on avait testé un simple écho ça a pris beaucoup de temps pour finalement se rendre compte que le code était plutôt correct dans le principe.

    Le programme minimal à faire fonctionner avant de réactiver tout le reste, c'est :
    - Dans l'ISR USART0_RX, si UDR0 == '\r' alors activer l'interruption sur UDRE0
    - Dans l'ISR USART0_UDRE, faire UDR0 = '\x06' et désactiver l'interruption sur UDRE0
    Si ça ne te renvoie pas un ACK à la 1ère commande, je ne peux plus rien pour toi, car c'est la même chose que l'écho mais en plus simple.

    En gros ça devrait donner :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    ISR(USART0_RX_vect)
    {
      char data;
    
      data = UDR0;
      if (data == '\r')
        UCSR0B |= 1 << UDRIE0;
    }
    
    ISR(USART0_UDRE_vect)
    {
      UDR0 = '\x06';
      UCSR0B &= ~(1 << UDRIE0);
    }

  20. #100
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2012
    Messages
    110
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Allemagne

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : Mars 2012
    Messages : 110
    Points : 27
    Points
    27
    Par défaut
    Salut Hibernatus34,

    tu avais poste ceci dans le programme du microcontrô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
    /* Envoie une réponse sur l'USART0 via la file de transfert */
    static void USART0_Send(const char *s)
    {
      int i; 
      for (i = 0; s[i] != 0; ++i)
        USART0_QueueIn(s[i]);
      if (usart0_tx_buffer_size > 0)
        UCSR0B |= 1 << UDRIE0;
    }
    
    /* Ajout dans une file */
    void USART0_QueueIn(char c)
    {
      int i;
      if (usart0_tx_buffer_size < usart_buffer_max_size)
      {
        i = (usart0_tx_buffer_size + usart0_tx_buffer_start) % usart_buffer_max_size;
        usart0_tx_buffer[i] = data;
        ++usart0_tx_buffer_size;
      }
    }
    La varaible "data" n´a pas ete declare et ne possede aucune donnee dans la fonction USART0_QueueIn(). Donc l´USART0 ne transmettra ni "ACK" ou "NAK" au pc.

    Je propose ceci:
    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
    /* Envoie une réponse sur l'USART0 via la file de transfert */
    static void USART0_Send(const char *s)
    {
      int i; 
      for (i = 0; s[i] != 0; ++i)
        USART0_QueueIn(s[i]);
      if (usart0_tx_buffer_size > 0)
        UCSR0B |= 1 << UDRIE0;
    }
    
    /* Ajout dans une file */
    void USART0_QueueIn(char c)
    {
      int i;
      if (usart0_tx_buffer_size < usart_buffer_max_size)
      {
        i = (usart0_tx_buffer_size + usart0_tx_buffer_start) % usart_buffer_max_size;
        usart0_tx_buffer[i] = c;
        ++usart0_tx_buffer_size;
      }
    }
    J´ai effectue a nouveau les tests en tenant compte de ta proposision. Helas j´ai a nouveau obtenu ceci:
    Envoie de :
    5359,6121
    !ReadFile
    ERREUR
    J´ai essaye de modifier ta proposition de la maniere suivante:
    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
    ISR(USART0_RX_vect)
    {
      char data;
    
      data = UDR0;
    //  if (data == '\r')
      //  UCSR0B |= 1 << UDRIE0;
    }
    
    ISR(USART0_UDRE_vect)
    {
      
      UDR0 = '\x06';
     // UCSR0B &= ~(1 << UDRIE0);
    }
    Le deboggage donne le resultat suivant:
    Envoie de :
    5359,6121
    OK
    Envoie de :
    2756,4216
    OK
    ............
    je vais effectuer a nouveau des tests.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 1
    Dernier message: 30/04/2010, 21h24
  2. Réponses: 3
    Dernier message: 26/10/2009, 13h32
  3. Lecture d´un fichier texte .
    Par pilouface dans le forum C
    Réponses: 5
    Dernier message: 20/01/2006, 23h48
  4. importation d'un fichier texte vers excel
    Par darkpocket dans le forum Macros et VBA Excel
    Réponses: 3
    Dernier message: 07/01/2005, 11h47

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