Version initiale

Dependencies:   mbed

Fork of Le_Pont_V10116 by SAGNES Christophe

Committer:
CS
Date:
Thu Mar 29 15:41:22 2018 +0000
Revision:
2:a10c8133d71c
Parent:
0:8b3c6f593515
Publish of "Le_Pont_V11003" in the team folder

Who changed what in which revision?

UserRevisionLine numberNew contents of line
CS 0:8b3c6f593515 1 /*******************************************************************/
CS 0:8b3c6f593515 2 /* */
CS 0:8b3c6f593515 3 /* Port Série */
CS 0:8b3c6f593515 4 /* */
CS 0:8b3c6f593515 5 /* Gestion du port série par interruption */
CS 0:8b3c6f593515 6 /* */
CS 0:8b3c6f593515 7 /* */
CS 0:8b3c6f593515 8 /*******************************************************************/
CS 0:8b3c6f593515 9
CS 0:8b3c6f593515 10 #include "mbed.h"
CS 0:8b3c6f593515 11 #include "Port_Serie.h"
CS 0:8b3c6f593515 12 #include "Modbus.h"
CS 0:8b3c6f593515 13
CS 0:8b3c6f593515 14 Serial RS(p28 , p27) ;
CS 0:8b3c6f593515 15 Serial PC8(USBTX, USBRX) ;
CS 0:8b3c6f593515 16 Timer Chrono_Serie ;
CS 0:8b3c6f593515 17
CS 0:8b3c6f593515 18 volatile U8 Buffer_Emission_U8[TAILLE_BUFFER_EMISSION] ;
CS 0:8b3c6f593515 19 volatile U8 Pointeur_Emission_U8 ;
CS 0:8b3c6f593515 20 volatile U8 Nb_Caracteres_A_Emettre_U8 ;
CS 0:8b3c6f593515 21 volatile U8 Buffer_Reception_U8[TAILLE_BUFFER_RECEPTION] ;
CS 0:8b3c6f593515 22 volatile U8 Pointeur_Reception_U8 ;
CS 0:8b3c6f593515 23 volatile U8 Nb_Caracteres_Attendus ;
CS 0:8b3c6f593515 24 volatile U8 Numero_Ordre_En_Reception_U8 ;
CS 0:8b3c6f593515 25 volatile U8 Numero_Ordre_En_Emission_U8 ;
CS 0:8b3c6f593515 26 volatile U8 Index ;
CS 0:8b3c6f593515 27 volatile S32 Date_Dernier_Caractere_S32 ;
CS 0:8b3c6f593515 28 volatile S32 Temps_alloue_Reception_S32 ;
CS 0:8b3c6f593515 29 static S32 Temps_alloue_Caractere_S32 ;
CS 0:8b3c6f593515 30
CS 0:8b3c6f593515 31 /******* Réception sous interruption ***************************/
CS 0:8b3c6f593515 32 void iReception_Serie ()
CS 0:8b3c6f593515 33 {
CS 0:8b3c6f593515 34 U8 Car ;
CS 0:8b3c6f593515 35 // Si premier caractere recu, enclenche le chrono
CS 0:8b3c6f593515 36 if ( Pointeur_Reception_U8 == 0 )
CS 0:8b3c6f593515 37 {
CS 0:8b3c6f593515 38 //Chrono_Serie.start() ;
CS 0:8b3c6f593515 39 }
CS 0:8b3c6f593515 40 // Si il y a des caractères dans le buffer
CS 0:8b3c6f593515 41 while ( RS.readable() )
CS 0:8b3c6f593515 42 {// Réception d'un caractère
CS 0:8b3c6f593515 43 Car=RS.getc();
CS 0:8b3c6f593515 44 Buffer_Reception_U8 [ Pointeur_Reception_U8 ] = Car ;
CS 0:8b3c6f593515 45 //RS.putc(Car) ;
CS 0:8b3c6f593515 46 Pointeur_Reception_U8++ ;
CS 0:8b3c6f593515 47 }
CS 0:8b3c6f593515 48 if ( ( Pointeur_Reception_U8 > 0 )
CS 0:8b3c6f593515 49 &&( Ordres[Numero_Ordre_En_Reception_U8].Etat_U8 == ATTENTE ) )
CS 0:8b3c6f593515 50 {// Si au moins un caractère recu, la réception est en cours
CS 0:8b3c6f593515 51 Ordres[Numero_Ordre_En_Reception_U8].Etat_U8 = RECEPTION ;
CS 0:8b3c6f593515 52 }
CS 0:8b3c6f593515 53 //PC8.printf("\r\n Serie : Reception %s ", &Buffer_Reception_U8 [0]) ;
CS 0:8b3c6f593515 54
CS 0:8b3c6f593515 55 //Date_Dernier_Caractere_S32 = Chrono_Serie.read_us() ;
CS 0:8b3c6f593515 56 // Analyse de la trame
CS 0:8b3c6f593515 57 if ( ( Buffer_Reception_U8 [ 0 ] == SLAVE_ID )
CS 0:8b3c6f593515 58 || ( Buffer_Reception_U8 [ 0 ] == MB_ADDRESSE_BROADCAST ) )
CS 0:8b3c6f593515 59 {// Adresse de l'esclave, ou Adresse de broadcast
CS 0:8b3c6f593515 60 //PC8.printf("\r\n Serie : Adresse %i ", Buffer_Reception_U8 [0]) ;
CS 0:8b3c6f593515 61 if ( Pointeur_Reception_U8 >= 6 )
CS 0:8b3c6f593515 62 {
CS 0:8b3c6f593515 63 //PC8.printf("\r\n Serie : Func %i ", Buffer_Reception_U8 [1]) ;
CS 0:8b3c6f593515 64 if (( Buffer_Reception_U8 [ 1 ] == MB_FUNC_READ_HOLDING_REGISTER )
CS 0:8b3c6f593515 65 ||( Buffer_Reception_U8 [ 1 ] == MB_FUNC_READ_INPUT_REGISTER ))
CS 0:8b3c6f593515 66 {// Fonction 3 ou 4, Lecture de registres
CS 0:8b3c6f593515 67 Nb_Caracteres_Attendus = 8 ;
CS 0:8b3c6f593515 68 //PC8.printf("\r\n Serie : Func %i ", Buffer_Reception_U8 [1]) ;
CS 0:8b3c6f593515 69 }
CS 0:8b3c6f593515 70 else if ( Buffer_Reception_U8 [ 1 ] == MB_FUNC_WRITE_MULTIPLE_REGISTERS )
CS 0:8b3c6f593515 71 {// Fonction 16 (0x10), écriture de registres
CS 0:8b3c6f593515 72 Nb_Caracteres_Attendus = 9 + Buffer_Reception_U8 [ 5 ] * 2 ;
CS 0:8b3c6f593515 73 }
CS 0:8b3c6f593515 74 }
CS 0:8b3c6f593515 75
CS 0:8b3c6f593515 76 if ( Pointeur_Reception_U8 >= Nb_Caracteres_Attendus )
CS 0:8b3c6f593515 77 {
CS 0:8b3c6f593515 78 // On a recu une trame complète
CS 0:8b3c6f593515 79 //PC8.printf("\r\n Serie : trame %d complete %d / %d",Numero_Ordre_En_Reception_U8,Pointeur_Reception_U8,Nb_Caracteres_Attendus) ;
CS 0:8b3c6f593515 80
CS 0:8b3c6f593515 81 Index = 0 ;
CS 0:8b3c6f593515 82 //Chrono_Serie.stop() ;
CS 0:8b3c6f593515 83 while( Index < Pointeur_Reception_U8 )
CS 0:8b3c6f593515 84 {// Copie la trame dans l'ordre en cours de réception
CS 0:8b3c6f593515 85 Ordres[Numero_Ordre_En_Reception_U8].Trame_Recue_aU8[Index] = Buffer_Reception_U8 [ Index ] ;
CS 0:8b3c6f593515 86 Index++ ;
CS 0:8b3c6f593515 87 }
CS 0:8b3c6f593515 88 // Nombre de caractères de l'ordre
CS 0:8b3c6f593515 89 Ordres[Numero_Ordre_En_Reception_U8].Nb_Caracteres_Recus_U8 = Pointeur_Reception_U8 ;
CS 0:8b3c6f593515 90 // Fin de réception
CS 0:8b3c6f593515 91 Ordres[Numero_Ordre_En_Reception_U8].Etat_U8 = RECU ;
CS 0:8b3c6f593515 92
CS 0:8b3c6f593515 93 }
CS 0:8b3c6f593515 94
CS 0:8b3c6f593515 95 }
CS 0:8b3c6f593515 96 else
CS 0:8b3c6f593515 97 {
CS 0:8b3c6f593515 98 // Le message n'est pas pour nous, on purge le buffer
CS 0:8b3c6f593515 99 Pointeur_Reception_U8 = 0 ;
CS 0:8b3c6f593515 100 Ordres[Numero_Ordre_En_Reception_U8].Etat_U8 = ATTENTE ;
CS 0:8b3c6f593515 101 Nb_Caracteres_Attendus = TAILLE_BUFFER_RECEPTION ;
CS 0:8b3c6f593515 102 //Chrono_Serie.stop() ;
CS 0:8b3c6f593515 103 PC8.printf("\r\n Serie : pas pour nous %i ",Buffer_Reception_U8 [ 1 ]) ;
CS 0:8b3c6f593515 104 }
CS 0:8b3c6f593515 105
CS 0:8b3c6f593515 106 }
CS 0:8b3c6f593515 107 /************ Enclenchement de la réception *****************/
CS 0:8b3c6f593515 108 void vPort_Serie_Reception ( U8 Numero_Ordre_U8 )
CS 0:8b3c6f593515 109 {
CS 0:8b3c6f593515 110 if ( (Ordres[Numero_Ordre_En_Reception_U8].Etat_U8 != RECEPTION )
CS 0:8b3c6f593515 111 && (Ordres[Numero_Ordre_En_Reception_U8].Etat_U8 != ATTENTE ))
CS 0:8b3c6f593515 112 {// La réception en cours est terminée
CS 0:8b3c6f593515 113 if ( ( Ordres[Numero_Ordre_U8].Etat_U8 == RECU )
CS 0:8b3c6f593515 114 ||( Ordres[Numero_Ordre_U8].Etat_U8 == TRAITE )
CS 0:8b3c6f593515 115 ||( Ordres[Numero_Ordre_U8].Etat_U8 == ARRET ) )
CS 0:8b3c6f593515 116 {// L'ordre est pret à être recu
CS 0:8b3c6f593515 117 Numero_Ordre_En_Reception_U8 = Numero_Ordre_U8 ;
CS 0:8b3c6f593515 118 Ordres[Numero_Ordre_En_Reception_U8].Etat_U8 = ATTENTE ;
CS 0:8b3c6f593515 119 Pointeur_Reception_U8 = 0 ;
CS 0:8b3c6f593515 120 Nb_Caracteres_Attendus = TAILLE_BUFFER_RECEPTION ;
CS 0:8b3c6f593515 121 //PC8.printf("\r\n Debut reception %i Etat %i ",Numero_Ordre_En_Reception_U8,Ordres[Numero_Ordre_En_Reception_U8].Etat_U8) ;
CS 0:8b3c6f593515 122 }
CS 0:8b3c6f593515 123 //PC8.printf("\r\n Reception1 %i Etat %i ",Numero_Ordre_U8,Ordres[Numero_Ordre_U8].Etat_U8) ;
CS 0:8b3c6f593515 124 }
CS 0:8b3c6f593515 125 //PC8.printf("\r\n Reception2 %i Etat %i ",Numero_Ordre_En_Reception_U8,Ordres[Numero_Ordre_En_Reception_U8].Etat_U8) ;
CS 0:8b3c6f593515 126 }
CS 0:8b3c6f593515 127 /************ Emission de la trame ************************/
CS 0:8b3c6f593515 128 void iEmission ( void )
CS 0:8b3c6f593515 129 {
CS 0:8b3c6f593515 130 // Si le buffer n'est pas saturé et qu'il reste des caractères à émettre
CS 0:8b3c6f593515 131 while ( ( Pointeur_Emission_U8 < Nb_Caracteres_A_Emettre_U8 ) )
CS 0:8b3c6f593515 132 {// Emission d'un caractère
CS 0:8b3c6f593515 133 RS.putc( (U8) Buffer_Emission_U8[ Pointeur_Emission_U8 ] ) ;
CS 0:8b3c6f593515 134 Pointeur_Emission_U8++ ;
CS 0:8b3c6f593515 135 //PC8.printf("\r\n Serie : Emission %i ", Buffer_Emission_U8[ Pointeur_Emission_U8-1 ]) ;
CS 0:8b3c6f593515 136 }
CS 0:8b3c6f593515 137 if ( Pointeur_Emission_U8 >= Nb_Caracteres_A_Emettre_U8 )
CS 0:8b3c6f593515 138 {// Tous les caractères sont émis, cloture l'émission
CS 0:8b3c6f593515 139 Ordres[Numero_Ordre_En_Emission_U8].Etat_U8 = FIN ;
CS 0:8b3c6f593515 140 Pointeur_Emission_U8 = 0 ;
CS 0:8b3c6f593515 141 Nb_Caracteres_A_Emettre_U8 = 0 ;
CS 0:8b3c6f593515 142 }
CS 0:8b3c6f593515 143 else
CS 0:8b3c6f593515 144 {// Le buffer est saturé, on reviendra plus tard
CS 0:8b3c6f593515 145
CS 0:8b3c6f593515 146 }
CS 0:8b3c6f593515 147 }
CS 0:8b3c6f593515 148 /************ Emission de la réponse ************************/
CS 0:8b3c6f593515 149 void vPort_Serie_Emission ( U8 Numero_Ordre_U8 )
CS 0:8b3c6f593515 150 {
CS 0:8b3c6f593515 151 U8 Index_U8 ;
CS 0:8b3c6f593515 152
CS 0:8b3c6f593515 153
CS 0:8b3c6f593515 154 if (Ordres[Numero_Ordre_En_Emission_U8].Etat_U8 != EMISSION )
CS 0:8b3c6f593515 155 {// L'émission en cours est terminée
CS 0:8b3c6f593515 156 if (Ordres[Numero_Ordre_U8].Etat_U8 == TRAITE )
CS 0:8b3c6f593515 157 {// L'ordre est pret à être émis
CS 0:8b3c6f593515 158 Ordres[Numero_Ordre_U8].Etat_U8 = EMISSION ;
CS 0:8b3c6f593515 159 Numero_Ordre_En_Emission_U8 = Numero_Ordre_U8 ;
CS 0:8b3c6f593515 160 Nb_Caracteres_A_Emettre_U8 = Ordres[Numero_Ordre_U8].Nb_Caracteres_A_Emettre_U8 ;
CS 0:8b3c6f593515 161 Index_U8 = 0 ;
CS 0:8b3c6f593515 162 // Copie la trame dans le buffer
CS 0:8b3c6f593515 163 while( Index_U8 < Nb_Caracteres_A_Emettre_U8 )
CS 0:8b3c6f593515 164 {
CS 0:8b3c6f593515 165 Buffer_Emission_U8 [ Index_U8 ] = Ordres[Numero_Ordre_U8].Trame_Reponse_aU8 [Index_U8] ;
CS 0:8b3c6f593515 166 Index_U8++ ;
CS 0:8b3c6f593515 167 }
CS 0:8b3c6f593515 168 Pointeur_Emission_U8 = 0 ;
CS 0:8b3c6f593515 169 }
CS 0:8b3c6f593515 170
CS 0:8b3c6f593515 171 //PC8.printf("\r\n Serie : Emission %i : %i/%i",Numero_Ordre_En_Emission_U8, Pointeur_Emission_U8,Nb_Caracteres_A_Emettre_U8) ;
CS 0:8b3c6f593515 172 }
CS 0:8b3c6f593515 173 // Emission de la trame
CS 0:8b3c6f593515 174 iEmission() ;
CS 0:8b3c6f593515 175 }
CS 0:8b3c6f593515 176 /************ Initialisation du Port ************************/
CS 0:8b3c6f593515 177 void vPort_Serie_Init(int Baudrate)
CS 0:8b3c6f593515 178 {
CS 0:8b3c6f593515 179 // Initialisation du port RS
CS 0:8b3c6f593515 180 RS.baud(Baudrate) ;
CS 0:8b3c6f593515 181 // Purge des buffers
CS 0:8b3c6f593515 182 for ( Pointeur_Emission_U8 = 0 ; Pointeur_Emission_U8 < TAILLE_BUFFER_EMISSION ; Pointeur_Emission_U8++ )
CS 0:8b3c6f593515 183 {
CS 0:8b3c6f593515 184 Buffer_Emission_U8[Pointeur_Emission_U8] = 0 ;
CS 0:8b3c6f593515 185 }
CS 0:8b3c6f593515 186 for ( Pointeur_Reception_U8 = 0 ; Pointeur_Reception_U8 < TAILLE_BUFFER_RECEPTION ; Pointeur_Reception_U8++ )
CS 0:8b3c6f593515 187 {
CS 0:8b3c6f593515 188 Buffer_Reception_U8[Pointeur_Reception_U8] = 0 ;
CS 0:8b3c6f593515 189 }
CS 0:8b3c6f593515 190
CS 0:8b3c6f593515 191 Pointeur_Emission_U8 = 0 ;
CS 0:8b3c6f593515 192 Pointeur_Reception_U8 = 0 ;
CS 0:8b3c6f593515 193 Numero_Ordre_En_Reception_U8 = 0 ;
CS 0:8b3c6f593515 194 Numero_Ordre_En_Emission_U8 = 0 ;
CS 0:8b3c6f593515 195 //PC8.printf("\r\n Serie : Init %i ", Baudrate) ;
CS 0:8b3c6f593515 196 // Temps alloué pour 1 caractere = 10bits / Baudrate x 1E6 us
CS 0:8b3c6f593515 197 Temps_alloue_Caractere_S32 = 10000000 / Baudrate * 3 ;
CS 0:8b3c6f593515 198 }
CS 0:8b3c6f593515 199
CS 0:8b3c6f593515 200 /************ Ouverture du port Série **********************/
CS 0:8b3c6f593515 201 void vPort_Serie_Ouvre(void)
CS 0:8b3c6f593515 202 {
CS 0:8b3c6f593515 203 // Purge du buffer de réception
CS 0:8b3c6f593515 204 while( RS.readable() )
CS 0:8b3c6f593515 205 {
CS 0:8b3c6f593515 206 Buffer_Reception_U8[0] = RS.getc() ;
CS 0:8b3c6f593515 207 }
CS 0:8b3c6f593515 208 Buffer_Reception_U8[0] = 0 ;
CS 0:8b3c6f593515 209
CS 0:8b3c6f593515 210 vPort_Serie_Reception ( 0 ) ;
CS 0:8b3c6f593515 211 RS.attach (&iReception_Serie , RS.RxIrq) ;
CS 0:8b3c6f593515 212
CS 0:8b3c6f593515 213 //RS.printf ("Debut") ;
CS 0:8b3c6f593515 214 //PC8.printf("\r\n Serie : Attach ") ;
CS 0:8b3c6f593515 215
CS 0:8b3c6f593515 216 }
CS 0:8b3c6f593515 217
CS 0:8b3c6f593515 218 /************ Controle de réception **********************/
CS 0:8b3c6f593515 219 U8 cControle_Reception( U8 Numero_Ordre_U8 )
CS 0:8b3c6f593515 220 {/*
CS 0:8b3c6f593515 221 if ( Numero_Ordre_U8 != Numero_Ordre_En_Reception_U8 )
CS 0:8b3c6f593515 222 {// La réception est arrétée
CS 0:8b3c6f593515 223 //Chrono_Serie.stop() ;
CS 0:8b3c6f593515 224 return ( ARRET ) ;
CS 0:8b3c6f593515 225 }
CS 0:8b3c6f593515 226 if ( Chrono_Serie.read_us() > ( Temps_alloue_Caractere_S32 * Nb_Caracteres_Attendus ) )
CS 0:8b3c6f593515 227 {// Dépassement du temps alloué
CS 0:8b3c6f593515 228 //Chrono_Serie.stop() ;
CS 0:8b3c6f593515 229 Numero_Ordre_En_Reception_U8++ ;
CS 0:8b3c6f593515 230 Pointeur_Reception_U8 = 0 ;
CS 0:8b3c6f593515 231 Nb_Caracteres_Attendus = TAILLE_BUFFER_RECEPTION ;
CS 0:8b3c6f593515 232
CS 0:8b3c6f593515 233 return ( TIMEOUT ) ;
CS 0:8b3c6f593515 234 }*/
CS 0:8b3c6f593515 235 return ( RECEPTION ) ;
CS 0:8b3c6f593515 236 }
CS 0:8b3c6f593515 237
CS 0:8b3c6f593515 238 /************ Fermeture du port Série **********************/
CS 0:8b3c6f593515 239 void vPort_Serie_Ferme( void )
CS 0:8b3c6f593515 240 {
CS 0:8b3c6f593515 241 //RS.detach() ;
CS 0:8b3c6f593515 242 }
CS 0:8b3c6f593515 243
CS 0:8b3c6f593515 244 /************ Cloture du port Série **********************/
CS 0:8b3c6f593515 245 void vPort_Serie_Cloture( void )
CS 0:8b3c6f593515 246 {
CS 0:8b3c6f593515 247 }