
timer		EQU	38h	;preset value for timer interrupt (100µs @ 24MHz)
SCR		EQU	P3.5	;Pin 9, output that fires SCR, active LOW
magnet		EQU	P3.6	;input comparator for pickup trigger, 12 = +, 13 = - input
test		EQU	P1.2	;test to see comp output Pin 14

;	R0	counts 5*100µs = 500µs SCR control
;	R1	generates 4*100µs = 400µs period
;	R2	counts the revolution length between two interrupts in 400µs steps
;	R3	counts the required delay (pickup pulse to ignition) in 100µs steps

ORG  0	            ;Start at 000 after Reset
AJMP start              ;Reset

org 00Bh             	;interrupt vector timer interrupt 0  8051
AJMP TIMER              ;TIMER  interrupt routine 

start:                 	;program start 
MOV SP, #45h		;set stack pointer 
MOV TH0, #timer		;reload timer 100µs 
MOV TL0, #timer
MOV TMOD, #22h		;internal timer mode 2
MOV IE, #82h            ;allow timer 0 Interrupt 
SETB TR0			;start timer 0
MOV DPTR, #LUT1		;Data pointer to LUT1
;reset variables:
MOV R0, #01h		;R0 = 1 means SCR off
MOV R1, #04h		;4*100µs = 400µs
MOV R2, #FFh		;prevent misfire on first revolution at startup

SETB PT1			;highest Prio for timer1
SETB magnet			;make magnet an input!!

mainloop:
JB magnet, mainloop	;wait for negative pulse from pickup
CLR test			;comp output LOW, here negative pulse from pickup
MOV R3, #0			;first R3 = 0, might be a different value later
MOV A, R2			;R2 counted in interrupt, contains 400µs counts between two pickup pulses
ADD A, #01h			;RPM > 588 (R2 < 255)? Then OK, otherwise quit firing (R2 = 255)
JC label6			;quit if R2 = 255
ADD A, #ECh			;RPM < 8000? Then OK, otherwise quit firing (R2 < 13h)
JNC label6			;if R2 too small (RPM too high) quit firing

;here RPM OK, enable firing
MOV A, #FFh		;turn LUT upside down (R2 = 255 reads first value, 254 second and so on)
CLR C			;substract with no borrow
SUBB A, R2		;load period (R2) from last interrupt (difference between two rounds)
MOVC A, @A+DPTR	
MOV R3, A		;send value to delay counter, delays ignition R3*100µs
label6:
MOV R1, #04h	;4*100µs = 400µs, needed in interrupt
MOV R2, #0		;for next period count, counts up every 400µs in interrupt
MOV TL0, #FEh	;make sure next interrupt comes soon
wait:
JNB magnet, wait	;wait until pickup pulse is over
SETB test		;comp output HIGH
MOV DPTR, #LUT1	;Data pointer to LUT1
AJMP mainloop

;************ Timer 0 Interrupt every 100µs
TIMER:
PUSH PSW
CPL P3.1			;Toggle Pin3 every 100µs, for testing if µP is running fine
DJNZ R1, label1		;here 4*100µs loop
MOV R1, #04h		;go through loop every 4*100µs (400µs)
CJNE R2, #FFh, label2	;if R2 = FF maximum period, don't increase any more
AJMP label1
label2:
INC R2			;here rev > 588/min (R2 < 255)
label1:
CJNE R3, #0h, label4	;if R3 still > 0 count down until SCR trigger
AJMP label3
label4:
DJNZ R3, label3		;wait with trigger SCR until R3 = 0
MOV R0, #05h		;05h*100µs = 500µs length of SCR trigger impulse
CLR SCR			;trigger SCR
label3:
DJNZ R0, label5		;don't turn off SCR when R0 > 1
SETB SCR			;when R0 = 1 time is over, turn off SCR
MOV R0, #01h		;jump out of loop only during firing of SCR
label5:
POP PSW 
RETI
;End timer interrupt


;here calculated straight line: 6000RPM:36°, 600RPM:9°, 1200RPM:12°, pickup 58° before top

LUT1:
DB 139,138,138,137,137,136,136,135,134,134,133,133,132,131,131,130,130,129,129,128
DB 127,127,126,126,125,125,124,123,123,122,122,121,121,120,119,119,118,118,117,116
DB 116,115,115,114,114,113,112,112,111,111,110,110,109,108,108,107,107,106,105,105
DB 104,104,103,103,102,101,101,100,100,99,99,98,97,97,96,96,95,95,94,93
DB 93,92,92,91,90,90,89,89,88,88,87,86,86,85,85,84,84,83,82,82
DB 81,81,80,79,79,78,78,77,77,76,75,75,74,74,73,73,72,71,71,70
DB 70,69,69,68,67,67,66,66,65,64,64,63,63,62,62,61,60,60,59,59
DB 58,58,57,56,56,55,55,54,53,53,52,52,51,51,50,49,49,48,48,47
DB 47,46,45,45,44,44,43,43,42,41,41,40,40,39,38,38,37,37,36,36
DB 35,34,34,33,33,32,32,31,30,30,29,29,28,27,27,26,26,25,25,24
DB 23,23,22,22,21,21,20,19,19,18,18,17,17,16,15,15,14,14,13,12
DB 12,11,11,10,10,9,8,8,7,7,6,6,5,4,4,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2

END