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

Time-Out pour liaison UART
Jérémy
Administrateur du site
Administrateur du site
Messages : 2722
Âge : 44
Enregistré en : juillet 2015
Localisation : Dans le sud
Contact :

#1 Message par Jérémy » dim. 5 janv. 2020 16:55 lien vers la Data-Sheet : Cliquez ici

Bonjour à tous,

J'ai déjà évoqué le sujet il y a un moment et je souhaite revenir dessus.

Je fais une com UART avec une autre carte. Un petit dialogue plutôt simple. J'utilise une machine d'état pour traiter la reception d'info plutôt que d'utiliser un buffer!
Cependant j'aimerais être certain qui si un loupé se produisait l'UART ne se bloquerai pas; pour ce faire j'avais imaginé un truc dans ce genre.

- reception du start d'une trame sur l'UART
- lancement du Timer prévu pour un time-out de 40ms ( large)
- si le message est bien reçu j’arrête le Timer et je le réinitialise pour un autre lancement plus tard
- Si une erreur est survenue de je ne sais où , au bout de 40ms l'INT du Timer, réinitialise la valeur de l'UART, réinitialise son compteur et se stoppe elle même .

Pensez vous que c'est jouable peut être qu'il y a mieux comme façon de faire, ou peut être que sa fonctionne pas du tout ?
Est ce gênant qu'une INT s'auto arrête ?

Code : Tout sélectionner

void interrupt(){
 
//-----------------------          UART 1        -----------------------------
  
if((RC1IF_bit==1) && (RC1IE_bit==1)) {

     
Reception_UART1 UART1_Read();                                            // On récupere la donnée

     
switch (Valeur){
        case 
0:     if (Reception_UART1 == 2){     // reception du Start signal
                       
Valeur 1;
                       
TMR1ON_bit 1;            // Je lance le time-Out
                     
}
                     else
                       
Valeur 0;
                    break;

                    
// Command : ordre=0x00 ; parametre=0x01
        
case 1:     if (Reception_UART1 == 0){
                       
Valeur 2;
                     }
                    else {
                       
Valeur 0;
                     }
                    break;
                   
                   
// Nombre de DATA
       
case 2:     if (Reception_UART1 == 1){
                       
Valeur 3;
                    }
                   else{
                       
Valeur 0;
                    }
                    break;

                   
//DATA
        
case 3:    Ordre Reception_UART1;
                   XOR = 
3^Reception_UART1;
                   
Valeur 4;
                   break;

                   
// Calcul du Checksum
       
case 4:     if (XOR == Reception_UART1){
                       
F_Ordre_OK 1;
                    }
                    
TMR1ON_bit 0;     // J'eteins le time-Out
                    
TMR1H      0x63;  // Je réinitilise
                    
TMR1L      0xC0;
                    
Valeur     0;
                    break;
                   
       default:    
Valeur 0;
      }
   }

  
// -----  TIMER1 : 40 ms pour time-Out sur la reception UART
  
if (TMR1IF_bit){
      
TMR1IF_bit 0;
      
TMR1ON_bit 0;     // J'eteins le time-Out
      
TMR1H     0x63;
      
TMR1L     0xC0;
      
Valeur     0;     // Je RAZ la valeur
   
}
   
}
 



Merci
C'est en faisant des erreurs, que l'on apprend le mieux !!!

Time-Out pour liaison UART
satinas
Expert
Expert
Messages : 1225
Enregistré en : novembre 2015

#2 Message par satinas » dim. 5 janv. 2020 19:50 lien vers la Data-Sheet : Cliquez ici

Bonsoir Jérémy,
pourquoi pas, mais dans les "case 1:" et "case 2:", si tu fais "Valeur = 0", le timer continue à tourner et il devrait pas.

Time-Out pour liaison UART
Jérémy
Administrateur du site
Administrateur du site
Messages : 2722
Âge : 44
Enregistré en : juillet 2015
Localisation : Dans le sud
Contact :

#3 Message par Jérémy » dim. 5 janv. 2020 20:29 lien vers la Data-Sheet : Cliquez ici

Effectivement !

Ceci dit ce n'est pas trop genant il s'arretera de lui meme 40 ms plus tard !.
Donc a chaque fois que je fais Valeur = 0 je devrais l’arrêter !

Du coup je ré-initilaise le timer au départ pour eviter de le faire a cahque fois . cela donne ceci :

Code : Tout sélectionner

