Assuming you do not use the NOSAVE option when defining the IRQ, you already waste around 100 clock cycles while Bascom saves most of the registers, does your ( admittedly simple ) code, and then recovers the registers. You can damatically reduce the IRQ service time by using ASM to do the actual operation, only saving the couple of registers you actually use, and then you have plenty of time to do the couple of additional compares to check which piece of code you actually use in the ISR, based on what flags are set in the main progrm.
Something like:[code:1:9a4b765a45]
dim A as byte 'use a byte for flag
on int0 gosub int0_isr nosave 'define ISR, tell Bascom not to save any regs
'in main
A = 1 'set the flag value
'in the ISR
#asm 'use asm
int0_isr:
push r16 'save used reg
in r16,sreg 'ALWAYS save sreg !!!
push r16
lds r16,{A} 'get value of A from main
tst r16 'sets processor flags based on value in r16, in particular Z flag if A was zero
sbi portd,7 'set bit in portd.7
breq t200_ns 'branch around extra delay code based on Z flag, 1 clock if branch not taken, 2 if is
'else use longer delay
nop 'each nop is 1 clock, add more for a longer delay
'for even longer delays, set a value in r16 and count it down to zero in a loop
'you could even use the value of A passed as a delay counter, then you can control it from main
t200_ns:
nop 'waste a cycle
cbi portd,7 'reset port bit
pop r16 'recover used reg
out sreg,r16 'recover sreg
pop r16
rti
#end asm
[/code:1:9a4b765a45]
Note that the ISR code sets the output port, then tests for the flag value to get the delay
That way, you avoid complicated branches and multiple bits of code depending on what the flag setting is.
I never tested how many clocks the Bascom NOP command takes, it may well be longer than a NOP in ASM.
There are many other ways of doing similar delays in ASM, when you want really precise and small timing intervals, learning how to do it in ASM well pays the time to learn how to do it.
↧