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 !