; Pic 16F88 Unité 8µs HS oscillator en _CONFIG indispensable!! ;24/7/6 Avec decalage de courbe ;Peut simuler une IT toutes les lTSIM millisecondes ;Filename: 88TCF2.asm Allumage cartographique philippe.loutrel@laposte.net ;**********Allumage moteur 4 cyl avec allumeur et bobine classique ou ;sans distributeur, avec deux bobines jumeau-statiques (jumo) ;Dans ce cas, ;il faut UNE SEULE palette en bout de vilo(capteur Hall) pour cyl 1 et 4 ;l'etincelle intermediaire (cyl 2 ou 3) est générée par soft ;Sait recevoir les tables L et T d'un PC par la liaison serie et les envoyer au PC ; Logiciel de type OPTIAEx (ou OAxxxx) necessaire sur le PC ;Test si un car reçu du PC après chaque etincelle ;Le PC attend le car "P" venu du ¨Pic pour traiter 512 car puis restart ;IMPORTANT!! ;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx ;Pour QBASIC, il faut relier DTR et DSR (pin 4 et 6 ) sur la prise RS232 ;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx ;XXXXXXXXXXXXXXXXavec PICDEM+, connecter RB2surRC7 et RB5sur RC6 pour Tx et RX ;Effacement de 32 mots: 210µs soit 3.85ms pour 512 mots. Ecriture de 4 mots :130µs ;Avec TchR(alenti) à TBV et utilisé ds ltab i.e. N<=3750t/mn mot ;Avec protec bobine: ; pin 18 relièe au transistor PNP qui(sans PIC) clamp à la masse ;les deux gates(protection bob) ;Qd le PIC execute ce prog, pin 18 = +5V ;ce qui bloque le PNP et libère les deux gates de la masse ;Tout ceci pour permettre l'utilisation des bobines à faible resistance ( < 3 ohms) ;Traitement special démarrage : saute les premières étincelles (valeur lNOet) ; Le temps de charge des bobines est FIXE, par ex 3ms, géré par TMR1, AVEC CONTEXTE ;c'est à dire que l'on tient compte de l'acceleration (ou deceleration) pour calculer ;l'instant de recharge de la bobine. Voir la SUB SET_TMR1 qui attend ;T8-Tch +(T8-T8prec) Le terme correctif, entre parenthèses, est nul ;à vitesse constante, négatif en accel(car T8< T8prec), positif en deceleration ;Concrètement, en acceleration, on declenche plus tôt la recharge de la bobine ; #DEFINE OPTI 1 ; 0 AEPL classique, 1 relié à un PC pour optimisation #DEFINE lJUMO 0 ; 0 pour bobine normale(vis ou 2 palettes) ; 1 pour 2 bobines jumo (1 seule palette) #DEFINE MOT d'16' ;13 ou 16 ; Avance 0° de 0 à 914t/mn moteur si MOT=13 ; Avance 11°25 de 0 à 914t/mn moteur si MOT=16 #DEFINE lTSIM 0 ;0 normalement sinon T simulée en ms #DEFINE lTCH_H d'1' ;durée de charge en u de 8 µs #DEFINE lTCH_L d'119' ; 256+119=375 375X8=3ms #DEFINE lTCHR_H d'2' ;durée de charge en u de 8 µs N <3750 t/mn moteur #DEFINE lTCHR_L d'238' ; 512+238=750 750X8µs=6ms C'est un MAXI! #DEFINE lNOet 5 ;saute (cette valeur)-1 étincelles au démarrage #DEFINE Bob_14 PORTA,0 ;pin 17 #DEFINE Bob_23 PORTB,4 ;pin10 #DEFINE TX PORTB,5 ;emission vers USART, pin 11 #DEFINE RX PORTB,2 ;reception venant de l'USART, pin 8 ; ; ; ATTENTION:Il doit exister un dossier C:\AEPL sur le disque C ; dans lequel le programme ; 8GENTCF1.bas (ou exe) (ou OPTIAEx ou OAxxxx) ; a généré les DEUX tables : 8ltab.txt , 8htab.txt avant d'assembler ce ; programme ; ;XXXXXXXXXXXXXXXXXX IMPORTANT:Avance statique sur poulie moteur: 45°XXXXXXXXXXXXXXXXX ;********************************************************************** list p=16F88 ; list directive to define processor #include ; processor specific variable definitions ;Program Configuration Register 1 PIEGE sur 16F88: il FAUT _HS_OSC meme à 4MHz!!! __CONFIG _CONFIG1, _CP_OFF & _CCP1_RB0 & _DEBUG_OFF & _WRT_PROTECT_OFF & _CPD_OFF & _LVP_OFF & _BODEN_OFF & _MCLR_ON & _PWRTE_ON & _WDT_OFF & _HS_OSC ;Program Configuration Register 2 __CONFIG _CONFIG2, _IESO_OFF & _FCMEN_OFF ;Mclr_on= habituel( =off connection interne du reset à Vdd, Mclr devient RA5). CCP_RB0, RB0 est l'entrée du module COMPARE. SURTOUT oscllateur HS,bug avec XT! ERRORLEVEL -302 ; VARIABLES ; cblock h'20' ;Dans la memoire RAM w_temp ; variable used for context saving status_temp ; variable used for context saving Front ;Flag = 1 qd front montant (45° avant PMH) T_H ;T =Periode entre deux fronts T_L ;unité de T = 8µs D_H ;Delai theorique pour etincelle, u=8µs, après front D_L CT_H ;Copie de T CT_L TS4_H ;stock T/4 pendant l'extraction de D TS4_L TS16 ;stock T/16 TS16_H ;uniquement pour N<457 t/mn JUMO ;reçoit lJUMO GEN_H ;pour attente ds SUB WAIT_GEN GEN_L T8_H T8_L ;periode en u de 8µs, pour TIMR1 T8PREC_H ;pour contexte T8PREC_L Bobi ;1 pour bob 1,4 0 pour bob 2,3 TBVF ;flag pour très basses vitesses, N<914t/mn moteur NOet_14 ;nb d'étincelles sautées au démarrage NOet_23 CARPC ;car venu du PC OPTF ;flag pour optimisation TMP N32 CPT ;compteur de 1 à 4 ecrit Flash TI_H TI_L ;pour calcul du delai de charge TCHR ;flag pour utiliser TchR et non Tch jusqu'à 3750t/mn DELF ;flag pour mode decalage DEL ;valeur du decalage en u de 8µs TSIM ;periode de simulation en ms SIMF ;flag de simulation DEBRAM ;4 car de stockage avant ecriture en Flash ; Attention, rien ici car il faut reserver 4 car!! endc cblock h'A0' ;comme on utilise les bk 2 et 3 bidon ; peut recevoir w, idem w_temp, après IT endc ; VALEURS NUMERIQUES lTC equ d'14' ; temps de calcul fixe TC en u (8µs) lTC1 equ d'14' ; correction pour étincelle Bob 23 lTCdel equ d'6' ;correction tmps de calcul de decalage 48µs LTABLE equ h'200' ; Table des delais basse vitesse 457-1875 rpm HTABLE equ h'300' ; Table des delais haute vitesse >1875 rpm ; générées au préalable par 68GENxx(.bas ou .exe) B9600 equ d'25' ;baud generator 9600bps ;********************************************************************** start ORG 0 goto Main ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ISR ORG h'04' ;Interrupt Service Routine(Front, Tmr1 et Tmr0) movwf w_temp ;Save context. First w swapf STATUS,w ;twist STATUS clrf STATUS ;garantit bk0 movwf STATUS_TEMP ; and save it btfss PIR1,TMR1IF ;BR Le bit d'IT d'overflow de Tmr1 est à 1? goto k2 ;non, bsf Bob_14 ;oui, toutes les 65536*8µs= 0.52s bsf Bob_23 ;couper les deux bob, moteur arrété bcf PIR1,TMR1IF ;clear l'IT sinon retour immédiat goto Finit k2 btfss PIR1,CCP1IF ;le front sur RB0 a declenché l'IT du module CCP? goto k3 ;non movfw CCPR1H movwf T_H ;sauver T. movfw CCPR1L movwf T_L bsf FRONT,0 clrf TMR1H ;clear TMR1 clrf TMR1L bcf PIR1,CCP1IF Finit swapf STATUS_TEMP,w;Restore context Untwist STATUS movwf STATUS swapf w_temp,f ;Twist twice since w was stored untwitesd! swapf w_temp,w RETFIE ;Retour active GIE k3 bcf INTCON,TMR0IE;disable IT de TMR0, sera remise par sub SET_TMR0 btfss BOBI,0 ;donc c'est TMR0, pour recharge goto k4 call ION_14 ;c'est la bob 14 qui est visée, retablire I14 bcf INTCON,TMR0IF goto Finit k4 call ION_23 ;c'est la bob 23 qui est visée, retablire I23 bcf INTCON,TMR0IF goto Finit ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;MAIN;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; MAIN ;Laisse la place en h4 pour Interrupt Service Routine call WAIT_1ms call WAIT_1ms call WAIT_1ms call WAIT_1ms call WAIT_1ms call WAIT_1ms call WAIT_1ms call WAIT_1ms call WAIT_1ms call INIT ;Initialiser les variables et I/O Wait ;etincelle juste emise movlw lTSIM movwf TSIM ;re init le nb de ms pour T , en simulation btfss OPTF,0 ;1 si mode optimisation goto wait2 ;0 classique movlw 'p' call emet ;signaler au PC qu'on est pret à recevoir des car movfw RCREG ;purge buffer bsf RCSTA,CREN ;Continuous receive enable Wait2 btfsc SIMF,0 ;test simulation flag goto wsim ;oui, on simule aller attendre 1ms ckf decfsz Front,w ;Si Front=1, c'est qu'une IT (vis) est arrivée goto tspc ;Front = 0, attendre ;IT Front arrivée bcf RCSTA,CREN ;Continuous receive disable clrf Front ;clear ce flag btfss JUMO,0 goto hp1 ;une seule bob movlw b'11111110' ; Deux bob Jumo, T va etre divisée par 2 andwf T_L,f ;RAZ de b0 ds T_L pour avoir C=0, ;on veut b0 de T_H en pos b7 ds T_L bcf STATUS,C ;C=0 rrf T_H,f ;b0 de T_H ds C rrf T_L,f ;b0 de T_H en pos 7 de CT_L, C=0 T/2 hp1 movfw T_H movwf T8_H ;sauver T en u de 8µs pour TMR1 movfw T_L movwf T8_L call EXTRACT_D ;Get D dans une des 2 tables call CALC_DEL ;Correction de D en + ou en - ;B1 Breakpoint T ds CT_H,CT_L et D dans D_H,D_L btfsc TBVF,0 ; si N<914t/mn mot, traitement special goto ac call WAIT_DP ;Attendre avant etincelle ; call IOFF_14 ;B3 etincelleOK**********************Fin de calcul de TC call SET_TMR0 ;Lancer TMR0 btfss JUMO,0 goto ab bcf Bobi,0 ;c'est Bob 23 qu'il faudra charger call WAIT_TP ;attendre TP pour étincelle.TP =T-TC1 corrigé pour temps passé ; Noter que durant cette attente call IOFF_23 ; une IT intervient pour charger Bob23 call SET_TMR0 ; ab bsf Bobi,0 ;c'est Bob14 qu'il faudra charger movfw T8_H movwf T8prec_H ;conserver periode précédente movfw T8_L movwf T8prec_L goto Wait ac call TRAIT_TBV goto Wait tspc btfss OPTF,0 ;1 si optimisation goto wait2 ;0 classique btfss PIR1,RCIF ;bit RCIF=1 si car arrivé goto wait2 ;non, donc pas de car reçu à cette etincelle, attendre front bcf INTCON,GIE ;fin definitive des IT call VER_CAR ;lire un car avec verif ereur de transmission movwf CARPC movlw 'W' subwf CARPC,w btfss STATUS,Z goto ckr ;pas W call WAIT_1ms call WAIT_1ms call WAIT_1ms call WAIT_1ms call WAIT_1ms call WAIT_1ms call WAIT_1ms call WAIT_1ms call WAIT_1ms call ERASE_LT ;c'est W(rite), effacer L et T, puis les reecrit car4 call GET4C ;on va lire 4 car du PC et les ecrire en Flash call WR4inst call WAIT_1ms call WAIT_1ms movlw 4 ;si on a atteint h400, c'est fini banksel EEADRH ;bk2 subwf EEADRH,w banksel PIR1 ;bk0 btfss STATUS,Z goto car4 ;non, encore 4 car goto start ;oui,fini Htab ,on redemarre ckr movlw 'R' ;R(ead),lecture des tables L et T par le PC subwf CARPC,w btfss STATUS,Z goto ckdel ;voir si decalage demandé call WAIT_1ms call WAIT_1ms call WAIT_1ms call WAIT_1ms call WAIT_1ms call WAIT_1ms call WAIT_1ms call WAIT_1ms call WAIT_1ms call INIT_EEADR car1 call RDF1c ;lit 14 bits de Flash, garde 1 car movfw CARPC call emet movlw 4 ;si on a atteint h400, c'est fini banksel EEADRH ;bk2 subwf EEADRH,w banksel PIR1 ;bk0 btfss STATUS,Z goto car1 ;non, encore 1 car goto start ;oui,fini Htab ,on redemarre ckdel clrf DELF ;Flag de decalage à 0 movlw ' ' ; espace, h20 subwf CARPC,w btfss STATUS,Z ;si espace, laisser DELF=0, arret du decalage bsf DELF,0 ;pas un espace, donc un code, set flag de decalage bsf INTCON,GIE ;retablir les IT goto wait2 wsim call WAIT_1ms ;simulation decfsz TSIM,f goto ckf ;T pas encore fini, voir front nop bsf PIR1,CCP1IF ;simule un front sur pin 6 nop goto ckf ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; EMET ;SUB d'envoi d'un car vers PC btfss PIR1,TXIF ;attendre tant que flag=0 goto $-1 movwf TXREG ;il lui sera ajouté 1 bit de Start et 1 de Stop return ;************************************************************ ERASE32 ;SUB efface un bloc de 32 mem flash erase_row banksel EECON1 ;bk3 clrf EECON1 bsf EECON1,EEPGD;1 pour poiter vers Flash, 0 vers EEPROM bsf EECON1,WREN ;Write enable bsf EECON1,FREE ;libére,ie RAZ bcf INTCON,GIE ;pas d'IT ;;;;;;;;;;;;;;;;;;;; movlw h'55' ;magic sequence movwf EECON2 ;registre virtuel movlw h'AA' movwf EECON2 bsf EECON1,WR ;set bit Write, start erase ;;;;;;;;;;;;;;;;;;;; nop nop bcf EECON1,WREN ;disable Write banksel PIR1 ;bk0 return ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ERASE_32w ;Efface 32*w mots de flash ;là où pointe EEADRH,EEADR movwf N32 ag2 call ERASE32 decfsz N32,f goto again1 return again1 banksel EEADR ;ajouter 32 à EEADRH,EEADR movlw d'32' addwf EEADR,f btfsc STATUS,C incf EEADRH,f goto ag2 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ERASE_LT ;SUB efface(libère) call INIT_EEADR movlw d'16' ;16*32=512 call ERASE_32w call INIT_EEADR ;en h200 return ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; EXTRACT_D ;SUB de calul de Delai avant etincelle bcf TCHR,0 ;flag long Tch bcf TBVF,0 ;Flag pour N<914t/mn moteur ;Garnit D_H et D_L a partir de T (detruit,copié ds CT) movfw T_H ;Sauver T movwf CT_H movfw T_L movwf CT_L movlw b'11111100' ;T va etre divisée par 4 andwf T_L,f ;RAZ de b0-b1 ds T_L pour avoir C=0, 2 fois ;on veut b1b0 de T_H en pos b7b6 ds T_L bcf STATUS,C ;C=0 rrf T_H,f ;b0 de T_H ds C rrf T_L,f ;b0 de T_H en pos 7 de T_L, C=0 T/2 rrf T_H,f ;b1 de T_H rrf T_L,f ;en pos 7 de T_L T/4 movfw T_H ;sauver T/4 movwf TS4_H movfw T_L movwf TS4_L movlw b'11111100' ;T va etre encore divisée par 4 andwf T_L,f ;RAZ de b0-b1 ds T_L pour avoir C=0, 2 fois ;on veut b1b0 de T_H en pos b7b6 ds T_L bcf STATUS,C ;C=0 rrf T_H,f ;b0 de T_H ds C rrf T_L,f ;b0 de T_H en pos 7 de T_L, C=0 T/8 movfw T_H ;sauve T/8 ds D pour 0-366 t/mn movwf D_H movfw T_L movwf D_L rrf T_H,f ;b1 de T_H rrf T_L,f ;en pos 7 de T_L T/16 movfw T_L ;T/16 movwf TS16 ; movfw T_H movwf TS16_H ;pour N < 457 t/mn, T_H <> 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 < 457t/mn, 0 deg avance, ou 5°6 movfw T_L ;Z=1,donc T_H=0,T < 4096, N>457 t/mn addlw -d'62' ;ligne 62 mini de LTABLE N=1875t/mn 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 bsf TCHR,0 ;set flag pour long Tch 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<457 t/mn,avance 5°6 (T/16) addwf D_L,f ; 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 bsf TBVF,0 return ;sortir, avec D à jour TBV13 movfw TS4_H ;N<457 t/mn,avance 0 deg. movwf D_H ;il suffit de D=T/4 (22.5 = 90/4) pour avance 0 deg movfw TS4_L ; movwf D_L bsf TBVF,0 return ;sortir avec D à jour ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; GET4C ;SUB lit 4 car du PC , mis en DEBRAM movlw DEBRAM ;avec verif erreur de trans movwf FSR movlw 4 movwf TMP g1 movlw 'P' ;signal au PC pret à recevoir un car call emet movfw RCREG bsf RCSTA,CREN ;enable conti reception btfss PIR1,RCIF goto $-1 ;rien de reçu call VER_CAR movwf INDF ;ranger en RAM incf FSR,f ;index FSR decfsz TMP,f goto g1 ;4 car return ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; INIT_EEADR ;SUB init pointeur à la flash en h200 ;début de Ltab banksel EEADR ;bk2 movlw 2 movwf EEADRH clrf EEADR banksel PIR1 ;bk0 return ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ION_14 ;SUB charge bob14 bcf BOB_14 ;etablit I14 return ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; IOFF_14 ;SUB etincelle bob14 decfsz NOet_14,f return ;demarrage, pas d'étincelle bsf NOet_14,0 ;pour etre sur de revenir ici à chaque fois bsf BOB_14 ;coupe I14 return ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ION_23 ;SUB charge bob23 bcf BOB_23 ;etablit I23 return ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; IOFF_23 ;SUB etincelle bob23 decfsz NOet_23,f return ;demarrage, pas d'étincelle bsf NOet_23,0 ;pour etre sur de revenir ici à chaque fois bsf BOB_23 ;coupe I23 return ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; RDF1c ;SUB lecture d'un mot de flash(L et T) banksel EECON1 ;bk3 bsf EECON1,EEPGD;viser la Flash bsf EECON1,RD ;lire 14 bits nop nop ;ds EEDATH,EEDATA en bk2 banksel EEADR ;bk2 EEADRH,EEADR ++ movlw 1 addwf EEADR,f btfsc STATUS,C incf EEADRH,f movfw EEDATA ;oublier EEDATH qui contient h34 banksel PIR1 ;bk0 movwf CARPC return ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; SET_TMR0 ;SUB initialise TMR0 pour une attente(unités de 128µs) ; de (2*T8-T8prec -Trech) puis le lance ;En acceleration (T8 3750t/mn movwf TI_H movlw lTCH_L ;Trech ds TI movwf TI_L btfss TCHR,0 goto lt movlw lTCHR_H ;N<3750t/mn, long Tch movwf TI_H movlw lTCHR_L ;Trech ds TI movwf TI_L btfsc TCHR,0 lt movfw T8prec_L addwf TI_L,f btfsc STATUS,C ;ajouter T8prec incf TI_H,f movfw T8prec_H addwf TI_H,f movfw T8_L ;soustraire deux fois T8 subwf TI_L,f btfss STATUS,C decf TI_H,f movfw T8_H subwf TI_H,f movfw T8_L ; subwf TI_L,f btfss STATUS,C decf TI_H,f movfw T8_H subwf TI_H,f movlw b'11110000' ;/16 pour unités 128µs car 8*16=128 andwf TI_L,f bcf STATUS,C rrf TI_H,f rrf TI_L,f ;/2 rrf TI_H,f rrf TI_L,f ;/4 rrf TI_H,f rrf TI_L,f ;/8 rrf TI_H,f rrf TI_L,w ;/16 movwf TMR0 bcf INTCON,TMR0IF ;clear IT flag s bsf INTCON,TMR0IE ;IT de TMR0 enabled return ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; WAIT_1ms ;SUB d'attente 1 ms movlw d'250' ;attendre 1ms = 250X4mus addlw -1 btfss STATUS,Z goto $-2 return ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; WAIT_DP ;SUB attente de DP=D-TC movfw D_H movwf GEN_H movfw D_L movwf GEN_L movlw lTC subwf GEN_L,f btfss STATUS,C decf GEN_H,f call WAIT_GEN return ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; WAIT_TP ;SUB attente de T corrigée par TC1 movfw CT_H movwf GEN_H movfw CT_L movwf GEN_L movlw lTC1 subwf GEN_L,f btfss STATUS,C decf GEN_H,f call WAIT_GEN return ;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: WAIT_GEN ;SUB Attente générique , unité 8µs movf GEN_L,f ;sur place btfsc STATUS,Z goto Q1 ;0 donc ne pa sa&ttendre Q2 nop ;1u=8µs d'ici a F nop btfsc Front,0 ;si, par hasard une IT etait arrivée, sortir return nop decfsz GEN_L,f ;dec GEN_L tant que non zero 1 goto Q2 ; F 2 Q1 movf GEN_H,f ;update Z flag,test si GEN_H =0 (pseudo mov) btfsc STATUS,Z ;si GEN_H =0, Z=1 return ; oui, fini decf GEN_H,f ; non, dec DP_H goto Q2 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::::::;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; WR4 ;SUB ecrit 4 mots en flash là où pointe EEADRH,EEADR ;ces mots sont lus là où pointe FSR ;il faut 4 car pour 4 mots car h'34' cte ;en début de mot(6bits) banksel EECON1 ;bk3 clrf EECON1 bsf EECON1,EEPGD;1 pour pointer vers Flash, 0 vers EEPROM bsf EECON1,WREN ;Write enable banksel cpt ;bk0 compteur de 1 à 4 movlw 4 movwf cpt banksel EEDATA ;bk2 movf EEADR,f ;sur place, test si 0 btfsc STATUS,Z goto debtab ;h200 ou h300 loop banksel EEDATA ;get 6 bits movlw h'34' ;op code RETLW ld movwf EEDATH ;tj cette valeur de 6 bits, un mot sur 2 ;sauf 07 en debut des tables movf INDF,w ;indirect load de EEDATA, get 1 car movwf EEDATA incf FSR,f ;pointer++ banksel EECON1 movlw h'55' ;magic sequence movwf EECON2 ;registre virtuel movlw h'AA' movwf EECON2 bsf EECON1,WR ;set bit Write, start erase nop nop banksel EEADR ;EEADRH,EEADR ++ movlw 1 addwf EEADR,f btfsc STATUS,C incf EEADRH,f banksel cpt decfsz cpt,f goto loop ;pas encore 4 passages banksel EECON1 bcf EECON1,WREN ;disable Write banksel PIR1 ;bk0 return debtab movlw h'82' ;h0782 = addwf PCL,f en debut des tables movwf INDF ;remplace le car, DEBRAM=h82 movlw h'07' goto ld ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; WR4inst ;SUB ecrit 4 instructions de 14 bits en Flash ;là où pointe EEADRH,EEADR movlw DEBRAM ;vers premier car movwf FSR call WR4 return ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; LTABLE org h'200' ;Table des delais N =457-1875 t/mn addwf PCL,f ;sauter au bon endroit h34=opcode pour RETLW INCLUDE c:\aepl\8ltab.txt ;ici la LTABLE préalablement ;générée par le prog. gentvxx ;::::::::::::::::::::::::::::::::::::::::::::::::: HTABLE org h'300' ;Table des delais N >1875 t/mn addwf PCL,f ;sauter au bon endroit h34=opcode pour RETLW INCLUDE c:\aepl\8htab.txt ;ici la HTABLE préalablement ;générée par le prog. gentvxx ;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: org h'400' ;car plus de place avant h200 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; CALC_DEL ;SUB calcul la correction pour D, u de 8µs ;Appel et retour inclus :48µs soit lTCdel=6u movf TBVF,f ;sur place.si Nmot<914t/mn, sortir btfss STATUS,Z return ;oui, TBVF=1 movf DELF,f ;sur place.si ce flag=0, sortir btfsc STATUS,Z return movfw TS16 ;calculé par SUB EXTRACT, correspond à 11.2° vilo movwf DEL ;initialise DEL qui sera ajouté à D movfw CARPC ;code reçu du PC, de h30 à h37 andlw 3 ;garder b0,b1 movwf TMP movf TMP,f ;sur place. btfsc STATUS,Z goto ws1 ;0 donc c'est 11°2 bcf STATUS,C ;T/32 rrf DEL,f movlw 1 subwf TMP,w btfsc STATUS,Z goto ws2 ;1 donc 5°6 bcf STATUS,C ;T/64 rrf DEL,f movlw 2 subwf TMP,w btfsc STATUS,Z goto apdel ;2 donc 2°8 bcf STATUS,C ;3 donc 1°4 rrf DEL,f ;T/128 apdel btfsc CARPC,2 ;b2 donne le sens, + ou - d'avance goto mav ;1 donc - d'avance, on ajoute DEL à D movfw DEL ;0 donc + d'avance, on retranche DEL de D subwf D_L,f btfss STATUS,C decf D_H,f goto f23 mav movfw DEL ;D=D+DEL addwf D_L,f btfsc STATUS,C incf D_H,f f23 movlw lTCdel ;corriger D pour temps ds cette SUB subwf D_L,f btfss STATUS,C decf D_H,f return ws1 goto $+1 ;attendre pour s'aligner sur tps de calcul de 2°8=1°4 goto $+1 goto $+1 ws2 goto $+1 goto $+1 goto apdel ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; INIT ;SUB d'initialisation des variables et E/S clrf INTCON ;Aucune IT autorisée clrf DELF ;Flag pour decalage d'avance clrf TBVF ;Flag Nmot<914t/mn clrf SIMF ;flag de simulation movlw lTSIM movwf TSIM ;nb de ms pour T simulée movf TSIM,f ;sur place btfss STATUS,Z bsf SIMF,0 ; pas 0, donc simulation call INIT_EEADR ;pointe à h'200' debut de Ltab movlw OPTI movwf OPTF ;1 si mode optimisation banksel ANSEL ;bk1 clrf ANSEL ;TTes les entrées en numerique movlw B9600 ;Init USART movwf SPBRG ;Baud genarator à 9600 bps clrf TXSTA bsf TXSTA,BRGH ;b2 de TXSTA pour Hi speed baud generator bcf TXSTA,SYNC ;b3 de TXSTA pour Asynchrone bsf TXSTA,TXEN ;b4 de TXSTA,enable transmission, ; also sets bit TXIF de PIR1 banksel RCSTA ;Revenir à Bank 0 bsf RCSTA,SPEN ;b7 de RCSTA,Set Serial Port RD et TX movlw lJUMO movwf JUMO movlw lNOet movwf NOet_14 movwf NOet_23 clrf T_H clrf T_L clrf Front bsf INTCON,PEIE ;Peripheral enable IT, pour TMR1 et CCP module ;INIT De TMR0 qui assure la recharge des bob, unité de 128µs bcf INTCON,TMR0IF ;IT flag bcf INTCON,TMR0IE ;Disable IT.Sera remise par SET_TMR0 et enlevée ds ISR clrf TMR0 banksel OPTION_REG ;bk1 bcf OPTION_REG,T0CS ;input is from internal clock bcf OPTION_REG,PSA ;pre scaaler is for TMR0, not WDT bsf OPTION_REG,PS2 bsf OPTION_REG,PS1 ;/128 bcf OPTION_REG,PS0 ;INIT de TMR1 qui mesure T, unités de 8µs banksel PIR1 ;bk0 bcf PIR1,TMR1IF ;IT d'overflow de TMR1 16 bits banksel PIE1 ;bk1 bsf PIE1,TMR1IE ;enabled banksel PIR1 ;bk0 bsf T1CON,T1CKPS1;/8 bsf T1CON,T1CKPS0 bcf T1CON,TMR1CS;Clock select: internal bcf T1CON,TMR1ON;ne pas lancer clrf TMR1H clrf TMR1L ;INIT de CCP module movlw b'00000101' ;Event is:front montant sur RB0, pin6, IT à chaque front movwf CCP1CON bcf PIR1,CCP1IF ;flag d'IT banksel PIE1 ;bk1 bsf PIE1,CCP1IE ;enable IT ;tj en bk1 movlw b'00000101' ;Make RB0 INPUT (hardware pin6) 1 for 1nput ;RB4 OUTPUT (hardware pin 10) bob cyl 3 et 2 ;RB5 TX out pin 11, RB2 RX in pin 8 movwf TRISB movlw b'00110000' ;Make RA4 INPUT(hardware pin3) 1 for 1nput(comp Polling) ;et RA0 OUTPUT(harware pin 17) bob cyl 1 et 4 ;et RA1 (pin 18) out protec bob, tj à 1 movwf TRISA banksel PIR1 ;bk0 bsf Bob_14 ; couper I bsf Bob_23 bsf PORTA,1 ;1 pour bloquer le transistor ;qui clampait les grilles des IGBT bsf T1CON,TMR1ON;lancer TMR1 bsf INTCON,GIE ;Enable all ITs return ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; TRAIT_TBV ;SUB génère étincelles qd N<914t/mn moteur ; Ion pendant lTCHR,typique 5ms call IOFF_14 ;securité movfw D_H ;D contient T/4 si avance 0°, 3T/16 si avance 11°25 movwf GEN_H ;preparer D-lTCHR pour attente avant recharge movfw D_L ;NOTA on laisse tomber la correction lTC ;car faible env 120µs movwf GEN_L movlw lTCHR_L ;typique 5ms subwf GEN_L,f btfss STATUS,C decf GEN_H,f movlw lTCHR_H subwf GEN_H,f call WAIT_GEN call ION_14 ;etablit le courant movlw lTCHR_H movwf GEN_H movlw lTCHR_L movwf GEN_L call WAIT_GEN ;lTCHR de Ion call IOFF_14 ;étincelle Bob 14 btfss JUMO,0 return ;1 seule bob call IOFF_23 ;on a 2 bob,securité movfw CT_H ; movwf GEN_H ;preparer T-lTCHR pour attente avant I23 ON movfw CT_L movwf GEN_L movlw lTCHR_L ;typique 5ms subwf GEN_L,f btfss STATUS,C decf GEN_H,f movlw lTCHR_H subwf GEN_H,f call WAIT_GEN ;attendre T-lTCHR call ION_23 ;etablit le courant movlw lTCHR_H movwf GEN_H movlw lTCHR_L movwf GEN_L call WAIT_GEN ;pendant lTCHR call IOFF_23 ;étincelle Bob 23 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; VER_CAR ;SUB verifie erreur de transm.Y reste pour obtenir un car ;on y entre qd le bit RCIF=1, qd on sort, CREN=0 btfsc RCSTA,OERR ;over run error goto errcar btfsc RCSTA,FERR ;Frame error goto errcar movfw RCREG ;OK, pas d'erreur de reception,lire car, ce qui reset RCIF bcf RCSTA,CREN ;Arret reception return ;avec car ds w errcar bcf RCSTA,CREN ;clear OERR et FERR,ignorer ce car à pb bsf RCSTA,CREN movfw RCREG movfw RCREG ;purge buffer bsf RCSTA,CREN ;enable read btfss PIR1,RCIF goto $-1 ;attendre 1 car goto VER_CAR ;verif next car return ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; END ; directive 'end of program