Version initiale
Dependencies: mbed
Fork of Le_Pont_V10116 by
Port_Serie.cpp@2:a10c8133d71c, 2018-03-29 (annotated)
- 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?
User | Revision | Line number | New 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 | } |