;********************************************************************** ; This file is a basic code template for assembly code generation * ; on the PICmicro PIC16F84. This file contains the basic code * ; building blocks to build upon. * ; * ; ; * ; Template file assembled with MPLAB V3.99.18 and MPASM V2.15.06. * ; * ;********************************************************************** ; ; Filename: AEVM2.asm Allumage cartographique ; Date:15 Octobre 2002 version multi moteurs, 2 temps et 4 temps Ph Loutrel ;Pour moteurs 4 temps de 1,2,4,5,6,8 cylindres et 2 temps de 1,2,3,4 cylindres ;OK pour prog de saisie AECOURBE V1 pour 4 cylindres seulement ;Utilise NCYL mis par GENTVm1 dans LTABLE ;ATTENTION! utiliser OBLIGATOIREMENT GENTVM1k pour generer la courbe d'avance ; Principe de cette version multimoteurs: ;Les tables de delai D d'allumage (fonction de T) saisies avec GENTVM1 restent identiques ;Mais à 6000t/mn, par ex, le PIC mesurera T=5ms pour un 4 cyl et 2.5ms pour un 8 cyl ;Comme D (l'avance ) est independante du nb de cylindres, il faut X2 la periode T ; avant d'aller lire D. D'où les modifs apportées dans la sub EXTRACT_D qui selon NCYL ;va corriger T avant d'extraire D ; Nota: ;Toutes les vitesses de rotation et degrès sont pour ; l'ALLUMEUR, c'est a dire N moteur/2, degrés poulie vilo/2 ;PAR DEFAUT: Avance 0° de 0 à 366 t/mn(732 t/mn moteur) ; Sinon en mettant 16 ci-dessous, avance de11°2(poulie moteur) #DEFINE MOT d'13' ;13 pour 1300 0° d'avance de 0 à 732t/mn moteur ;16 pour 1600S 11°2 d'avance de 0 à 732t/mn moteur ; ; ATTENTION:Il doit exister un dossier C:\AEPL sur le disque C ; dans lequel le programme GENTVxx a généré les deux ; tables : 0ltab.txt et 0htab.txt avant d'assembler le ; programme qui suit ; ; IMPORTANT:Calage de l'avance statique sur poulie moteur: 45° pour tout NCYL ; ; ; RAPPEL DE QQ MNEMONICS ; bsf bit set file ad,N° du bit ; movlw move litteral to w litteral de 1 Byte,w Working register ; movwf move w to file ; bcf f,n bit clear file ,bit n ; clrf raz de file ; btfss bit test file and skip next inst if set (bit=1) ; btfsc bit test file and skip next inst if cleared (bit=0) ; incfsz increment file and skip if result is 0,flag Z=1 ; ; ; Page 0 0-FF, P1 100-1FF, P2 200-2FF, P3 300-3FF ; ; Temps d'execution: 1µs(ou mus) sauf 2µs pour CALL,GOTO,RETURN ; et BTFSC(S) qd le SKIP est execute (quartz à 4 Mhz) ; ; ;********************************************************************** list p=16F84 ; list directive to define processor #include ; processor specific variable definitions __CONFIG _CP_OFF & _WDT_OFF & _PWRTE_ON & _XT_OSC ;Cette ligne génère le MOT DE CONFIGURATION en h2007=3FFA qui n'apparait pas ;sur le listing de code objet mais est généré par l'assemleur ds la dernière ;ligne du fichier .HEX ;Pas deprotection du code:3FF b13-4=1 ;Pas de Watchdog b2=0 ;Pas de Power up Timer Enable b3=1 ;Oscillateur quartz Hi Speed (4 à 20 Mhz) b1=1,b0=0 ; '__CONFIG' directive is used to embed configuration data within .asm file. ; The lables following the directive are located in the respective .inc file. ; See respective data sheet for additional information on configuration word. ;************ Les VARIABLES**************** cblock h'20' ;Dans la memoire RAM DA_H DA_L ;Delai Ancien en u=10µs TR_H ;Temps Restant entre etincelle et vis ouvertes TR_L ;en u de 10µs T_H ;Periode entre deux vis ouvertes T_L ; MOT_ART ;flag set si moteur arrete D_H ;Delai theorique pour etincelle, u D_L DP_H ;Delai Pratique pour etincelle = D-TC DP_L CS ;Carry Storage pour calcul de T CT_H ;Copie de T CT_L ; TS4_H ;stock T/4 pendant l'extraction de D TS4_L ; TS16 ;stock T/16 ou /32 TS16_H ; SEUIL ;Stockage du seuil de coupure allumage u=10, ;ex h70 pour 3500 t/mn(c'est le négatif en hexa) TS2_H ;stock T/2 TS2_L REDL ;Flag de ligne rouge 0 si OK,sinon -1 (ds EXTRACT_D) NCYL ;Reçoit le nb de cylindres saisi par GENTV TC ;Temps de calcul ajusté selon NCYL endc ;************** Les CONSTANTES******************** TC4 equ d'11' ;Temps de calcul 11 u de 10µs pour 4 cylindres LTABLE equ h'200' ; Table des delais basse vitesse 367-1500 rpm HTABLE equ h'300' ; Table des delais haute vitesse 1500-5000 rpm ; générées au préalable par GENTAB.bas ;********************************************************************** START ORG 0 ; processor reset vector MEM FLASH(0-3FF) ;soit 1024 mots de 14 bits goto MAIN ; go to beginning of program MAIN ;Initialization bsf status,RP0 ;Switch to Bank 1(set bit 5 de Status(adr 03)) movlw b'00010000' ;Make RA4 INPUT (hardware pin3) 1 for 1nput ;et RA0 OUTPUT(harware pin 17) 0 for 0utput movwf TRISA bcf STATUS,RP0 ;Switch back to Bank 0 Reset bit de Status clrf PORTA ;raz les entrees call OUTPUT_ON ;Coupe le courant dans la bobine ;jusqu'au premier front donc pas de courant dans la ;bobine qd le moteur est arrété call REDCYL ;Aller dans LTABLE lire la ligne rouge(SEUIL) et NCYL clrf DA_H ;Initialise DA pour le premier tour clrf DA_L clrf MOT_ART ;Clear flag Moteur arrete btfsc PORTA,4 ;Skip si bit =0 goto $-1 ;bit = 1 vis ouvertes btfss PORTA,4 ;Skip si bit =1 goto $-1 ;bit = 0 vis fermees clrf TR_H ;vis ouvertes, c'est le premier front clrf TR_L ;la premiere fois, TR=0, waitfront ;sauf la première fois,une etincelle vient ;d'etre maintenue 1 ms ;attendre le prochain front(ouverture vis) stillop ;Attendre 1u = 10microsecondes d'ici a B call INCTR ;ajouter 1 a TR btfsc MOT_ART,0 ;Si ce b0=0, moteur en marche goto START ;b0=1, moteur arrete, on redemarre tout btfsc PORTA,4 ;lire les vis, bit set qd vis ouvertes goto stillop ;bit = 1, encore ouvertes B closed ;bit = 0, vfermees Attente 1u=10mus d'ici a D call INCTR btfsc MOT_ART,0 ;Si ce b0=0, moteur en marche goto START ;b0=1, moteur arrete, on redemarre tout btfss PORTA,4 ;lire les vis*****************Debut de calcul de TC 2mu goto closed ;bit = 0 ,vis fermees D ;bit = 1, les vis viennent de s'ouvrir call COMPUTE_T ;T = D + TR periode entre 2 vis ouvertes 2+15mu ;Breakpoint T ds T_H, T_L btfsc MOT_ART,0 ;B1 si ce b0=0, moteur en marche 2 goto START ;moteur arrete call EXTRACT_D ;Get D dans une des 2 tables 2+43 ;Breakpoint T ds CT_H,CT_L et D dans D_H,D_L call COMPUTE_DP ;B2 DP = D - TC 2+6 call WAIT_DP ;Attendre avant etincelle incfsz REDL,w ;Si trop vite ce flag=-1 goto $+2 ; Régime OK goto nospark ;Trop vite, pas d'étincelle ;Breakpoint. La fenetre STOPWATCH affiche le temps call OUTPUT_ON ;B3 etincelleOK**********************Fin de calcul de TC nospark call UPDATE_DA_TR ; call OUTPUT_OFF ;attend 1ms avant de couper goto waitfront ;END MAIN::::::::::::::::::::::::::::::::::::::::::::::::::: REDCYL ;SUB pour lire SEUIL et NCYL movlw 1 ;Aller dans LTABLE chercher le SEUIL (negatif) ;de ligne rouge bcf pclath,0 ;LTABLE est la page 2(en h200) bsf pclath,1 ;donc PCLATH =2 call LTABLE movwf SEUIL ;stocker dans SEUIL movlw 2 ;Aller dans LTABLE chercher NCYL call LTABLE movwf NCYL ;stocker le nombre de cylindres movf NCYL,f ;si =0, mettre 4 btfss STATUS,Z goto $+3 ;diff de 0, ne rien faire movlw 4 movwf NCYL ;0 donc initialiser à 4 pour 4 cylindres movlw TC4 ;Initialiser TC pour 4 cylindres movwf TC movlw -d'4' ;4 cyl ? addwf NCYL,w btfsc STATUS,Z ;Si Z=1 on a 4 cyl return ;donc 4 cyl incf TC,f ;+1 si 8 cylindres movlw -d'8' addwf NCYL,w btfsc STATUS,Z return ;donc, 8 cyl incf TC,f ;+3 pour 6,5,2,1 cyl incf TC,f incf TC,f return ;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: INCTR ;SUB compteur d'u pour TR. Elle incremente TR 2mus incfsz TR_L,f ;ajoute 1 a TR_L, si passe a 0 (Z=1), 256 passages donc return ;Z=0, incfsz TR_H,f ;ajouter 1 a TR_H. Si overflow, moteur arrete return ;moteur tourne bsf MOT_ART,0 ;moteur arrete, set bit 0 de MOT-ART return ;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: COMPUTE_T ;SUB de calcul de periode.Elle garnit T=D + TR 15mus ;double precision clrf CS ;RAZ de Carry Storage movfw DA_L addwf TR_L,w ;DA_L + TR_L ds w movwf T_L ;le tout ds T_L btfsc STATUS,C ;si C=0, pas de carry a ajouter aux bytes _H bsf CS,0 ;C=1, l'enregistrer ds CS movfw DA_H ;Ajouter les _H dans ts les cas addwf TR_H,w movwf T_H btfsc STATUS,C ;C=0,OK mais reste a ajouter CS goto A ;C=1,deja un overflow addwf CS,w ;C=0 ,ajouter CS=0 ou 1 au total movwf T_H ;et le mettre de T_H btfss STATUS,C ;C=1, overfow return ;C=0,OK A bsf MOT_ART,0 ;overflow donc moteur arrete return ;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: EXTRACT_D ;SUB de calul de Delai avant etincelle ;Garnit D_H et D_L a partir de T (detruit,copié ds CT) movfw T_H ;Sauver T dans CT movwf CT_H movfw T_L movwf CT_L ;On va ajuster T (si NCYL<> 4) pour extraire D movlw -d'4' addwf NCYL,w btfsc STATUS,Z ;Z=1 si 4 cyl goto allc ;Z=1, 4 cyl, T n'est pas à ajuster movlw -d'8' ;tester si 8 cyl addwf NCYL,w btfss STATUS,Z ;Z=1 si 8 cyl goto txc ;cas des 6,5,2,1 cyl bcf STATUS,C ;8 cyl, RAZ de C pour calcul de T*2 rlf T_L,f ;b7 de L dans C rlf T_H,f ;puis dans b0 de H goto allc ;T a été X2 pour aller lire D txc ;Cas de 6,5,2,1 cyl ;calcul et stockage de T/2 puis de T/4 ;T va etre divisée par 2 bcf STATUS,C ;C=0 rrf T_H,f ;b0 de T_H ds C, b7 de T_H=0 rrf T_L,f ;b0 de T_H en pos 7 de T_L, T/2 ds T movfw T_H movwf TS2_H movfw T_L movwf TS2_L ;sauver T/2 bcf STATUS,C ;on recommence pour T/4 rrf T_H,f ; rrf T_L,f ; movfw T_H ;sauver T/4 movwf TS4_H movfw T_L movwf TS4_L t6c movlw -d'6' addwf NCYL,w btfss STATUS,Z goto t5c ;pas un 6 cyl movfw CT_L ;6 cyl, calcul de T+T/2= 3/2T pour aller lire D addwf TS2_L,w ; movwf T_L btfsc STATUS,C ;si carry incf TS2_H,f ; oui, ajuster H movfw CT_H addwf TS2_H,w movwf T_H goto allc t5c movlw -d'5' addwf NCYL,w btfss STATUS,Z goto t2c ;pas un 5 cyl movfw CT_L ; 5 cyl, calcul de T+T/4 pour aller lire D addwf TS4_L,w movwf T_L btfsc STATUS,Z incf TS4_H,f ;carry movfw CT_H addwf TS4_H,w movwf T_H goto allc t2c movlw -d'2' addwf NCYL,w btfss STATUS,Z goto t1c ;monocylindre movfw TS2_L ;2 cyl, preparer T/2 pour aller lire D movwf T_L movfw TS2_H movwf T_H goto allc t1c movfw TS4_H ;Monocylindre, preparer T/4 pour aller lire D movwf T_H movfw TS4_L movwf T_L allc ;T est maintenant ajustée pour le nb de cylindres clrf REDL ;verifier regime autorisé movfw T_H ;Au dela du régime maxi? 1 addlw -1 ; 1 btfss STATUS,Z ;si T_H = 1, Z=1, continuer test 1 goto spk ;T_H > 1, on est en dessous du maxi 2 movf T_L,w ;Z=1,test si T_L 0 movf T_H,f ;Astuce:bouge sur place :update Z btfss STATUS,Z ;test pour T_H =0 goto TBV ;Z=0 donc T_H <>0 T>4096, N < 367t/mn, 0 deg avance movfw T_L ;Z=1,donc T_H=0,T < 4096, N>366 t/mn addlw -d'62' ;ligne 62 mini de LTABLE N=1500t/mn(ligne 255 N=367) btfsc STATUS,C goto lrpm ;C=1, donc T_L>=62, aller ds LTABLE avec T/16 hrpm movfw TS4_L ;C=0, donc T_L<62, aller dans HTABLE avec T/4 bsf pclath,0 ;B2=1,courbe normale.Astuce pour Prog Counter en h300 bsf pclath,1 ;PCLATH = 3 Page 3 addlw -1 ;correction pour début de table ;Breakpoint.No de ligne de HTABLE ds w call HTABLE ;B4 on entre ds la table des hirpm avec T/4 movwf D_L ;on revient avec D (0-255) dans w clrf D_H return ; delai pour cette sub 43µs lrpm addlw d'62' ;restituer T/16 bcf pclath,0 ; Astuce pour Prog Counter en h200 bsf pclath,1 ;PCLATH = 2 addlw -1 ;correction pour début de table call LTABLE ;B5 Breakpoint.No : Entre ds LTABLE avec T/16 movwf D_L ;on revient avec D (0-255) dans w bcf STATUS,C ;il faut X D_L par 4. Clear C clrf D_H ;RAZ de D_H pour injecter des 0 ds C lors des rotations rlf D_L,f ;Rotate Left donc D_LX2, et b7 de D_L ds C rlf D_H,f ;b7 ds D_H, 0 ds C DX2 rlf D_L,f ;D_L X4, b6 ds C rlf D_H,f ;b6 ds D_H, 0 ds C DX4 return ; ds D on a la valeur du delai pour low rpm 49µs TBV movlw -d'16' ;tester si 1600S addlw MOT btfss STATUS,Z ;Si Z=1, 1600 goto TBV13 movfw TS16 ;R267N<367 t/mn,avance 5°6 (T/16).Grace à 22.5 deg d'avance statique addwf D_L,f ;il suffit de D=T/8+T/16=3T/16 pour avance 5°6 (D contenait T/8) btfsc STATUS,C incf D_H,f ;C=1, l'ajouter au future resultat movfw TS16_H addwf D_H,f return ;sortir, avec D à jour TBV13 movfw TS4_H ;N<367 t/mn,avance 0 deg.Grace à 22.5 deg d'avance statique movwf D_H ;il suffit de D=T/4 (22.5 = 90/4) pour avance 0 deg movfw TS4_L ; movwf D_L return ;sortir avec D à jour ;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: COMPUTE_DP ;SUB de calcul de delai pratique.Garnit DP 6mus movfw D_H ;recopier le Byte de poids fort movwf DP_H movfw TC ;temps de calcul subwf D_L,w ;D_L - TC ds w movwf DP_L ;et enfin ds DP_L btfsc STATUS,C ; Si Carry=0 D_L <= TC, agir return ;C=1 rien a faire movlw h'ff' ;C=0, retirer 1 a DP_H addwf DP_H,f return ;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: OUTPUT_ON ;SUB Met output bit RA0 (pin 17) à haut 3µs bsf PORTA,0 ;niveau haut pour etincelle,coupe le courant ds bobine return ;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: OUTPUT_OFF ;SUB Met output bit RA0 (pin 17) à bas 1004µs movlw d'250' ;attendre 1ms = 250X4mus K addlw -1 ; 1mus btfss STATUS,Z ; 1 goto K ; 2 bcf PORTA,0 ;RA0 (pin 17) à bas, rétablit le courant ds bobine return ;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: WAIT_DP ;SUB Attente avant emission de l'etincelle nop ;1u=10mus d'ici a F nop nop nop ; 7mus nop nop nop decfsz DP_L,f ;dec DP_L tant que non zero 1 goto WAIT_DP ; F 2 bcf STATUS,Z ;clear flag movf DP_H,f ;update Z flag,test si DP_H =0 (pseudo mov) btfsc STATUS,Z ;si DP_H =0, Z=1 return ; oui, fini decf DP_H,f ; non, dec DP_H goto WAIT_DP ;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: UPDATE_DA_TR ;SUB ajuste le Delai Ancien.Garnit DA et TR movf D_L,w ;DA = le delai juste utilisé movwf DA_L movf D_H,w movwf DA_H movlw d'100' ;on a maintenu l'etincelle pendant 1 ms movwf TR_L ;donc 100 unites de 10mus clrf TR_H ;Dans TR pour demarrer le calcul de T return ;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: LTABLE org h'200' ;Table des delais N =367 - 1500 t/mn(0° avant,soit T/4) addwf PCL,f ;sauter au bon endroit h34=opcode pour RETLW INCLUDE c:\aepl\0ltab.txt ;ici la LTABLE préalablement générée par le prog. gentab.bas ;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: HTABLE org h'300' ;Table des delais N =1500 - 5000 t/mn addwf PCL,f ;sauter au bon endroit h34=opcode pour RETLW INCLUDE c:\aepl\0htab.txt ;ici la HTABLE préalablement générée par le prog. gentab.bas END ; directive 'end of program':::::::::::::::::::::::::::::::::::::::::::::