40deg advance signal is coming at "RA3" pin of microcontroller.
hall effect sensor is employed near the flywheel to catch the first pulse by the
magnet.
trigger to the ignition driving mosfet/SCR is done by the microcontroller "RB0"
pin.
http://ot40.com/cdi_ignition.htm      <- all the schematics are here
;=========================================================================
;;CDI for model engines
;Based on "Bike Advance" 4.23
;V1.0 09.14.2005 Jon-Magne Johansen
;=========================================================================
;==========================================================================
        Title "Bike Advance"
;   http://www.perso.wanadoo.fr/transmic/
;       01 11 04      Version 4.23 for 16F84a      Thierry.P
; -------------------------------------------------------------------------
; Adaptation of the program Ign.txt "Auto Advance" from A. Nixon
; Title "Auto Advance" for 16c54
;       24 08 94      Version 1.0      A. Nixon
;==========================================================================
        ;
        ;   Ign advance starts at 1500 engine RPM
        ;
        ;   Ign full advance is at 16000 engine RPM
        ;
        ;   dwell time is fixed at 1mS, =    10 X 100uS loops
        ;
        ;   After 1500 RPM, the ignition advance is calculated in 116 steps.
        ;   This continues up until 16000 RPM is reached.
        ;
        ;
        ;   At a engine speed of 1200 RPM;
        ;
        ;          1200 / 60 = 20 revs per second
        ;            1 / 20 = 50mS per rev
        ;             1 rev = 360 degrees
        ;
        ;          36 degrees at 1200 RPM = (36 / 360) X 50 = 5mS
        ;
        ;   Therefore maximum retard at 1200 RPM = 5mS after the firing
        ;   point is reached. This figure remains constant down to 0 RPM.
        ;
        ;   At a engine speed of 16000 RPM, maximum advance will have been reached,
        ;   and ignition is immediately after the firing point is reached.
        ;
        ;   The intermediate values will be looked up in an advance table map
        ;   and will correspond to engine speed from 1500 RPM to 16000 RPM.
        ;
        ;   As the engine RPM increases above 1500, the retard value becomes
        ;   progressively lower until 5000RPM is reached, then increase until
        ;   16000 RPM is reached, whereby the retard value will be 0.
        ;   Under 1500 RPM the retard value is fixed at 12ms
        ;
        ;
        ;   Map holds retard values in 100uS loops for every loop change
        ; in rpm rate.
        ;
        ;
        ;
;==========================================================================
;
;       PIC 16F84 wiring
;
;==========================================================================
     ;
     ;                         RA2    1+--O--+18       RA1
     ;   pickup36°-----------> RA3    2|      |17      RA0
     ;   test jumper---------> RA4    3|      |16      Osc ------ 4MHz
     ;   +5V--+----R------ -> MCLR 4|         |15      Osc ------ Quartz
     ;   Ground--------- -- -- -- Vss     5|          |14 Vcc ------ +5Vdc
     ;   Thyristor    <---- -     -- RB0   6|          |13 RB7 ------>PickupLED
     ;   LEDrpmLimit <----- RB1      7|      |12      RB6
     ;   ReverseOutput<-- -- RB2     8|      |11      RB5
     ;   Strobe<------------- RB3    9+-----+10       RB4
;==========================================================================
;
;       Versions
;
;==========================================================================
         ;   Version   2.3:   add a reverse output to coil, detect rotor __-__
         ;   Version   2.6:   modif calculation, detect rotor --_--
         ;   Version   2.8:   modif register
         ;   Version   3.0:   correction at low RPM, or big retard.
         ;   Version   3.1:   deboun=1ms, initial delay=18ms, detect rotor high __-__
         ;   Version   3.2:   suppression extra pluses at low RPM
         ;   Version   4.0:   simplification, 4MHz cristal.trigger on decreasing edge
         ;   Version   4.1:   trigger on rising edge
         ;   Version   4.2:   map move at the end of the soft. max adv=0ms
         ;   Version   4.3:   Same soft as 4.2 but range 1500-16000RPM (for 2strokes)
         ;
         ;
