Jauge de mesure de niveau de fuel basée sur un capteur de pression
J'ai réalisé il y a quelques années une jauge à fuel électronique, plus précise que la jauge pneumatique existante. Elle utilise un capteur de pression absolue, immergé au fond de la cuve à fuel, et relié à une carte à base de micro-contrôleur ST6210, qui gère un afficheur via un MM5450.
Sachant que tout corps plongé dans un liquide en ressort mouillé d'une part, et subit une pression égale au poids du volume du liquide déplacé d'autre part (Archimède), le tout saupoudré d'un peu de Bernouilli, il est aisé de faire le lien entre la pression au niveau du capteur et la quantité de fuel dans la cuve.
Schéma théorique
Typon d'une des versions, à titre indicatif
(à remettre à l'échelle: extérieur 227 * 136 mm)
Plan d'implantation:
Fichier source
;--------------------------------------------------------------------------- ; Programme pour Jauge à Fuel ; ; Carte à base de ST62T10 ; ; Développement sur ST62TE20 ; ; dB ; ; Original 20/02/97 ; ; - gestion du watchdog qui ne peut être masqué (HWD) ; - travail sans interruptions ; - photo des ports E/S en début de boucle ; - travail sur la photo au long du programme ; - réécriture des ports E/S en fin de boucle ; ; Version jauge00.asm à jauge05.asm ; ; - Diverses errances ; - Erreurs de pointage en table ; - Mauvais format de dialogue avec le MM5450 ; - Ensemble trop lent (incrément/décrément unités) ; ; Version jauge06.asm ; ; - Temps de boucle plus important ; - Incrément et décrément de 10 en 10 ; - Le digit des unités est toujours forcé à zéro ; - Globalement ça marche !!! ; ; Version jauge07.asm ; ; - Ajout filtrage soft mesure pression: la variable ; pression ne peut changer que d'un point par ; mesure. Marche tout bien, sauf si micro-coupure ; (les digits des chiffres sont alors 'déformés') ; ; Version jauge08.asm ; ; - Ajout d'une routine de test des codes envoyés ; au MM5450 : Si un code digit est différent de ; celui d'un chiffre de 0 à 9, alors schnell RESET. ; ; Version jauge09.asm ; ; - On casse tout et on recommence, avec un principe ; plus simple: on fait la moyenne de 256 mesures, ; et le nombre obtenu est utilisé directement pour ; l'affichage. ; - Chaque routine appelée doit faire complètement son ; travail avant de rendre la main: c'est le cas par ; exemple du dialogue avec le MM5450: envoi de salves ; - Sur la carte, on relie la broche 34 du MM, non ; utilisée, à la broche 33, pour augmenter le courant ; disponible pour la Led STOP. ; On modifie donc les salves envoyées à ce MM ; pour valider cette broche 34 avec la broche 33. ; - Plus de clignotement de la led STOP. ; ; Version jauge10.asm ; ; - Découverte d'une erreur au niveau du mapping: les ; adresses 080h à 083h sont affectées aux registres ; du micro (X, Y, V, W): ce qui explique bien des ; problèmes. ; ; Version jauge11.asm ; ; - Cette version est basée sur la version 7, ; avec cette fois ci déclaration des variables à ; partie de l'adresse 084h ; ; Version jauge12.asm ; ; - Cette version est basée sur la version 10 ; avec du blabla en plus ; ; Essentiel sur le ST6225, très difficile à retrouver dans un certain ; livre sur les ST62XX particulièrement mal fait, et dont je tairai ; le nom: ; ; Drapeaux C retenue ; Z zéro ; ; Flag Carry du ST6225 (différent pour un ST60): ; - mis à 1 si dépassement capacité lors d'additions ADD ADDI ; - contient le MSB du registre avant un complément COM ; - mis à 1 si A < toto et mis à 0 si A>= toto ; dans CP A, toto et CPI A, toto ; - contient l'ancien MSB du registre après un RLC ; (et le nouveau LSB du registre est l'ancien flag C) ; - contient l'ancien MSB du registre après un SLA ; (et le nouveau LSB du registre est 0) ; - mis à 1 si A < toto et mis à 0 si A>= toto ; dans SUB A, toto et SUBI A, toto ; ; Espace mémoire ST6210/20 Les deux ST6215/25 ; Fenêtre ROM 040h à 07Fh ; Registre X 080h ; Registre Y 081h ; Registre V 082h ; Registre W 083h ; Données RAM 084h à 0BFh ; Registre DRA 0C0h ; Registre DRB 0C1h ; Registre DRC 0C2h ; Registre DDRA 0C4h ; Registre DDRB 0C5h ; Registre DDRC 0C6h ; Registre IOR 0C8h ; Registre DRWR 0C9h ; Registre ORA 0CCh ; Registre ORB 0CDh ; Registre ORC 0CEh ; Registre ADR 0D0h ; Registre ADCR 0D1h ; Registre PSC 0D2h ; Registre TCR 0D3h ; Registre TSCR 0D4h ; Registre WDR 0D8h ; Registre 8b A 0FFh ; Programme 880h à F9Fh 080h à F9Fh ; Vecteur CAN FF0h & FF1h ; Vecteur Timer FF2h & FF3h ; Vecteur Pb & Pc FF4h & FF5h ; Vecteur Pa FF6h & FF7h ; Vecteur Nmi FFCh & FFDh ; Vecteur Reset FFEh & FFFh ; ; Configuration des entrées sorties: ports A, B, C ; bit DDR bit OR bit DR Mode ; 0 0 0 Entrée avec rappel, ss interruption (initial) ; 0 0 1 Entrée sans rappel ni interruption ; 0 1 0 Entrée avec rappel et interruption ; 0 1 1 Entrée sans rappel ni interruption (PA0 à 3) ; ou Entrée analogique (autres) ; 1 0 X Sortie drain ouvert 10 mA (PA0 à 3) ; ou Sortie drain ouvert 5 mA (autres) ; X est l'état dans lequel la sortie est placée ; 1 = haut et 0 = bas ; 1 1 X Sortie symétrique ; X est l'état dans lequel la sortie est placée ; 1 = haut et 0 = bas ; ; Attention: ne pas utiliser de set ou reset sur les bits d'un ; registre DRA, DRB ou DRC, car il y a alors lecture, positionnement et ; réécriture: la lecture n'étant pas fiable (certains registres sont ; à écriture seule), en faisant cela on peut modifier la configuration ; du registre. ; ; 1 cycle = 13 périodes de l'oscillateur, soit ici 3.53 µs avec le ; quartz à 3.6864 MHz. Avec en moyenne 4 cycles par instruction, ; on trouve un temps approximatif de 14.1 µs par instruction. ; ; Convertisseur analogique > numérique: ; ; Registre ADR à lecture seule, pour le résultat ; ; Registre ADCR pour le contrôle ; ADCR b7 b6 b5 b4 b3 b2 b1 b0 ; EAI EOC STA PDS - - - - ; ; Bit 0 1 ; PDS CAN inactif CAN prêt ou en cours ; STA Doit être mis à 0 Au front montant, déclenche ; avant une acquisition une acquisition ; EOC Mis à 0 quand STA Mis à 1 en fin de conversion ; passe à 1 ; EAI Pas d'interruption Interruption ADC générée en ; fin de conversion ; La fréquence du quartz doit être au moins de 1.2 MHz pour pouvoir ; utiliser le CAN. ; La plage de signal est 00h pour Vss (ex: 0V) à FFh pour Vdd (ex: +5V) ; La source de tension analogique doit avoir une impédance de sortie ; inférieure à 30 kOhm. ; ; Fenêtre ROM: la mémoire ROM n'est accessible que via une fenêtre de ; 64 octets dans l'espace adressable par le micro. L'adresse du premier ; octet de la fenêtre est 0040h, et celle du dernier octet est 007Fh. ; On choisi le segment de ROM visible dans la fenêtre par le chargement ; préalable du registre Data Rom Window Register, l'adresse dans la ROM ; étant définie ainsi sur 12 bits: ; ; Adresse ROM 11 10 09 08 07 06 05 04 03 02 01 00 ; DRWR 00 00 D5 D4 D3 D2 D1 D0 ; Adresse dans fenêtre 0 1 D5 D4 D3 D2 D1 D0 ; î ; Ce 1 est là car la première ; adresse de la fenêtre est 64 ; ; Timer: un registre TCR (compteur) et un registre TSCR (contrôle) ; ; registre TSCR: ; b7 b6 b5 b4 b3 b2 b1 b0 ; TMZ ETI TOUT DOUT PSI PS2 PS1 PS0 ; ; TMZ : Mis à 1 si le registre TCR passe à 0, et déclenche une ; interruption si ETI est à 1 ; ; ETI : autorise les interruptions, si mis à 1 ; TOUT DOUT TMZ Déterminent la fonction de la broche Timer ainsi: ; 0 0 - Entrée, front montant actif, compteur d'évennements ; 0 1 - Entrée, niveau 1 = comptage horloge interne ; 0 = arrêt comptage ; utilisé pour mesure durées ; 1 - 0 Sortie, niveau = valeur précédente ; 1 0 1 Sortie, niveau = 0 (DOUT) } utilisé pour générer un ; 1 1 1 Sortie, niveau = 1 (DOUT) } niveau en fin comptage ; ; PSI : Si mis à 1, commande la mise à 1 de tous les bits du TCR et du ; prédiviseur PSC, et autorise fonctionnement et accès. ; Si mis à 0, le TCR est gelé et le PSC est forcé à 7Fh ; ; PS2 PS1 PS0 Rapport de division ; 0 0 0 1 ; 0 0 1 2 ; 0 1 0 4 ; 0 1 1 8 ; 1 0 0 16 ; 1 0 1 32 ; 1 1 0 64 ; 1 1 1 128 ; ; Chien de garde : registre DWDR dont les bits DWDR1 (MSB ! ) à ; DWDR7 (LSB !) sont décrémentés à une fréquence égale à celle du ; quartz, divisée par 3072: en fait, le basculement du bit DWDR2 ; provoque un reset, donc la valeur utile du watchdog se charge ; sur DWD2 à DWD7, soit un mot de 6 bits, variant donc de 0 à 63. ; Comme il faut 13 coups d'horloge pour un cycle machine, le registre ; DWDR est donc décrémenté tous les 3072 / 13 = 236 cycles machine ; environ, soit en moyenne toutes les 59 instructions. ; Après un reset, le chien de garde doit être réarmé avant la 28ème ; instruction, et ensuite au moins toutes les 59 instructions environ, ; pour un rechargement avec la valeur 10000000b, et toutes les 3750 ; instructions environ, pour un rechargement avec la valeur 11111110b. ; Dialogue avec le MM 5450 ; ; - Validation sur front montant horloge ; - Fréquence maximale horloge: 500 kHz ; - Envoi dans l'ordre de 1, Q1, ..., Q35 ; (Q35 inexistante mais doit être gérée pour ; compatibilité avec le MM 5451) ; - Séquence: positionnement data ; attente de 300 ns ; montée de l'horloge ; attente de 300 ns ; descente de l'horloge ; etc ... ; La tempo de 300 ns n'est pas gérée par le timer ; mais se fait si besoin par boucle d'attente, et en ; fait il n'y en a pas besoin ici, car avec une ; horloge à 3.6864 MHz, on a un temps de cycle de ; 1 / (3.6864 E6 / 13) = 3.53 µs, soit un temps ; d'instruction de 14.1 µs environ, largement au ; dessus des 300 ns nécessaires. ; ; Ne pas oublier: ; ; - effacage aux U.V. 30 minutes ; - d'obstruer la fenêtre du ST6225 après programmation ou ; mieux griller un OTP (composant non effaçable, et donc ; programmable une seule fois), quand tout est OK. ; ; Assemblage du programme: ; ; - Le programme assembleur source est par exemple CHENILLE.ASM ; - Pour un ST6225, l'assembler par AST6 -L CHENILLE ; ; Programmation du ST6: ; ; - copier le programme assemblé (.hex) sur la disquette ; bootable chenille ; - Rebooter le PC sur cette disquette (démarrage sous un ; ancien DOS, le logiciel ne tournant pas sous WIN95) ; - Utiliser la carte branchée sur le port parallèle ; - Alimenter la carte en 12V DC ; - Lancer le programme ST6PGM.BAT ; ; Brochage du MM 5450 ; ; Broche Fonction Segment d'afficheur ; 1 Vss ; 2 Q17 dp centaines ; 3 Q16 d dizaines ; 4 Q15 e dizaines ; 5 Q14 f dizaines ; 6 Q13 a dizaines ; 7 Q12 g dizaines ; 8 Q11 b dizaines ; 9 Q10 c dizaines ; 10 Q 9 dp dizaines ; 11 Q 8 d unités ; 12 Q 7 e unités ; 13 Q 6 f unités ; 14 Q 5 a unités ; 15 Q 4 g unités ; 16 Q 3 b unités ; 17 Q 2 c unités ; 18 Q 1 dp unités ; 19 Réglage luminosité ; 20 Vdd ; 21 Horloge ; 22 Data ; 23 /Enable ; 24 Q34 Stop ; 25 Q33 Stop ; 26 Q32 d milliers ; 27 Q31 e milliers ; 28 Q30 f milliers ; 29 Q29 a milliers ; 30 Q28 g milliers ; 31 Q27 b milliers ; 32 Q26 c milliers ; 33 Q25 dp milliers ; 34 Q24 d centaines ; 35 Q23 e centaines ; 36 Q22 f centaines ; 37 Q21 a centaines ; 38 Q20 g centaines ; 39 Q19 b centaines ; 40 Q18 c centaines ; ; Dialogue avec le MM 5450 ; ; - Validation sur front montant horloge ; - Fréquence maximale horloge: 500 kHz ; - Envoi dans l'ordre de 1, Q1, ..., Q34 ; - Séquence: positionnement data ; montée de l'horloge ; attente de ktemporl ; descente de l'horloge ; etc ... ; ; Affectation des E/S du ST6210: ; ; - PA0: sortie Horloge pour le MM 5450 ; - PA1: sortie Data pour le MM 5450 ; - PA2: sortie /Enable pour le MM 5450 (mettre a 0) ; - PA3: non utilisée, en entrée avec rappel ; ; - PB0: Entrée Tout ou Rien Niveau ; - PB1: non utilisée, en entrée avec rappel ; - PB2: non utilisée, en entrée avec rappel ; - PB3: entrée analogique tension image de la pression ; - PB4: non utilisée, en entrée avec rappel ; - PB5: non utilisée, en entrée avec rappel ; - PB6: non utilisée, en entrée avec rappel ; - PB7: non utilisée, en entrée avec rappel ; ; Ne pas oublier: ; ; - effaçage aux U.V. 15 minutes ; - obstruer la fenêtre du ST62E20 après programmation ; ; Assemblage du programme: ; ; - Le programme assembleur source est par exemple JAUGE.ASM ; - Pour un ST62E20, l'assembler par AST6 -L JAUGE ; ; Programmation du ST6: ; ; - copier le programme assemblé (.hex) sur la disquette ; boot jauge, dans le répertoire jauge. ; - Rebooter le PC sur cette disquette (démarrage sous un ; ancien DOS, le logiciel ne tournant pas sous WIN95) ; - Utiliser la carte branchée sur le port parallèle ; - Alimenter la carte en 12V DC ; - Lancer le programme ST6PGM.BAT ; ; - Presser éventuellement sur le connecteur de la carte lors ; des dialogues car il y a un faux contact (à réparer un de ; ces jours) ; ;--------------------------------------------------------------------------- ; Directives d'assemblage .title "Jauge a Fuel" ; titre sur le listing .vers "st6215" .input "6215_reg.asm" ; définition noms registres ;--------------------------------------------------------------------------- ; définition des constantes utilisées dans le programme (ROM) ktempo .equ 10 ; valeur chargée dans TCR, donne un ; pulse de 10 * 2.78us = 27.8 us ktemporl .equ 2 ; (2-1) * 27.8us = 27.8us T/2 horloge knonos .equ 254 ; Un gros os pour le chien de garde kvalisto .equ 250 ; valeur en sortie du CAN pour ; laquelle on considère que la cuve ; est remplie à toc d'où allumage ; de la led STOP (ceci est redondant ; avec l'entrée contact flotteur) kdevasto .equ 240 ; valeur en sortie du CAN pour ; laquelle on considère que le ; niveau est redescendu assez pour ; éteindre la led STOP ;--------------------------------------------------------------------------- ; définition des emplacements des variables en RAM boucle .def 0084h ; pour calcul pression moyenne codeuni .def 0085h ; code des unités envoyé au MM 5450 codediz .def 0086h ; code des dizaines envoyé au MM 5450 codecen .def 0087h ; code des centaines envoyé au MM 5450 codemil .def 0088h ; code des milliers envoyé au MM 5450 cumul .def 0089h ; cumul poids faible pression flag1 .def 008Ah ; série de drapeaux ; b0: bit envoyé au MM 5450: led STOP ; b1: horloge MM 5450 ; b2: data MM 5450 ; b3: ; b4: 1 si milliers affichés ; b5: 1 si centaines affichées ; b6: 1 si dizaines affichées ; b7: 1 si segment afficheur valide ima .def 008Bh ; image du port A imb .def 008Ch ; image du port B masque .def 008Dh ; masquage sérialisation MM 5450 numoct .def 008Eh ; numéro octet envoyé au MM 5450 numbit .def 008Fh ; numéro du bit envoyé au MM 5450 pression .def 0090h ; mémorisation de la sortie du CAN tabluni .def 0091h ; valeur des unités lue en table tabldiz .def 0092h ; valeur des dizaines lue en table tablcen .def 0093h ; valeur des centaines lue en table tablmil .def 0094h ; valeur des milliers lue en table temporl .def 0095h ; tempo décrémentée horloge MM 5450 ;--------------------------------------------------------------------------- ; définition des vecteurs d'interruption CAN, timer, ports, NMI et reset ; Travail sans aucune interruption .org 0FF0h ; Vecteur d'interruption CAN reti .org 0FF2h ; Vecteur d'interruption du timer reti .org 0FF4h ; Vecteur interruption port B reti .org 0FF6h ; Vecteur interruption port A reti .org 0FFCh ; Vecteur interruption NMI reti .org 0FFEh ; Vecteur de reset jp reset ;--------------------------------------------------------------------------- ; Table de données pour convertir l'octet en sortie du CAN, variant de 0 ; à 255, en un volume en litres, affiché sur les quatre digits. ; L'octet en sortie du CAN reflète la pression à la base de la cuve, qui ; varie linéairement avec la hauteur de liquide. ; Le volume à afficher en litres sur les quatre digits est fonction de ; la pression à la base, proportionnelle à la hauteur du liquide, mais ; est aussi fonction de la forme et des dimensions de la cuve. ; La table ci-dessous donne dans l'ordre les valeurs affichées pour des ; valeurs de CAN croissantes de 0 à 255, pour une cuve cylindrique d'une ; contenance de 3000 L, à axe horizontal, et mesurant 1.20 m de diametre. ; Les valeurs affichées tiennent sur deux octets, soit 4 quartets. ; L'assembleur inverse les deux octets des mots doubles, donc moi aussi, ; il n'y a pas de raison de se gêner: On a donc la disposition suivante: ; Le quartet de gauche est pour l'afficheur des dizaines, puis ; le quartet suivant pour les unités (litres), puis le suivant les ; milliers, et enfin à droite les centaines, ceci au niveau du ; programme assembleur, et en fait, en ROM, on aura dans l'ordre ; milliers, centaines, dizaines, unités. ; Le quartet contient la valeur binaire du chiffre à afficher (0 à 9) ; Exemple1: pour la valeur 7 du CAN, le nombre à afficher est 0023 Litres, ; et les quatre premiers quartets de la table sont 0010 0011 0000 0000 ; Exemple2: pour la valeur 254 du CAN, le nombre à afficher est 2998 L, ; et les quatre premiers quartets de la table sont 1001 1000 0010 1001 .org 0890h ; oct afficheur Tabvo .word 0000000000000000b ; 0 0000 .word 0000000100000000b ; 1 0001 .word 0000010000000000b ; 2 0004 .word 0000011000000000b ; 3 0006 .word 0001000000000000b ; 4 0010 .word 0001010000000000b ; 5 0014 .word 0001100000000000b ; 6 0018 .word 0010001100000000b ; 7 0023 .word 0010100000000000b ; 8 0028 .word 0011001100000000b ; 9 0033 .word 0011100100000000b ; 10 0039 .word 0100010100000000b ; 11 0045 .word 0101000100000000b ; 12 0051 .word 0101011100000000b ; 13 0057 .word 0110010000000000b ; 14 0064 .word 0111000100000000b ; 15 0071 .word 0111100000000000b ; 16 0078 .word 1000010100000000b ; 17 0085 .word 1001001100000000b ; 18 0093 .word 0000000100000001b ; 19 0101 .word 0000100100000001b ; 20 0109 .word 0001011100000001b ; 21 0117 .word 0010010100000001b ; 22 0125 .word 0011001100000001b ; 23 0133 .word 0100001000000001b ; 24 0142 .word 0101000100000001b ; 25 0151 .word 0110000000000001b ; 26 0160 .word 0110100100000001b ; 27 0169 .word 0111100000000001b ; 28 0178 .word 1000100000000001b ; 29 0188 .word 1001011100000001b ; 30 0197 .word 0000011100000010b ; 31 0207 .word 0001011100000010b ; 32 0217 .word 0010011000000010b ; 33 0226 .word 0011011100000010b ; 34 0237 .word 0100011100000010b ; 35 0247 .word 0101011100000010b ; 36 0257 .word 0110011100000010b ; 37 0267 .word 0111100000000010b ; 38 0278 .word 1000100100000010b ; 39 0289 .word 1001100100000010b ; 40 0299 .word 0001000000000011b ; 41 0310 .word 0010000100000011b ; 42 0321 .word 0011001100000011b ; 43 0333 .word 0100010000000011b ; 44 0344 .word 0101010100000011b ; 45 0355 .word 0110011000000011b ; 46 0366 .word 0111100000000011b ; 47 0378 .word 1001000000000011b ; 48 0390 .word 0000000100000100b ; 49 0401 .word 0001001100000100b ; 50 0413 .word 0010010100000100b ; 51 0425 .word 0011011100000100b ; 52 0437 .word 0100100100000100b ; 53 0449 .word 0110000100000100b ; 54 0461 .word 0111001100000100b ; 55 0473 .word 1000011000000100b ; 56 0486 .word 1001100000000100b ; 57 0498 .word 0001000000000101b ; 58 0510 .word 0010001100000101b ; 59 0523 .word 0011011000000101b ; 60 0536 .word 0100100000000101b ; 61 0548 .word 0110000100000101b ; 62 0561 .word 0111010000000101b ; 63 0574 .word 1000011100000101b ; 64 0587 .word 0000000000000110b ; 65 0600 .word 0001001100000110b ; 66 0613 .word 0010011000000110b ; 67 0626 .word 0011100100000110b ; 68 0639 .word 0101001000000110b ; 69 0652 .word 0110010100000110b ; 70 0665 .word 0111100100000110b ; 71 0679 .word 1001001000000110b ; 72 0692 .word 0000011000000111b ; 73 0706 .word 0001100100000111b ; 74 0719 .word 0011001100000111b ; 75 0733 .word 0100011000000111b ; 76 0746 .word 0110000000000111b ; 77 0760 .word 0111010000000111b ; 78 0774 .word 1000011100000111b ; 79 0787 .word 0000000100001000b ; 80 0801 .word 0001010100001000b ; 81 0815 .word 0010100100001000b ; 82 0829 .word 0100001100001000b ; 83 0843 .word 0101011100001000b ; 84 0857 .word 0111000100001000b ; 85 0871 .word 1000010100001000b ; 86 0885 .word 1001100100001000b ; 87 0899 .word 0001001100001001b ; 88 0913 .word 0010100000001001b ; 89 0928 .word 0100001000001001b ; 90 0942 .word 0101011000001001b ; 91 0956 .word 0111000000001001b ; 92 0970 .word 1000010100001001b ; 93 0985 .word 1001100100001001b ; 94 0999 .word 0001010000010000b ; 95 1014 .word 0010100000010000b ; 96 1028 .word 0100001000010000b ; 97 1042 .word 0101011100010000b ; 98 1057 .word 0111000100010000b ; 99 1071 .word 1000011000010000b ; 100 1086 .word 0000000100010001b ; 101 1101 .word 0001010100010001b ; 102 1115 .word 0011000000010001b ; 103 1130 .word 0100010000010001b ; 104 1144 .word 0101100100010001b ; 105 1159 .word 0111010000010001b ; 106 1174 .word 1000100100010001b ; 107 1189 .word 0000001100010010b ; 108 1203 .word 0001100000010010b ; 109 1218 .word 0011001100010010b ; 110 1233 .word 0100100000010010b ; 111 1248 .word 0110001000010010b ; 112 1262 .word 0111011100010010b ; 113 1277 .word 1001001000010010b ; 114 1292 .word 0000011100010011b ; 115 1307 .word 0010001000010011b ; 116 1322 .word 0011011100010011b ; 117 1337 .word 0101000100010011b ; 118 1351 .word 0110011000010011b ; 119 1366 .word 1000000100010011b ; 120 1381 .word 1001011000010011b ; 121 1396 .word 0001000100010100b ; 122 1411 .word 0010011000010100b ; 123 1426 .word 0100000100010100b ; 124 1441 .word 0101011000010100b ; 125 1456 .word 0111000100010100b ; 126 1471 .word 1000011000010100b ; 127 1486 .word 0000000100010101b ; 128 1501 .word 0001011000010101b ; 129 1516 .word 0011000000010101b ; 130 1530 .word 0100010100010101b ; 131 1545 .word 0110000000010101b ; 132 1560 .word 0111010100010101b ; 133 1575 .word 1001000000010101b ; 134 1590 .word 0000010100010110b ; 135 1605 .word 0010000000010110b ; 136 1620 .word 0011010100010110b ; 137 1635 .word 0101000000010110b ; 138 1650 .word 0110010100010110b ; 139 1665 .word 0111100100010110b ; 140 1679 .word 1001010000010110b ; 141 1694 .word 0000100100010111b ; 142 1709 .word 0010010000010111b ; 143 1724 .word 0011100100010111b ; 144 1739 .word 0101010000010111b ; 145 1754 .word 0110100000010111b ; 146 1768 .word 1000001100010111b ; 147 1783 .word 1001100000010111b ; 148 1798 .word 0001001100011000b ; 149 1813 .word 0010011100011000b ; 150 1827 .word 0100001000011000b ; 151 1842 .word 0101011100011000b ; 152 1857 .word 0111000100011000b ; 153 1871 .word 1000011000011000b ; 154 1886 .word 0000000100011001b ; 155 1901 .word 0001010100011001b ; 156 1915 .word 0011000000011001b ; 157 1930 .word 0100010000011001b ; 158 1944 .word 0101100100011001b ; 159 1959 .word 0111001100011001b ; 160 1973 .word 1000100000011001b ; 161 1988 .word 0000001000100000b ; 162 2002 .word 0001011000100000b ; 163 2016 .word 0011000100100000b ; 164 2031 .word 0100010100100000b ; 165 2045 .word 0101100100100000b ; 166 2059 .word 0111010000100000b ; 167 2074 .word 1000100000100000b ; 168 2088 .word 0000001000100001b ; 169 2102 .word 0001011000100001b ; 170 2116 .word 0011000000100001b ; 171 2130 .word 0100010000100001b ; 172 2144 .word 0101100000100001b ; 173 2158 .word 0111001000100001b ; 174 2172 .word 1000011000100001b ; 175 2186 .word 0000000000100010b ; 176 2200 .word 0001010000100010b ; 177 2214 .word 0010100000100010b ; 178 2228 .word 0100000100100010b ; 179 2241 .word 0101010100100010b ; 180 2255 .word 0110100100100010b ; 181 2269 .word 1000001000100010b ; 182 2282 .word 1001011000100010b ; 183 2296 .word 0000100100100011b ; 184 2309 .word 0010001000100011b ; 185 2322 .word 0011011000100011b ; 186 2336 .word 0100100100100011b ; 187 2349 .word 0110001000100011b ; 188 2362 .word 0111010100100011b ; 189 2375 .word 1000100000100011b ; 190 2388 .word 0000001000100100b ; 191 2402 .word 0001010000100100b ; 192 2414 .word 0010011100100100b ; 193 2427 .word 0100000000100100b ; 194 2440 .word 0101001100100100b ; 195 2453 .word 0110011000100100b ; 196 2466 .word 0111100000100100b ; 197 2478 .word 1001000100100100b ; 198 2491 .word 0000001100100101b ; 199 2503 .word 0001011000100101b ; 200 2516 .word 0010100000100101b ; 201 2528 .word 0100000000100101b ; 202 2540 .word 0101001000100101b ; 203 2552 .word 0110010000100101b ; 204 2564 .word 0111011000100101b ; 205 2576 .word 1000100000100101b ; 206 2588 .word 0000000000100110b ; 207 2600 .word 0001001000100110b ; 208 2612 .word 0010001100100110b ; 209 2623 .word 0011010100100110b ; 210 2635 .word 0100011000100110b ; 211 2646 .word 0101100000100110b ; 212 2658 .word 0110100100100110b ; 213 2669 .word 1000000000100110b ; 214 2680 .word 1001000100100110b ; 215 2691 .word 0000001000100111b ; 216 2702 .word 0001001100100111b ; 217 2713 .word 0010001100100111b ; 218 2723 .word 0011010000100111b ; 219 2734 .word 0100010000100111b ; 220 2744 .word 0101010000100111b ; 221 2754 .word 0110010100100111b ; 222 2765 .word 0111010100100111b ; 223 2775 .word 1000010100100111b ; 224 2785 .word 1001010000100111b ; 225 2794 .word 0000010000101000b ; 226 2804 .word 0001010000101000b ; 227 2814 .word 0010001100101000b ; 228 2823 .word 0011001000101000b ; 229 2832 .word 0100000100101000b ; 230 2841 .word 0101000000101000b ; 231 2850 .word 0101100100101000b ; 232 2859 .word 0110100000101000b ; 233 2868 .word 0111011000101000b ; 234 2876 .word 1000010100101000b ; 235 2885 .word 1001001100101000b ; 236 2893 .word 0000000100101001b ; 237 2901 .word 0000100000101001b ; 238 2908 .word 0001011000101001b ; 239 2916 .word 0010001100101001b ; 240 2923 .word 0011000000101001b ; 241 2930 .word 0011011100101001b ; 242 2937 .word 0100010000101001b ; 243 2944 .word 0101000000101001b ; 244 2950 .word 0101011000101001b ; 245 2956 .word 0110001000101001b ; 246 2962 .word 0110100000101001b ; 247 2968 .word 0111001100101001b ; 248 2973 .word 0111100000101001b ; 249 2978 .word 1000001100101001b ; 250 2983 .word 1000011100101001b ; 251 2987 .word 1001000100101001b ; 252 2991 .word 1001010100101001b ; 253 2995 .word 1001100000101001b ; 254 2998 .word 0000000000110000b ; 255 3000 ; Ci-dessous les codes à envoyer en série au MM 5450 (bit de poids ; faible en premier) pour affichage des différents chiffres sur les ; afficheurs sept segments. ; F F F F F ; E A ; E A ; E A ; G G G G G ; D B ; D B ; D B ; C C C C C ; Les huits bits d'un octet étant envoyés dans l'ordre suivant, ; (lié au câblage): DP c b g a f e d .org 0A90h ; defagbcP Tabdi .byte 11110110b ; code d'un 0 .byte 00010100b ; code d'un 1 .byte 10111010b ; code d'un 2 .byte 00111110b ; code d'un 3 .byte 01011100b ; code d'un 4 .byte 01101110b ; code d'un 5 .byte 11101110b ; code d'un 6 .byte 00110100b ; code d'un 7 .byte 11111110b ; code d'un 8 .byte 01111110b ; code d'un 9 ;--------------------------------------------------------------------------- ; Debut du programme ; initialisations .org 0B00h reset ldi wdr, knonos ; On calme le chien de garde ldi ddra,00000111b ; A7 à A4 inexistantes ldi ora, 00000111b ; A3 non connectée, entrée rappel ldi dra, 00000000b ; A2 A1 A0 sorties symétriques ldi ddrb,00000000b ; B7 6 5 4 2 1 N.C. entrée rappel ldi orb, 00001000b ; B3 entrée analogique ldi drb, 00001000b ; B0 entrée rappel ldi tcr, ktempo ldi tscr, 00011000b ; b7 passe à 1 si TCR passe à 0 ; b6 interdit interruptions par b7 ; b5 4 broche timer en entrée (+Vcc) ; b3 TCR valide si b5 à 1 (exact) ; b2 1 0: division par 1 ; soit 4.6864/(12*1)=360.49kHz 2.78us ret ; car niveau pile aléatoire à la ret ; mise sous tension ... ret ret ret ret clr pression ; pression mesurée clr cumul ; cumul poids faible pression clr boucle ; pour calcul pression clr temporl ; tempo décrémentée horloge MM 5450 clr tabluni ; octet des unités lu en table clr tabldiz ; octet des dizaines lu en table clr tablcen ; octet des centaines lu en table clr tablmil ; octet des milliers lu en table clr codeuni ; code des unités envoyé au MM 5450 clr codediz ; code des dizaines envoyé au MM 5450 clr codecen ; code des centaines envoyé au MM 5450 clr codemil ; code des milliers envoyé au MM 5450 ldi masque, 1 ; masquage pour sérialisation ldi numoct, 1 ; numéro octet à sérialiser ldi numbit, 1 ; numéro du bit envoyé au MM 5450 ldi flag1, 00000000b ; 8 drapeaux (cf allocation mem) ldi adcr, 00010000b ; Activation du CAN et reset ;--------------------------------------------------------------------------- ; Boucle principale tourne ldi wdr, knonos ; On calme le chien de garde call photo ; on prend une photo des 2 ports E/S call mespress ; mesure de la pression (niveau) call geststop ; gestion led STOP call lectable ; constitution 4 octets valeur digits call gencode ; genère les codes des 4 digits call testcode ; vérifie la validité des codes call digitoff ; extinction des chiffres inutiles call gest5450 ; dialogue avec le MM 5450 jp tourne ;--------------------------------------------------------------------------- ; Photographie des 2 ports E/S, pour éviter les problèmes de modification ; des configurations de ports lors de l'écriture d'une sortie photo ld a, dra ld ima, a ld a, drb ld imb, a ret ;--------------------------------------------------------------------------- ; Mesure de la tension image de la pression ; Pour augmenter la stabilité de l'affichage, la mesure est faite 256 fois, ; et on utilise la moyenne des 256 mesures. mespress clr cumul ; mise à 0 cumul poids faible press. clr pression ; mise à 0 poids fort pression ldi boucle, 255 ; prêt pour 256 tours mes00 ldi wdr, knonos ; on calme le chien de garde set 5, adcr ; on lance la mesure ADC mes01 jrr 6, adcr, mes01 ; on attend qu'elle soit terminée res 5, adcr ; CAN prêt pour mesure suivante ld a, adr ; on lit le résultat de la CAN add a, cumul ; cumul avec mesure précédente jrnc mes02 ; si retenue on incrémente pression inc pression mes02 ld cumul, a ; mise à jour du cumul ld a, boucle jrz mes03 dec boucle ; et bouclage tant que l'on a pas jp mes00 ; effectué 255 mesures mes03 ld a, cumul ; Histoire de perfectionner, on cpi a, 127 ; arrondi le résultat final au point jrc mes04 ; le plus proche (permet d'obtenir inc pression ; 255 si on avait tj 255 ...) mes04 ret ;--------------------------------------------------------------------------- ; Gestion de l'allumage de la led STOP ; ; 1) la led STOP est allumée si le contact du flotteur en haut de la cuve ; est ouvert, OU si la sortie du CAN est au dessus du seuil kvalisto. ; 2) La led STOP est éteinte si le contact du flotteur en haut de la cuve ; est fermé ET si la pression est en dessous du seuil kdevasto geststop jrr 0, imb, sto00 ; si contact ouvert, on allume la set 0, flag1 ; led STOP jp sto02 sto00 ld a, pression ; si pression supérieure au seuil cpi a, kvalisto ; kvalisto, on allume la led STOP jrc sto01 set 0, flag1 jp sto02 sto01 ld a, pression ; si contact fermé, et cpi a, kdevasto ; si pression inférieure au seuil jrnc sto02 ; kdevasto, on éteint la led STOP res 0, flag1 sto02 ret ;--------------------------------------------------------------------------- ; Lecture de la table principale, qui contient les valeurs de ; chacun des 4 digits, (codées sur 4 bits), pour les 256 ; valeurs possibles en sortie du CAN. ; ; Parenthèse: la mémoire ROM n'est accessible que via une fenêtre de 64 ; octets dans l'espace adressable par le micro. L'adresse du premier octet ; de la fenêtre est 0040h, et celle du dernier octet est 007Fh. ; ; On choisi le segment de ROM visible dans la fenêtre par le chargement ; préalable du registre Data Rom Window Register, l'adresse dans la ROM ; étant définie ainsi sur 12 bits: ; ; Adresse ROM 11 10 09 08 07 06 05 04 03 02 01 00 ; DRWR D5 D4 D3 D2 D1 D0 ; Adresse exécution 00 01 D5 D4 D3 D2 D1 D0 ; ; Ici la table contient des doubles octets, donc l'adresse s'incrémente de ; 2 en 2, et donc on a: ; ; Adresse ROM 11 10 09 08 07 06 05 04 03 02 01 00 ; DRWR D5 D4 D3 D2 D1 D0 ; Valeur pression 00 01 D4 D3 D2 D1 D0 00 ; î ; Ce 1 est là car la première ; adresse de la fenêtre est 64 ; D7 D6 D5 passés dans DRWR ; ; Ici Tabvo=0000 1 0 0 0 1 0 0 1 0 0 0 0b ; Soit ^0 ^ ^---8----^ ^----9---^ ^----0---^ = 0890h lectable ld a, pression ; A contient l'octet image de la rlc a ; pression. On ne garde que les 3 rlc a ; bits de poids fort: deviennent rlc a ; les 3 bits de poids faible du rlc a ; DRWR (Data Rom Window Register) andi a, 00000111b ; auquel on ajoute la valeur 22h, addi a, 22h ; pour obtenir au minimum l'adresse ld drwr, a ; 0000 1000 1001 0000b soit 0890h ; qui est celle de début de table ld a, pression ; A contient l'octet image de la ; pression. On ne garde que les 5 rlc a ; bits de poids faible, on multiplie andi a, 00111110b ; par deux (car table de mots de 16b) addi a, 01000000b ; on force deux trois trucs, et on ; envoie la sauce (adresse dans la ld x, a ; fenêtre), et miracle de la ld a, (x) ; technique, on obtient le premier ld tablmil, a ; octet FORT pointé dans la table. ld tablcen, a ; soit milliers et centaines inc x ; A table suite: le plat suivant est ld a, (x) ; le second octet, FAIBLE, soit ld tabldiz, a ; dizaines et unités ld tabluni, a ld a, tablmil rlc a rlc a rlc a rlc a rlc a andi a, 00001111b ld tablmil, a ld a, tablcen andi a, 00001111b ld tablcen, a ld a, tabldiz rlc a rlc a rlc a rlc a rlc a andi a, 00001111b ld tabldiz, a ld a, tabluni andi a, 00001111b ld tabluni, a ret ;--------------------------------------------------------------------------- ; Bon, maintenant il va falloir générer 4 octets qui seront envoyés en série ; au MM 5450: ces 4 octets doivent contenir les codes à envoyer aux quatre ; afficheurs pour afficher le nombre voulu: on utilise à nouveau une table, ; qu'on peut voir à travers notre petite fenêtre bien aimée. ; Cette table est à l'adresse ROM 0A90h (Tabdi) ; Tabdi = 0000 1 0 1 0 1 0 0 1 0 0 0 0b ; Soit ^0 ^ ^---A----^ ^----9---^ ^----0---^ = 0A90h ; Adresse ROM 11 10 09 08 07 06 05 04 03 02 01 00 ; DRWR D5 D4 D3 D2 D1 D0 ; Adresse exécution 00 01 D5 D4 D3 D2 D1 D0 gencode ldi a, 00101010b ; Pas la peine de faire des gros ld drwr, a ; calculs, on connait l'adresse Tabdi ; et on peut tout voir de la fenêtre ldi a, 01010000b ; On positionne a en début de fenêtre add a, tablmil ; et on ajoute la valeur du digit ld x, a ; On remplace cette valeur par son ld a, (x) ; code d'affichage, contenant des 1 ld codemil, a ; pour les segments allumés et des 0 ; pour ceux éteints ldi a, 01010000b ; On positionne a en début de fenêtre add a, tablcen ; et on ajoute la valeur du digit ld x, a ; On remplace cette valeur par son ld a, (x) ; code d'affichage, contenant des 1 ld codecen, a ; pour les segments allumés et des 0 ; pour ceux éteints ldi a, 01010000b ; On positionne a en début de fenêtre add a, tabldiz ; et on ajoute la valeur du digit ld x, a ; On remplace cette valeur par son ld a, (x) ; code d'affichage, contenant des 1 ld codediz, a ; pour les segments allumés et des 0 ; pour ceux éteints ldi a, 01010000b ; On positionne a en début de fenêtre add a, tabluni ; et on ajoute la valeur du digit ld x, a ; On remplace cette valeur par son ld a, (x) ; code d'affichage, contenant des 1 ld codeuni, a ; pour les segments allumés et des 0 ; pour ceux éteints ret ;--------------------------------------------------------------------------- ; Vérification de la validité des codes générés testcode ld a, codeuni ; Il suffit de tester les unités ; (Si problème, tout m... de part ; la loi de Murphy, et donc en ; particulier les unités). cpi a, 11110110b ; code d'un 0 jrz test01 cpi a, 00010100b ; code d'un 1 jrz test01 cpi a, 10111010b ; code d'un 2 jrz test01 cpi a, 00111110b ; code d'un 3 jrz test01 cpi a, 01011100b ; code d'un 4 jrz test01 jp test02 ; Petite bidouille à cause des ; déplacements courts (5 bits). test01 jp test03 test02 cpi a, 01101110b ; code d'un 5 jrz test03 cpi a, 11101110b ; code d'un 6 jrz test03 cpi a, 00110100b ; code d'un 7 jrz test03 cpi a, 11111110b ; code d'un 8 jrz test03 cpi a, 01111110b ; code d'un 9 jrz test03 jp reset test03 ret ;--------------------------------------------------------------------------- ; Extinction des digits inutiles digitoff set 4, flag1 ; On valide les digits milliers, set 5, flag1 ; centaines, dizaines (unités set 6, flag1 ; toujours validées) ld a, codemil ; Faut-il éteindre le digit des cpi a, 11110110b ; milliers ? Oui si zéro jrnz digi01 ; Toujours ce pbm de petits sauts res 4, flag1 jp digi02 digi01 jp digi03 digi02 ld a, codecen ; Faut-il éteindre les centaines cpi a, 11110110b ; Oui si zéro (et mille zéro) jrnz digi03 res 5, flag1 ld a, codediz ; Faut-il éteindre les dizaines cpi a, 11110110b ; Oui si zéro et milliers = 0 et jrnz digi03 ; centaines = 0 res 6, flag1 digi03 ret ;--------------------------------------------------------------------------- ; Discussion endiablee avec le MM 5450N gest5450 clr numbit inc numbit ldi masque, 1 ; Masque passe à 1 (pour la suite) ldi numoct, 1 ; Octet à envoyer = premier (idem) ges00 ld a, numbit ; Si c'est le premier bit qu'il faut cpi a, 1 ; envoyer au MM 5450, alors ne jrnz ges01 ; cherchez plus, c'est un 1. set 2, flag1 ; Data MM 5450 = 1 jp ges11 ges01 ld a, numbit ; Si c'est le bit 34, alors on envoie cpi a,34 ; l'état de la led STOP (en Q33) jrnz ges02 ; Sinon on passe à la suite res 2, flag1 ; On met à zéro jrr 0, flag1, ges01A ; et s'il fallait mettre à 1 set 2, flag1 ; on le fait, sans se fâcher ges01A jp ges11 ges02 ld a, numbit ; Si c'est le bit 35, alors on envoie cpi a,35 ; aussi l'état de la led STOP car jrnz ges03 ; les broches 33 et 34 sont reliées res 2, flag1 ; ensemble, pour obtenir plus jrr 0, flag1, ges02A ; d'intensité. set 2, flag1 ges02A jp ges11 ges03 ld a, numbit ; Si c'est le bit 36, alors on envoie cpi a,36 ; un 0 car la broche Q35 n'existe pas jrnz ges04 ; sur le MM 5450 res 2, flag1 jp ges11 ; prépare l'éternel recommencement. ; Bon, maintenant, on sait que ce n'est ni le bit 1, ni 34, 35, 36, ; alors au boulot! ges04 ld a, numoct ; Il s'agit maintenant de cpi a, 1 ; sérialiser les quatre octets jrnz ges05 ; préparés dans la routine lectable ld a, codeuni ; pour envoi sur la ligne Data MM5450 set 7, flag1 ; unités toujours affichées jp ges08 ; (= voyant présence tension) ges05 ld a, numoct ; Il doit y avoir un moyen plus cpi a, 2 ; simple, mais cette méthode un peu jrnz ges06 ; lourde marche. ld a, codediz ; Second octet envoyé = dizaines set 7, flag1 ; On valide ou non l'envoi des jrs 6, flag1, ges05A ; segments du digit, selon que le res 7, flag1 ; digit est validé ou pas ges05A jp ges08 ges06 ld a, numoct ; Troisième octet envoyé = centaines cpi a, 3 ; jrnz ges07 ; ld a, codecen set 7, flag1 ; On valide ou non l'envoi des jrs 5, flag1, ges06A ; segments du digit, selon que le res 7, flag1 ; digit est validé ou pas ges06A jp ges08 ges07 ld a, codemil ; Quatrieme octet envoyé set 7, flag1 ; = milliers jrs 4, flag1, ges08 ; segments alumé ou non, selon que le res 7, flag1 ; digit est validé ou pas ges08 and a, masque ; masque valant successivement jrnz ges09 ; 1, 2, 4, 8, 16, 32, 64, 128, et si res 2, flag1 ; le résultat est 0 on envoie 0 jp ges10 ges09 res 2, flag1 ; D'abord on éteint, après on cause jrr 7, flag1, ges10 ; Sinon on envoie 1, si le segment set 2, flag1 ; est validé seulement ges10 ld a, masque ; On fait tourner le 1 du masque rlc a ; vers la gauche res 0, a ; cas ou une retenue trainait ld masque, a jrnz ges11 ; Si le 1 tombe dans la retenue ldi masque, 1 ; on en remet un et on passe a inc numoct ; l'octet suivant ges11 call tictac inc numbit ld a, numbit cpi a, 37 jrz ges12 jp ges00 ges12 ret ;--------------------------------------------------------------------------- ; Gestion de l'horloge du MM 5450 tictac set 1, flag1 call bouge tic00 ldi temporl, ktemporl ; On recharge la tempo horloge tic01 call gesttemp ld a, temporl jrnz tic01 tic02 res 1, flag1 call bouge ret ;--------------------------------------------------------------------------- ; Gestion du temps qui passe gesttemp jrs 7, tscr, tem00 ; si la base n'est pas passée jp tem02 ; on attend tem00 ldi wdr, knonos ; On calme le chien de garde ldi tcr, ktempo ; on recharge le tcr pour suivant res 7, tscr ; on rabaisse le drapeau tem01 ld a, temporl ; tempo gestion horloge MM 5450 jrz tem02 ; jusqu'a zéro, ou elle reste dec temporl tem02 ret ;--------------------------------------------------------------------------- ; écriture du port à avec forcage des registres d'entrée non ; pas à la valeur relue, mais à la valeur de configuration ; Le port B étant entierement en entrée n'est pas réécrit. bouge clr ima ; RAZ Horloge, Data, Enable jrr 1, flag1, bou01 ; Positionnement Horloge MM 5450 set 0, ima bou01 jrr 2, flag1, bou02 ; Positionnement Data MM 5450 set 1, ima bou02 ld a, ima ; on réécrit le port E/S ld dra, a ; afin de positionner les sorties ret ;--------------------------------------------------------------------------- Vous pouvez bien sûr faire un copier/coller vers votre éditeur habituel !