You are on page 1of 12

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

You might also like