Friday, July 11, 2014

Timing Advance Processor with a PIC



Timing advance processors are electronic control units that change the original spark advance of the engine when it runs on CNG or LPG, thus optimising the engine’s operation with these fuels.

Because LPG is a higher octane fuel than petrol the combustion time is longer. It is possible to change the ignition timing mechanically or electronically. This makes the difference between driving on LPG or petrol less. The fuel consumption and the engine power at low speed could be the same or even better than on petrol. Also the engine will run more smoothly and the exhaust emission values will be better.



 
;**************************************************************************
;Svetlin Spasov
;Basic Timing Advance Processor for LPG and CNG powered vehicles
;
;**************************************************************************

        LIST P=16F877, R=DEC
#include          ; processor specific variable definitions
      __config _HS_OSC & _WDT_ON & _LVP_OFF  


;--------------------------------------------------------------------------
; Variables
;--------------------------------------------------------------------------


;angle           res     1  
;v_work          res     1
;back            res     1
;up              res     1

ScratchPadRam   EQU     0x20

;--------------------------------------------------------------------------
; Variables
;--------------------------------------------------------------------------

angle    EQU     ScratchPadRam+0
v_work   EQU     ScratchPadRam+1
back     EQU     ScratchPadRam+2
back1    EQU     ScratchPadRam+3
up       EQU     ScratchPadRam+4
up1      EQU     ScratchPadRam+5
store    EQU     ScratchPadRam+6


;--------------------------------------------------------------------------
; Program Code
;--------------------------------------------------------------------------
;--------------------------------------------------------------------------
;   Set the reset vector here.  If you are using a PIC16C5X device, use:
;               ORG     
;   Otherwise, use:
;               ORG     0
;--------------------------------------------------------------------------

                ORG     0       
                GOTO    Start
                
                ;comp = 3
MORE_THAN macro comp ,var0 , jump
    MOVLW comp ; slagame comp v accumulatora
 SUBWF var0, 0      ; ako v starshia registyr ima po-malko ot comp, obshtoto 4islo ne moje da e po-goliamo ot 1000
 BTFSC STATUS, Z 
    GOTO jump;
endm
                ;comp = 3
LESS_THAN macro comp ,var0 , jump
    MOVLW comp ; slagame comp v accumulatora
 SUBWF var0, 0      ; ako v starshia registyr ima po-malko ot comp, obshtoto 4islo ne moje da e po-goliamo ot 1000
 BTFSS STATUS, Z 
    GOTO jump;
endm

EQ_JP_EQUAL macro comp, var0, jump
MOVF comp;
XORWF var0,0;
BTFSC STATUS,Z;
GOTO jump;
endm

EQ_JP_NEQUAL macro comp, var0, jump
MOVF comp;
XORWF var0,0;
BTFSS STATUS,Z;
GOTO jump;
endm

MORE_THAN_16BIT macro compH, compL,varH,varL,jump ; jump to address if more than

      MOVLW varH ; sloj starshia reg v akumulatora
   BCF STATUS, RP1 ; izberi banka
   BCF STATUS, RP0 ; banka
   SUBWF compH, 0 ; izvadi tova i stoinostta v akumulatora
   BTFSS STATUS, Z ; proveri statusa za 0 bit
   GOTO L_setAngle_25 ; jump kym izhoda
   MOVLW varL          ; slovi mladshia v akumulatora
   SUBWF compL, 0     ; izvadi gi sus sravniavanoto 4islo
L_setAngle_25:
      BTFSC STATUS, C   ; proveri status za polojitelen ili otricatelen rezultat ot operaciata
   GOTO jump        ; sko4i, ako resultata e polojitelen

endm
;--------------------------------------------------------------------------
; Main Program
;--------------------------------------------------------------------------

                ORG     ScratchPadRam+7

Start
CLRWDT ; ku4eto v kusheto
CLRW ; accumulatora v kire4a
MOVLW b'11111111' ; portb initializaciq
BANKSEL TRISB
MOVWF TRISB  
               ; bankata e 0

MOVLW b'00000000' ; kak pishem tuka kato e vhod...
BANKSEL PORTB
MOVWF PORTB
   


clrw
BANKSEL TRISC

   CLRF TRISC ; izhoda 0
   
  BANKSEL PORTC
   CLRF PORTC    ; nulirame izhoda
   CLRW