;==========================================================================
;
;       Directives
;
;==========================================================================
        list p=16f84a         ; processor type
        ;
        __config B'11111111110010'
        ; No code protect, PWRT on, no watchdog, Quartz 4to20Mhz
        ;
        ; Page 0: 0-FF page1: 100-1FF page2: 200-2FF page3: 300-3FF
;==========================================================================
;
;       Register Definitions
;
;==========================================================================
W                                   EQU     H'0000'
F                                   EQU     H'0001'
;----- Register Files------------------------------------------------------
INDF                         EQU     H'0000'
TMR0                         EQU     H'0001'
PCL                          EQU     H'0002'
STATUS                       EQU     H'0003'
FSR                          EQU     H'0004'
PORTA                        EQU     H'0005'
PORTB                        EQU     H'0006'
EEDATA                       EQU     H'0008'
EEADR                        EQU     H'0009'
PCLATH                       EQU     H'000A'
INTCON                       EQU     H'000B'
OPTION_REG                   EQU     H'0081'
TRISA                        EQU     H'0085'
TRISB                        EQU     H'0086'
EECON1                       EQU     H'0088'
EECON2                       EQU     H'0089'
;----- STATUS Bits --------------------------------------------------------
IRP                          EQU     H'0007'
RP1                          EQU     H'0006'
RP0                          EQU     H'0005'
NOT_TO                       EQU     H'0004'
NOT_PD                       EQU     H'0003'
Z                            EQU     H'0002'
DC                           EQU     H'0001'
C                            EQU     H'0000'
;----- INTCON Bits --------------------------------------------------------
GIE                          EQU     H'0007'
EEIE                         EQU     H'0006'
T0IE                         EQU     H'0005'
INTE                         EQU     H'0004'
RBIE                         EQU     H'0003'
T0IF                         EQU     H'0002'
INTF                         EQU     H'0001'
RBIF                         EQU     H'0000'
;----- OPTION Bits --------------------------------------------------------
NOT_RBPU                     EQU     H'0007'
INTEDG                       EQU     H'0006'
T0CS                         EQU     H'0005'
T0SE                         EQU     H'0004'
PSA                          EQU     H'0003'
PS2                          EQU     H'0002'
PS1                          EQU     H'0001'
PS0                          EQU     H'0000'
;==========================================================================
;
;       Define
;
;==========================================================================
#DEFINE     rotor     PORTA,3                ; [pin2]= sensor input
#DEFINE     coil      PORTB,0          ; [pin6]= output to coil
#DEFINE     revcoil   PORTB,2                ; [pin8]= reverse output to coil
#DEFINE     rpmmax    PORTB,1          ; [pin7]= Min and Max RPM led
#DEFINE     led PORTB,7                ; [pin13]= pickup led
#DEFINE     strobe    PORTB,3                ; [pin9] = strobe light output
#DEFINE     test      PORTA,4                ; [pin3] = test jumper input
;==========================================================================
;
;       RAM Definition
;
;==========================================================================
rpmhi equ       0Ch       ;   RPM counter register high
rpmlo equ       0Dh       ;   RPM counter register low
dwell equ       0Eh       ;   dwell time counter
rtdset            equ   0Fh       ; retard value holding register
math equ        11h       ;   calculation register
coilflg           equ   12h       ; coil status
spkflg            equ   13h       ; flag after one spark
rotflg            equ   14h       ; rotor sense flag
retard            equ   15h       ; new retard value
d1                equ   16h             ;Temp value for the testdelay routine
d2                equ   17h             ;Temp value for the testdelay routine
;==========================================================================
;
;       Main Program
;
;==========================================================================
                org 0                          ; start adress 0