void interrupt(){
 //-----------------------          UART 1        -----------------------------
  if((RC1IF_bit==1) && (RC1IE_bit==1)) {

     Reception_UART1 = UART1_Read();                                            // On récupere la donnée

     switch (Valeur){
        case 0:     if (Reception_UART1 == 2){  // reception du Start signal
                       Valeur = 1;
                       TMR1H      = 0x63;       // Je réinitialise
                       TMR1L      = 0xC0;
                       TMR1ON_bit = 1;          // Je lance le time-Out
                     }
                     else{
                        Valeur = 0;
                     }
                    break;

                    // Command : ordre=0x00 ; parametre=0x01
        case 1:     if (Reception_UART1 == 0){
                       Valeur = 2;
                     }
                    else {
                       TMR1ON_bit = 0;     // J'eteins le time-Out
                       Valeur = 0;
                     }
                    break;
                   
                   
// Nombre de DATA
       case 2:     if (Reception_UART1 == 1){
                       Valeur = 3;
                    }
                   else{
                       TMR1ON_bit = 0;     // J'eteins le time-Out
                       Valeur = 0;
                    }
                    break;

                   //DATA
        case 3:    Ordre = Reception_UART1;
                   XOR = 3^Reception_UART1;
                   Valeur = 4;
                   break;

                   // Calcul du Checksum
       case 4:     if (XOR == Reception_UART1){
                       F_Ordre_OK = 1;
                    }
                    TMR1ON_bit = 0;     // J'eteins le time-Out
                    Valeur     = 0;
                    break;
                   
       default
:    Valeur = 0;
      }
   }

  // -----  TIMER0 pour clignotement led syncro
  if (TMR0IF_bit){
      TMR0IF_bit = 0;
      CPT0_100ms++;
      if (CPT0_100ms >= 9){
          CPT0_100ms = 0;
          if (LED_R_ACTIVE) LED_R = ~LED_R;
          if (LED_G_ACTIVE) LED_G = ~LED_G;
       }
   }

  // -----  TIMER1 : 40 ms pour time-Out sur la reception UART
  if (TMR1IF_bit){
      TMR1IF_bit = 0;
      TMR1ON_bit = 0;     // J'eteins le time-Out
      TMR1H         = 0x63;
      TMR1L         = 0xC0;
      Valeur     = 0;     // Je RAZ la valeur
   }
   
}
C'est en faisant des erreurs, que l'on apprend le mieux !!!

Time-Out pour liaison UART
satinas
Expert
Expert
Messages : 1225
Enregistré en : novembre 2015

#4 Message par satinas » dim. 5 janv. 2020 21:46 lien vers la Data-Sheet : Cliquez ici

Code : Tout sélectionner

     ...
     case 0:     if (Reception_UART1 == 2){  // reception du Start signal
                       Valeur = 1;
                       TMR1H      = 0x63;       // Je réinitialise
                       TMR1L      = 0xC0;
                       TMR1IF_bit = 0;
                       TMR1ON_bit = 1;          // Je lance le time-Out
                     }
    ...

  // -----  TIMER1 : 40 ms pour time-Out sur la reception UART
  if (TMR1IF_bit && TMR1ON_bit) {    // car tu peux avoir  TMR1IF_bit à 1 et TMR1ON_bit à 0)
      TMR1ON_bit = 0;     // J'eteins le time-Out
      Valeur     = 0;     // Je RAZ la valeur
   }

Time-Out pour liaison UART
Jérémy
Administrateur du site
Administrateur du site
Messages : 2722
Âge : 44
Enregistré en : juillet 2015
Localisation : Dans le sud
Contact :

#5 Message par Jérémy » dim. 5 janv. 2020 23:09 lien vers la Data-Sheet : Cliquez ici

Ok , très bien vu ! j’exécute ton conseil tout de suite.

Par contre tu as enlevé TMR1IF_bit = 0; ? D'apres la DS( enb lien en haut du post) en page 112, il faut effacer le drapeau par soft !
TMR1IF: TMR1 Overflow Interrupt Flag bit
1 = TMR1 register overflowed (must be cleared by software)
0 = TMR1 register did not overflow


Une raison particulière ?
C'est en faisant des erreurs, que l'on apprend le mieux !!!

Time-Out pour liaison UART
satinas
Expert
Expert
Messages : 1225
Enregistré en : novembre 2015

#6 Message par satinas » dim. 5 janv. 2020 23:22 lien vers la Data-Sheet : Cliquez ici

il y a bien un TMR1IF_bit = 0; juste avant le TMR1ON_bit = 1;

Tu peux remettre TMR1IF_bit = 0; derrière le test "if (TMR1IF_bit && TMR1ON_bit) {"
Mais de toute façon si tu le laisses à 1, ça marchera quand même car comme TMR1ON_bit passe à 0 le "if" ne sera plus exécuté tant que TMR1ON_bit restera à 0.
C'est juste avant TMR1ON_bit = 1; qu'il faut faire TMR1IF_bit = 0; sinon s'il était à 1 le pic entre aussitôt dans l'interruption timer.

Time-Out pour liaison UART
Jérémy
Administrateur du site
Administrateur du site
Messages : 2722
Âge : 44
Enregistré en : juillet 2015
Localisation : Dans le sud
Contact :

#7 Message par Jérémy » dim. 5 janv. 2020 23:35 lien vers la Data-Sheet : Cliquez ici

Très belle explication !! Un grand merci car j'aurais appris encore plein de truc ce soir.
On voit tout de suite le coup d’œil de l'expert.

Merci !
C'est en faisant des erreurs, que l'on apprend le mieux !!!

Time-Out pour liaison UART
satinas
Expert
Expert
Messages : 1225
Enregistré en : novembre 2015

#8 Message par satinas » lun. 6 janv. 2020 09:29 lien vers la Data-Sheet : Cliquez ici

Bonjour, expert du dimanche car j'ai quand même mélangé TMR1ON et TMR1IE.
Je suppose que tu as mis TMR1IE à 1, donc si TMR1IF reste à 1, l'interruption timer se redéclenche en permanence, quel que soit l'état de TMR1ON. Le plus simple est de faire TMR1IF = 0 derrière chaque TMR1ON = 0, et le test redevient "if (TMR1IF_bit) {"

Si tu as mis TMR1IE à 0, pas bon car si n'y a plus aucune réception série, le test "if (TMR1IF_bit) {" ne sera plus atteind. Tu peux dans ce cas mettre le if dans la boucle du programme principal, qui a le droit de savoir si ça se passe mal.


Retourner vers « Langage C »

Qui est en ligne

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