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 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473
|
#include <16F877A.h>
#device icd=true // Autorisation debugger
#FUSES NOWDT // No Watch Dog Timer
#FUSES HS // High speed Osc (> 4mhz)
#FUSES NOPUT // No Power Up Timer
#FUSES NOPROTECT // Code not protected from reading
#FUSES NODEBUG // No Debug mode for ICD
#FUSES BROWNOUT // Reset when brownout detected
#FUSES NOLVP // No low voltage prgming, B3(PIC16) used for I/O
#FUSES NOCPD // No EE protection
#FUSES NOWRT // Program memory not write protected
#use delay(clock=20000000) // Fréquence du quartz 20MHz
/* Définition des paramètres pour la liaison série RS232 */
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)
// Définition des E/S TOR sur carte CONTROLE
#define muxvoie1 PIN_B1 // Sortie 1 de multiplexage voies RS232
#define muxvoie2 PIN_B2 // Sortie 2 de multiplexage voies RS232
#define mforc PIN_C0 // Entrée marche forcée
#define resetSP1 PIN_D1 // Reset du module SitePlayer
#define comm PIN_D7 // LED communication
// - FMa- Définition pour allumer et éteindre la LED coouminication
#define comm_on (output_high(comm))
#define comm_off (output_low(comm))
// Déclaration des fonctions utilisées (utile pour le compilateur)
void initialisation();
void acqui_analog();
void calcul();
void envoi_pc();
void recoi_pc();
void envoi_distrib();
void recoi_distrib();
void ecri_mot_sp1();
void ecri_bit_sp1();
void lit_mot_sp1();
void lit_bit_sp1();
int lit_char();
void envoi_trame(char[], size_t size);
// Déclarations du type des variables globales
// int1 : 1 bit
int1 autorise, autorisationGPL, timeout_error;
int1 alarmetemp, alarmestock, autorisationmarche;
// int : 8 bits (-128 à 127)
int nboctet, dist, i, etape, timeout, ;
int retard = 50;
// char : 8 bits (0 à 255)
char trame_tx1[15], trame_tx2[15];
char trame_rx1[15], trame_rx2[15];
// int16 = 16 bits
int16 prixlitre, volume, prixtotal, seuiltemp, stockmini, prov;
// float = virgule flottante
float temperature, stock, hcuve, eana0, eana1;
/* ============= PROGRAMME PRINCIPAL ==================
Nota : la boucle du programme principal est volontairement
ralentie (delay_ms(xx)) afin de laisser le temps aux
autres équipements d'effectuer leurs différents traitements.
*/
void main()
{
initialisation();
do
{
calcul(); // Calcul stock et alarmes.
output_low(muxvoie1); // Liaison série N°1 (PC Pompiste)
output_low(muxvoie2);
delay_ms(retard);
envoi_pc(); // Envoi trame au PC Pompiste
recoi_pc(); // Réception réponse du PC
output_high(muxvoie1); // Liaison série N°2 (Carte Distributeur)
output_low(muxvoie2);
delay_ms(retard);
envoi_distrib(); // Envoi trame au Ditributeur
recoi_distrib(); // Réception réponse du Distributeur
output_low(muxvoie1); // Liaison série N°3 (Web Serveur SP1)
output_high(muxvoie2);
delay_ms(retard);
ecri_mot_sp1(); // Ecriture des mots dans SP1
delay_ms(retard);
ecri_bit_sp1(); // Ecriture des bits dans SP1
delay_ms(retard);
lit_mot_sp1(); // Lecture des mots dans SP1
delay_ms(retard);
lit_bit_sp1(); // Lecture des bits dans SP1
delay_ms(retard);
}
while(1); // Le programme reboucle indéfiniment.
}
/* ============== FIN DU PROGRAMME PRINCIPAL ========== */
/* ====== FONCTIONS APPELEES PAR LE PROGRAMME PRINCIPAL ======= */
/* Configuration du microcontroleur */
void initialisation()
{
/* Initialisation des variables */
dist=0;
autorisationGPL = 0;
autorisationmarche = 0;
volume=0;
prixtotal=0;
etape=0;
/* Reset du Webserveur SP1 */
output_high(resetSP1);
delay_ms(100);
output_low(resetSP1);
/* Attente démarrage du Web serveur SP1 (mini 150 ms) */
for (i = 0 ; i < 5 ; i++)
{
output_high(comm); // Clignotement rapide de la LED communication
delay_ms(100);
output_low(comm);
delay_ms(100);
}
/* Init communication avec Web Serveur SP1 */
output_low(muxvoie1); // Liaison série N°3 (Web Serveur SP1)
output_high(muxvoie2);
comm_on;
for (i = 0 ; i < 20 ; i++)
{
putc(0); // Init communication SP1 (20 NOP)
}
comm_off;
/* Envoi au Web Serveur SP1 des paramètres sauvegardés dans PIC */
trame_tx2[0] = 0x87; // Code écriture 8 octets
trame_tx2[1] = 0x30; // Adresse écriture = 30H
trame_tx2[2] = read_eeprom(0); // nouveauprix
trame_tx2[3] = read_eeprom(1);
trame_tx2[4] = read_eeprom(2); // hcuve
trame_tx2[5] = read_eeprom(3);
trame_tx2[6] = read_eeprom(4); // seuiltemp
trame_tx2[7] = read_eeprom(5);
trame_tx2[8] = read_eeprom(6); // stockmini
trame_tx2[9] = read_eeprom(7);
prov = trame_tx2[3]*256 + trame_tx2[2];
if ((prov < 0) || (prov > 9999))
{
trame_tx2[2] = 0; // valeur par défaut 0,768 euro
trame_tx2[3] = 3;
}
prov = trame_tx2[5]*256 + trame_tx2[4];
if ((prov < 0) || (prov > 99))
{
trame_tx2[4] = 35; // valeur par défaut 35 cm
trame_tx2[5] = 0;
}
prov = trame_tx2[7]*256 + trame_tx2[6];
if ((prov < 0) || (prov > 500))
{
trame_tx2[6] = 4; // valeur par défaut 26,0 °C
trame_tx2[7] = 1;
}
prov = trame_tx2[9]*256 + trame_tx2[8];
if ((prov < 0) || (prov > 100))
{
trame_tx2[8] = 25; // valeur par défaut 25 %
trame_tx2[9] = 0;
}
comm_on;
for (nboctet = 0 ; nboctet < 10 ; nboctet++)
{
putc(trame_tx2[nboctet]); // Ecriture sur liaison série
}
delay_ms(retard); // Attente fin envoi avant changer mux
comm_off;
}
/* Calcul grandeurs physiques et élaboration des alarmes */
void calcul()
{
stock = (7000 * eana0) / (1024 * hcuve); // Stock en %
if (stock < stockmini) // alarme stock mini
alarmestock=1;
else
alarmestock = 0;
temperature = (500 * eana1 / 1024); // Température en 1/10 °C
if (temperature > seuiltemp) // alarme température maxi
alarmetemp=1;
else
alarmetemp = 0;
}
/* Envoi trame au PC Pompiste */
void envoi_pc()
{
trame_tx1[0] = 'A'; // Code début de trame
trame_tx1[2] = (volume/256);
trame_tx1[1] = (volume - trame_tx1[2] * 256);
trame_tx1[4] = (prixlitre/256);
trame_tx1[3] = (prixlitre - trame_tx1[4] * 256);
trame_tx1[6] = (prixtotal/256);
trame_tx1[5] = (prixtotal - trame_tx1[6] * 256);
trame_tx1[8] = (temperature/256);
trame_tx1[7] = (temperature - trame_tx1[8] * 256);
trame_tx1[10] = (stock/256);
trame_tx1[9] = (stock - trame_tx1[10] * 256);
trame_tx1[11] = autorisationmarche*8 + alarmestock*4 + alarmetemp*2 + dist;
trame_tx1[12] = etape;
comm_on;
for (nboctet = 0 ; nboctet < 13 ; nboctet++) // on envoie 13 octets
{
putc(trame_tx1[nboctet]); // écriture sur liaison série
}
comm_off;
}
/* Réception trame du PC pompiste*/
void recoi_pc()
{
nboctet = 0;
timeout_error = 0;
comm_on;
while ((timeout_error == 0) && (nboctet < 2)) // On attend 2 octets
{
trame_rx1[nboctet] = lit_char(); // Réception du caractère
nboctet++;
}
comm_off;
if ((timeout_error == 0) && (trame_rx1[0] == 'P')) // Si trame reçue OK
{
if (dist == 0)
autorisationGPL = trame_rx1[1] && 0x01;
else
autorisationGPL =0;
}
}
/* Ecriture mots dans Web Serveur SP1 */
void ecri_mot_sp1()
{
trame_tx2[0] = 0x8A; // Code écriture 11 mots (octets)
trame_tx2[1] = 0x0; // à l'adresse 0000
trame_tx2[2] = trame_tx1[1];
trame_tx2[3] = trame_tx1[2];
trame_tx2[4] = trame_tx1[3];
trame_tx2[5] = trame_tx1[4];
trame_tx2[6] = trame_tx1[5];
trame_tx2[7] = trame_tx1[6];
trame_tx2[8] = trame_tx1[7];
trame_tx2[9] = trame_tx1[8];
trame_tx2[10] = trame_tx1[9];
trame_tx2[11] = trame_tx1[10];
trame_tx2[12] = etape;
comm_on;
for (nboctet = 0 ; nboctet < 13 ; nboctet++)
{
putc(trame_tx2[nboctet]); // écriture sur liaison série
}
comm_off;
}
/* Ecriture bits dans Web Serveur SP1 */
void ecri_bit_sp1()
{
trame_tx2[0] = 0x90; // Code écriture bits
trame_tx2[1] = 0xE0; // Adresse dans SP1
trame_tx2[2] = 0x02;
trame_tx2[3] = alarmestock * 4 + alarmetemp * 2 + dist;
comm_on;
for (nboctet = 0 ; nboctet < 4 ; nboctet++)
{
putc(trame_tx2[nboctet]); // écriture sur liaison série
}
comm_off;
}
/* Lecture mots dans Web Serveur SP1 */
void lit_mot_sp1()
{
trame_tx2[0] = 0xC7; // Code lecture 8 mots (octets)
trame_tx2[1] = 0x30; // Adresse dans SP1
comm_on;
for (nboctet = 0 ; nboctet < 2 ; nboctet++)
{
putc(trame_tx2[nboctet]); // écriture sur liaison série
}
comm_off;
nboctet = 0;
timeout_error = 0;
comm_on;
while ((timeout_error == 0) && (nboctet < 8)) // On attend 8 octets
{
trame_rx2[nboctet] = lit_char(); // Réception du caractère
nboctet++;
}
comm_off;
if (timeout_error == 0) // si trame reçue OK
{
prov = trame_rx2[0] + (trame_rx2[1] * 256);
if ((prixlitre != prov) && (autorisationmarche == 0) && (dist == 0))
{
if ((prov > 0) && (prov < 10000))
prixlitre = prov;
else
prixlitre = 1000;
write_eeprom(0,trame_rx2[0]); // Sauvegarde nouveau prix
write_eeprom(1,trame_rx2[1]); // dans mémoire EEPROM du PIC
}
prov = trame_rx2[2] + (trame_rx2[3] * 256);
if (hcuve != prov)
{
if ((prov > 0) && (prov < 100))
hcuve = prov;
else
hcuve = 35;
write_eeprom(2,trame_rx2[2]); // Sauvegarde nouvelle hauteur
write_eeprom(3,trame_rx2[3]); // dans mémoire EEPROM du PIC
}
prov = trame_rx2[4] + (trame_rx2[5] * 256);
if (seuiltemp != prov)
{
if ((prov > 0) && (prov < 500))
seuiltemp = prov;
else
seuiltemp = 250;
write_eeprom(4,trame_rx2[4]); // Sauvegarde nouveau seuil
write_eeprom(5,trame_rx2[5]); // dans mémoire EEPROM du PIC
}
prov = trame_rx2[6] + (trame_rx2[7] * 256);
if (stockmini != prov)
{
if ((prov > 0) && (prov < 100))
stockmini = prov;
else
stockmini = 50;
write_eeprom(6,trame_rx2[6]); // Sauvegarde nouveau stockmini
write_eeprom(7,trame_rx2[7]); // dans mémoire EEPROM du PIC
}
}
}
/* Lecture bits dans Web Serveur SP1 */
void lit_bit_sp1()
{
trame_tx2[0] = 0xD0; // Code demande lecture bits
trame_tx2[1] = 0xE2; // Adresse dans SP1
trame_tx2[2] = 0x02; // Adresse dans SP1
comm_on;
for (nboctet = 0 ; nboctet < 3 ; nboctet++)
{
putc(trame_tx2[nboctet]); // écriture sur RS232
}
comm_off;
nboctet = 0;
timeout_error = 0;
comm_on;
while ((timeout_error == 0) && (nboctet < 1)) // On attend 1 octet
{
trame_rx2[nboctet] = lit_char(); // Réception du caractère
nboctet++;
}
comm_off;
if (timeout_error == 0) // si trame reçue OK
{
autorisationmarche = ((trame_rx2[0] && 0x01) || (!input(mforc)));
if (autorisationmarche == 0)
{
autorisationGPL =0;
autorise = 0;
}
}
}
/* Envoi trame à la carte DISTRIBUTEUR */
void envoi_distrib()
{
trame_tx2[0] = 'C';
trame_tx2[1] = trame_tx1[3]; // Prix au litre
trame_tx2[2] = trame_tx1[4];
autorise = autorisationGPL && autorisationmarche;
trame_tx2[3] = autorise; // Autorisation de distribution (0 ou 1)
comm_on;
for (nboctet = 0 ; nboctet < 4 ; nboctet++)
{
putc(trame_tx2[nboctet]); // écriture sur liaison série
}
comm_off;
}
/* Réception trame de la carte DISTRIBUTEUR */
void recoi_distrib()
{
nboctet = 0;
timeout_error = 0;
comm_on;
while ((timeout_error == 0) && (nboctet < 11)) // on attend 11 octets
{
trame_rx2[nboctet] = lit_char(); // Réception du caractère
nboctet++;
}
comm_off;
if (timeout_error == 0) // si trame reçue (pas timeout)
{
nboctet = 0;
if (trame_rx2[0] == 'D') // si trame OK
{
volume = trame_rx2[1] + trame_rx2[2] * 256;
prixtotal = trame_rx2[3] + trame_rx2[4] * 256;
dist = trame_rx2[5] && 0x01;
if ((dist == 1) && (autorisationGPL ==1))
{
autorisationGPL = 0;
}
eana0 = trame_rx2[6] + trame_rx2[7] * 256; // Valeurs E analogiques
eana1 = trame_rx2[8] + trame_rx2[9] * 256;
etape = trame_rx2[10];
}
}
}
/* Réception d'un caractère sur liaison série ou sortie sur timeout */
int lit_char()
{
timeout = 0;
timeout_error = 0;
while (!kbhit() && (++timeout < 30)) // Attente tant que pas caractère
delay_ms(1); // reçu et temps < 30 ms
if (kbhit()) // Si caractère reçu
return (getc()); // retour caractère lu
else
{
timeout_error = 1; // Sinon Erreur timeout
return(0);
}
} |
Partager