start       bsf    STATUS,RP0          ;   go to bank 1
            movlw H'FF'                ;   set all portA..
            movlw TRISA                ;   ..as inputs
            movlw H'00'                ;   set all portB..
            movwf TRISB                ;   ..as outputs
        ;
            movlw b'11000001'          ; no pull-up,rising edge int,internal timer,1:4
            movwf OPTION_REG
            bcf STATUS,RP0             ; come back into bank 0
            ;
            clrw                       ; clear all variables
            clrf PORTA                 ; clear variables
            clrf PORTB
            clrf math
            clrf rpmlo
            clrf coilflg
            movlw 0xff                 ; rpmhi = FF initially
            movwf rpmhi
            movwf spkflg               ; no spark until pickup is high
            movwf rotflg               ; and no spark loop if pickup stay up
                movwf retard                 ; retard value = 25ms initially
        ;
            ;
          ;       100uS loop time
          ;       4MHz clock / 4 = 1MHz instruction cycle
          ;       cycle time = 1/1MHz = 100uS
          ;       100uS/100uS = 100 cycles
          ;       prescaler set to divide by 4
          ;       preset TMR0 = 231, when = 0 = 100uS
          ;       231 to 255 = 25 x 4(prescaler) = 100
          ;
          movlw .231      ;movlw .206 for a 8MHz clock
          movwf TMR0
          ;
          ;
              btfss test                ; if the test jumper is set (low)
              goto testdelay            ; goes to testdelay routine
mnloop        movf TMR0,W
          btfss STATUS,Z        ; is TMR0=0 ?
          goto mnloop           ; no, main delay loop
          ;
          movlw .231                    ; yes, re-preset TMR0 (240max)
          movwf TMR0
          ;
      incf rpmlo,F             ; increment rpmlo
         btfsc STATUS,Z        ; is rpmlo = 0 ?
         incf rpmhi,F          ; yes, increment rpmhi
         ;
             ;       if rpm count > 1400h, 5120 x 100us=0.5 Secs, then it is assumed
that the
         ;       motor has stopped. Reinitialize system.
         movlw 0x14
         subwf rpmhi,W
         btfsc STATUS,Z        ; rpmhi - 14 = 0 ?
         goto start            ; yes
         ;
;rotchk     btfss rotor          ; + is rotor high or low?
rotchk         btfsc rotor             ; (- detect pickup low) (CH ignitions sensor)
          goto rnowlw          ; low
          ;
          movf rotflg,W         ; high, is it flagged high also? rotflg=FF?
          btfss STATUS,Z
          goto coilck           ; yes
          ;
          movlw 0xff                  ; no
          movwf rotflg          ; flag rotor as up
          bsf led                     ; turn ignition pickup led on
               clrf spkflg            ; reset flag for one spark
          goto rpmcalc          ; calculate RPM
     ;
rnowlw    movf rotflg,W         ; is it flagged low already ? rotflg=0?
          btfsc STATUS,Z
          goto coilck          ; yes, wasn't flagged high
          ;
dolow       bcf led                    ; no, turn ignition pickup led off
            clrf rotflg          ; flag rotor as down
            goto mnloop
            ;
decret         decf retard,F           ; no, decrement retard then wait
               goto mnloop
        ;
coilck      movf coilflg,W       ; is coil flagged high? coilflg=FF?
            btfss STATUS,Z
            goto upcoil         ; yes, then decrement dwell count
            movf retard,W         ; is retard = 0 ?
            btfss STATUS,Z
            goto decret                ; no, then decrement retard
            ;
                movf spkflg,W          ; yes, a spark have been done? spkflg=FF?
            btfss STATUS,Z
            goto mnloop         ; yes, no more spark
            ;
            bsf coil             ; no, go on for the first spark
                bsf strobe             ; same for strobe
            bcf revcoil
            movlw 0xff           ; set flag for high coil
            movwf coilflg
            movwf spkflg         ; set flag for one spark
        ;   ****************** YOU CAN MODIFY THE DWELL VALUE BELLOW ********
        movlw .2        ; 10 X 100uS = 1ms corrected to .2 ms for better strobe
performance
        movwf dwell           ; set dwell time
        ;
        goto mnloop
      ;
upcoil    ;                if dwell # 0 then dwell - 1
          ;                if dwell now = 0, turn on coil
          ;
          decfsz dwell,F         ; dwell = dwell - 1
          goto mnloop            ; dwell <> 0, wait
          bcf coil         ; dwell = 0, turn coil off
        bcf strobe         ; same with strobe
          bsf revcoil            ; dwell = 0, turn revcoil on
          clrf coilflg                 ; set flag for low coil
          goto mnloop
          ;