BANKSEL angle 
    CLRF v_work ; same bank as angle, virtualen raboten resistyr
    CLRF angle
    CLRF back ;
    CLRF back1 ;
    CLRF up ;
    CLRF up1 ;

    
    BANKSEL angle;
    MOVLW b'00000011' ; malko ugal za test
    MOVWF angle ;
    MOVF angle,0;
    MOVWF store ; store angle

      

 loop:  

    MOVLW b'00000011' ; malko ugal za test
    MOVWF angle ;

     BTFSC PORTB , 1 
     RLF angle, 1 ;   //umnojavame X 2 
     BTFSC PORTB , 2 
     RLF angle, 1 ;   //umnojavame X 2 
     BTFSC PORTB , 3 
     RLF angle, 1 ;   //umnojavame X 2 
     BTFSC PORTB , 4 
     RLF angle, 1 ;   //umnojavame X 2 


    BTFSS PORTB , 0 ; // (if portb.f0 == 0 && v_work.f0 == 1)
    BTFSS v_work , 0 ;
    GOTO chek1 ;
    BCF v_work, 0 ;
    CLRF back
    CLRF back1
    MOVF up, 0     ;zapazvame broaia4a v back
    MOVWF back
    MOVF up1,0;
    MOVWF back1; 
    GOTO setAngle;
    retsetAng:

    CLRF up ;
    CLRF up1;
 chek1;
    BTFSC PORTB,0; // if portb.f0 == 1 && v_work.f0 == 0
    BTFSC v_work,0;
    GOTO cont;
    BSF v_work,0;
    MOVF PORTB , 0
    MOVWF PORTC
    GOTO loop; 
 cont:
   BTFSC PORTB,0; // ako nivoto e visoko, uveli4i broaia4a na visoko nivo
   GOTO proc;
    

   GOTO loop
  
 proc:
   CLRWDT
   GOTO incUp;  // uveli4i broia4a
 retUp:

  ;DECFSZ back,1;
   CALL decBack;  // namali back broia4a
   ;DECFSZ back,1;
   MOVLW 0 
   XORWF back,0; ako "back" broaia4a stane 0
   BTFSS STATUS,Z
   GOTO loop;   // mladshia ne e 0 produlji
   MOVLW 0   
   XORWF back1,0
   BTFSS STATUS,Z
   GOTO loop;  //starshia ne 0, produlji

   BCF PORTC,0; // ako back stane 0 nivoto dolu





GOTO loop;

setAngle:

   
MORE_THAN_16BIT up1,up, 3 , 200 , L_setAngle_0 ; proverka na oborotite


  BANKSEL angle;
  
     MOVF up, 0     ;zapazvame broaia4a v "back"
     MOVWF back
     MOVF up1,0;
     MOVWF back1; 

     MOVF up1,0;     // sloji starshia registyr v store
     MOVWF store;    // poneje, veroiatno starshia registyr ne e uspial da se uveli4i dostatu4no pri visoki oboroti
     ;RLF store, 1 ;   //umnojavame X 2 
     ;RLF store, 1 ;   //umnojavame oshte X 2 


dec11:
     CALL decBack; 
     DECFSZ store,1;  
     GOTO dec11;       // loop

 

 GOTO retsetAng; / iz4ee !


L_setAngle_0: ; dec back counter

     MOVF angle,0;
     MOVWF store; //store ang > "store"
  
     dec: 
     ; DECF back,1;
     CALL decBack; 
     DECFSZ store,1;  
     GOTO dec;       // loop
GOTO retsetAng; // iz4ee!



incUp:
   INCF up, 1
   BTFSC STATUS, Z
   INCF up1, 1

GOTO retUp;

incBack:
   INCF back, 1
   BTFSC STATUS, Z
   INCF back1, 1

RETURN;


decBack: ;it's a func cos it's called more than 1 times, maybe it should be inlined for best speed instead of code size
            MOVLW 1
   SUBWF back, 1
   BTFSS STATUS, C
   DECF back1, 1
            
            
RETURN;

    
END


3 comments:

  1. Hello. I would like to start a project of arduino based TAP. Can you please describe a little algorithms you use in you device ? Thanks.

    ReplyDelete
    Replies
    1. more nfo here: http://conf.uni-ruse.bg/bg/docs/cp12/3.2/3.2-33.pdf

      Delete
  2. I forgot to check notify me, sorry.

    ReplyDelete