rpmcalc ;           engine RPM <= 1500 at maximum retard, = 40ms
      ;
        ;           40mS = 400 X 100us loops, = 190h
        ;           ( 1500RPM for a 1cyl - 4stroke with one spark loose )
        ;           ( 1500RPM for a 1cyl - 2stroke )
        ;           ( 750RPM for a 4cyl - 4stroke = 25Hz )
        ;
        ;      engine RPM >= 16000 at maximum advance, = 3.8mS
        ;          3.8mS = 38 X 100uS loops, = 26h
        ;          ( 16000RPM for a 1cyl - 4stroke with one spark loose )
        ;          ( 16000RPM for a 1cyl - 2stroke )
         ;        ( 8000RPM for a 4cyl - 4stroke = 266Hz )
         ;
         ;        this routine determines whether the engine RPM
         ;        value is below 38 loop counts - max advance, or above
         ;        400 loop counts - max retard, or some where in between.
         ;
         ;
         ; high RPM:            ; > 16000RPM
         ;
         movf rpmhi,W
         btfss STATUS,Z         ; is rpmhi = 0?
         goto bigfv             ; no
         ;
         movf rpmlo,W
         xorlw 0x26                   ; yes, is rpmlo = 26h ?
         btfsc STATUS,Z
         goto maxadv            ; yes, do max advance
         ;
         movlw 0x26
         subwf rpmlo,W          ; no, is rpmlo < 26h ?
         btfss STATUS,C
         goto maxadv            ; yes, do max advance
         ;
         ; medium RPM:
         goto caladv            ; no, calculate new advance
         ;
         ;
         ; low RPM:             ; < 1500RPM
bigfv    movf rpmhi,W
         xorlw .1               ; is rpmhi = 1 ?
         btfsc STATUS,Z
         goto resfv             ; yes, see if rpmlo = 90h
         ;
         movlw .1
         subwf rpmhi,W          ; no, is high byte > 1 ?
         btfsc STATUS,C
         goto maxret            ; yes, do max retard
         ;
         goto caladv            ; no, calculate new advance
         ;
resfv    movf rpmlo,W
         xorlw 0x90             ; rpmhi = 1, does rpmlo = 90h ?
         btfsc STATUS,Z
         goto maxret            ; yes, do max retard
         ;
         movlw 0x90
         subwf rpmlo,W          ; no, is rpmlo > 90h ?
         btfsc STATUS,C
         goto maxret            ; yes, do max retard
         ;
         ;
         ; the formula to get the data stored in the map is as follows
         ;
         ;                  rpmhi/lo count - 37
         ;    116    -    ---------------------------
         ;                             4
         ;
caladv   movlw d'37'            ; rpmhi/lo - 37
         subwf rpmlo,F          ; rpmlo = rpmlo - 37
        btfss STATUS,C
        decf rpmhi,F
        ;
        ; divide result by 4
        ;
        bcf STATUS,C
        rrf rpmhi,F
        rrf rpmlo,F           ; / 2
        ;
        bcf STATUS,C
        rrf rpmhi,F
        rrf rpmlo,F           ; / 4
        ;
        ;bcf STATUS,C
        ;rrf rpmhi,F
        ;rrf rpmlo,F          ; / 8
        ;
        movlw .116            ; 116 entries in map list
        movwf math
        ;
        movf rpmlo,W
        subwf math,W          ; W = 116 - result
        ;
        bcf PCLATH,0          ; be sure to go h'200'
        bsf PCLATH,1          ; where is the map.
        call map        ; read map
        movwf rtdset          ; come back with new retard value
        ;
rpmset clrf rpmhi             ; clear RPM counters
        clrf rpmlo
            movf rtdset,W           ; transfert advance value
        movwf retard
        goto mnloop           ; (therefore minimum retard is 1 loop-100us)
        ;
maxret movlw 0x32
        movwf rtdset          ; retard value = 32h (5ms)
        bcf rpmmax            ; turn off maxrpm led
        goto rpmset
        ;
maxadv clrf rtdset            ; retard value = 0ms
        bsf rpmmax            ; turn on maxrpm led
        goto rpmset
        ;
map     org h'200'            ; store map at 200h
            addwf PCL,1       ; add W + PCL
      ; *********** INSERT YOUR OWN VALUES HERE *******************
        retlw   32h   ;5ms
        retlw   31h   ;4,9ms   1503rpm
        retlw   31h   ;4,9ms   1517rpm
        retlw   30h   ;4,8ms   1531rpm
        retlw   2Fh   ;4,7ms   1545rpm
        retlw   2Fh   ;4,7ms   1559rpm
        retlw   2Eh   ;4,6ms   1573rpm
        retlw   2Eh   ;4,6ms   1587rpm
        retlw   2Dh   ;4,5ms   1601rpm
        retlw   2Dh   ;4,5ms   1616rpm
        retlw   2Ch   ;4,4ms   1631rpm
        retlw   2Ch   ;4,4ms   1646rpm
retlw   2Bh   ;4,3ms     1661rpm
retlw   2Bh   ;4,3ms     1677rpm
retlw   2Ah   ;4,2ms     1692rpm
retlw   2Ah   ;4,2ms     1708rpm
retlw   29h   ;4,1ms     1724rpm
retlw   29h   ;4,1ms     1741rpm
retlw   28h   ;4ms     1758rpm
retlw   28h   ;4ms     1775rpm
retlw   27h   ;3,9ms     1792rpm
retlw   27h   ;3,9ms     1809rpm
retlw   26h   ;3,8ms     1827rpm
retlw   26h   ;3,8ms     1846rpm
retlw   25h   ;3,7ms     1864rpm
retlw   25h   ;3,7ms     1883rpm
retlw   24h   ;3,6ms     1902rpm
retlw   24h   ;3,6ms     1922rpm
retlw   23h   ;3,5ms     1942rpm
retlw   23h   ;3,5ms     1962rpm
retlw   22h   ;3,4ms     1983rpm
retlw   22h   ;3,4ms     2004rpm
retlw   21h   ;3,3ms     2026rpm
retlw   21h   ;3,3ms     2048rpm
retlw   20h   ;3,2ms     2070rpm
retlw   20h   ;3,2ms     2093rpm
retlw   1Fh   ;3,1ms     2116rpm
retlw   1Fh   ;3,1ms     2140rpm
retlw   1Fh   ;3,1ms     2165rpm
retlw   1Eh   ;3ms     2190rpm
retlw   1Eh   ;3ms     2215rpm
retlw   1Dh   ;2,9ms     2241rpm
retlw   1Dh   ;2,9ms     2268rpm
retlw   1Ch   ;2,8ms     2295rpm
retlw   1Ch   ;2,8ms     2323rpm
retlw   1Bh   ;2,7ms     2351rpm
retlw   1Bh   ;2,7ms     2381rpm
retlw   1Ah   ;2,6ms     2411rpm
retlw   1Ah   ;2,6ms     2441rpm
retlw   19h   ;2,5ms     2473rpm
retlw   19h   ;2,5ms     2505rpm
retlw   19h   ;2,5ms     2538rpm
retlw   18h   ;2,4ms     2572rpm
retlw   18h   ;2,4ms     2606rpm
retlw   17h   ;2,3ms     2642rpm
retlw   17h   ;2,3ms     2679rpm
retlw   16h   ;2,2ms     2716rpm
retlw   16h   ;2,2ms     2755rpm
retlw   15h   ;2,1ms     2795rpm
retlw   15h   ;2,1ms     2836rpm
retlw   14h   ;2ms     2878rpm
retlw   14h   ;2ms     2921rpm
retlw   14h   ;2ms     2965rpm
retlw   13h   ;1,9ms     3011rpm
retlw   13h   ;1,9ms     3059rpm
retlw   12h   ;1,8ms     3107rpm
retlw   12h   ;1,8ms     3158rpm
retlw   11h   ;1,7ms     3210rpm
retlw   11h   ;1,7ms     3263rpm
retlw   11h   ;1,7ms     3319rpm
retlw   10h   ;1,6ms     3376rpm
retlw   10h    ;1,6ms    3435rpm
retlw   0Fh    ;1,5ms    3496rpm
retlw   0Fh    ;1,5ms    3560rpm
retlw   0Eh    ;1,4ms    3626rpm
retlw   0Eh    ;1,4ms    3694rpm
retlw   0Dh    ;1,3ms    3765rpm
retlw   0Dh    ;1,3ms    3838rpm
retlw   0Dh    ;1,3ms    3914rpm
retlw   0Ch    ;1,2ms    3994rpm
retlw   0Ch    ;1,2ms    4077rpm
retlw   0Bh    ;1,1ms    4163rpm
retlw   0Bh    ;1,1ms    4252rpm
retlw   0Ah    ;1ms    4346rpm
retlw   0Ah    ;1ms    4444rpm
retlw   0Ah    ;1ms    4546rpm
retlw   9h    ;1ms    4653rpm
retlw   9h    ;0,9ms    4765rpm
retlw   8h    ;0,9ms    4883rpm
retlw   8h    ;0,8ms    5006rpm
retlw   7h    ;0,8ms    5136rpm
retlw   7h    ;0,8ms    5273rpm
retlw   7h    ;0,7ms    5417rpm
retlw   6h    ;0,7ms    5569rpm
retlw   6h    ;0,6ms    5729rpm
retlw   5h    ;0,6ms    5899rpm
retlw   5h    ;0,5ms    6080rpm
retlw   4h    ;0,5ms    6272rpm
retlw   4h    ;0,5ms    6476rpm
retlw   4h    ;0,4ms    6693rpm
retlw   3h    ;0,4ms    6926rpm
retlw   3h    ;0,3ms    7176rpm
retlw   2h    ;0,3ms    7443rpm
retlw   2h    ;0,2ms    7732rpm
retlw   2h    ;0,2ms    8044rpm
retlw   1h    ;0,2ms    8381rpm
retlw   1h    ;0,1ms    8748rpm
retlw   0h    ;0,1ms    9149rpm
retlw   0h    ;0ms    9587rpm
retlw   0h    ;0ms    10070rpm
retlw   0h    ;0ms    10604rpm
retlw   32h    ;5ms
retlw   32h    ;5ms
retlw   32h    ;5ms
retlw   32h    ;5ms
retlw   32h    ;5ms
retlw   32h    ;5ms
;   *********** END OF YOUR OWN VALUES ******************************
retlw 8h      ; in case of overlap
; line544
;
;        reset vector
;
;
org 300h         ; if the program is loose,
;
;
;
        goto start            ; It goes back home.
        ;
        ;
;===================JMJ================================
;Test routine, sends ignition pulses to the thyristor at 4hz/140hz,
;selectable by rotor input.
testdelay
;     btfss test        ; checks the jumper to disconnect test mode
;     goto start
      bsf rpmmax
      bcf   led
     btfss rotor       ; checks hall device.   slow test if low, fast test if high
     goto slowtest
     goto fasttest
slowtest
      bsf   led
; Delay = 0.005 seconds
; Clock frequency = 4 MHz
;4998 cycles
      movlw 0xE7
      movwf d1
      movlw 0x04
      movwf d2
Delay_0
      decfsz      d1, f
      goto $+2
      decfsz      d2, f
      goto Delay_0
      goto $+1
      goto trigger           ; triggers the thyristor
      goto testdelay
fasttest
      bsf led
; Delay = 0.3 seconds
; Clock frequency = 4 MHz
;299998 cycles
      movlw 0x5F
      movwf d1
      movlw 0xEB
      movwf d2
Delay_1
      decfsz      d1, f
      goto $+2
      decfsz      d2, f
      goto Delay_1
      goto $+1
      goto trigger           ; triggers the thyristor
      goto testdelay
trigger
      bsf coil          ; set output
      bcf revcoil       ; set reverse output
; Delay = 0.002 seconds
; Clock frequency = 4 MHz
      movlw 0x8F
      movwf d1
      movlw 0x02
      movwf d2
Delay_3
      decfsz     d1, f
      goto $+2
      decfsz     d2, f
      goto Delay_3
                  ;2 cycles
     goto   $+1
      bcf coil
      bsf revcoil
      goto testdelay
        ;
;=============================End JMJ=============================
        end