Edward,
I'm not 100 % sure what the arbitrary time is. One thing is I'm on a 2MHZ
Bus clk, I would like to jump up to 16, but not sure if I can just do that
right away. I'm on a dev board and use their software to write to the chip,
and think they have timing characteristics built into their code based on
the clk speed they sent the board operating on.
Basically for my handlers, I have time_stamps of when I need to change
state. So I always store the current time stamp and use that and the next
time stamp to calculate the # of ticks until the next interrupt. Wording
may be a bit confusing down below. Logic in beginning of handler is to
decide if end of index has arrived and need to start at beginning. State
and Time Stamp arrays are out of phase by one index.
So I also calculated the number of cycles the program should take and in the
worst case shouldn't be more than 140 cycles. which should be under 100uS
with my bus speed. What's the lapse time between when the interrupt occurs,
and the handler starts executing? large, or something like exiting the
interrupt (10 cycles)? When I set and clear a port bit on entry and exit of
interrupt and measure that on a scope I get something like 120uS, approx
representation of handler cycle time.
;********************************************************************
;OC_INIT -- Initialization of the Interuptfor OC0
;Going to set up a periodic interupt on OC0-2 (Output Compare 0-2)
;Prescale is set to 3
;********************************************************************
OC_INIT:
sei ;disable interrupts
bset DDRP, #$FF ;make port P output
bset DDRT, #$FF ;make port T output
bset DDRM, #$FF ;make port M output
clr PTP ;make port P outputs all zero
clr PTT ;make port T outputs all zero
clr PTM ;make port M outputs all zero
bset TIOS, #$07 ;set interrupt on OC0-2
movb #$90, TSCR1 ;set TEN (Timer Enable) & fast clear
movb #$03, TSCR2 ;set Prescaler to make counter ticks operate at
;250kHz instead of E-clk of 8MHz
bset TIE, #$07 ;Arm C[0-2]F,
movb #$07, TFLG1 ;clear C[0-2]F (OC[0-2] Flag)
OC_RE_INIT:
ldd TCNT ;load current clock tick in d
addd #$4E20 ;offset the clock tick by 80 ms for first interrupt
std TC0 ;store the next interrupt time in Timer Capture
Channel 0
std TC1 ;store the next interrupt time in Timer Capture
Channel 1
std TC2 ;store the next interrupt time in Timer Capture
Channel 2
clr OXYGEN_INDEX1
clr FUEL_INDEX1
clr SPARK_INDEX1
clr OXYGEN_PREV_DELAY
clr FUEL_PREV_DELAY
clr SPARK_PREV_DELAY
ldaa #$02
staa OXYGEN_INDEX2
staa FUEL_INDEX2
staa SPARK_INDEX2
;cli ;initialize interrupts
rts ;return from subroutine
;********************************************************************
;OC0_HANDLER -- Toggles the ouptut to PORTP(0-2) on interrupt
;Test state of PORTP and apply the opposite to it
; Incrementing loop is working. checked output of both indexes !
;********************************************************************
OC0_HANDLER:
;bset TFLG1, #$01 ;Acknowledge interupt and clear flag
ldaa OXYGEN_NUM_STATES
deca
cmpa OXYGEN_INDEX1
bne COMP2_OK0
bclr OXYGEN_INDEX2, #$FF
COMP2_OK0:
ldaa OXYGEN_INDEX1 ;Check Current Index
cmpa OXYGEN_NUM_STATES
bne INDEX_OK0 ;Index is less than 6
bclr OXYGEN_INDEX1, #$FF ;reset ENG1_INDEX1 to zero
ldd #$0000
std OXYGEN_PREV_DELAY
INDEX_OK0:
ldy #OXYGEN_TIMESTAMP ;put base address of TIMESTAMP Array in Y
ldaa OXYGEN_INDEX2 ;retrieve current index
ldd a,y ;index the array
subd OXYGEN_PREV_DELAY
addd TC0 ;Calc next State Change
std TC0 ;Load next State Change.
ldy #OXYGEN_TIMESTAMP ;put base address of TIMESTAMP Array in Y
ldaa OXYGEN_INDEX2 ;retrieve current index
ldd a,y ;index the array
std OXYGEN_PREV_DELAY
ldy #OXYGEN_STATES ; put base address of STATE Array in X
ldaa OXYGEN_INDEX1 ;retrieve current index
ldab a,y ;index the array
eorb PTP ;
stab PTP ;make state change on PORT P
inc OXYGEN_INDEX1 ;retrieve current index
ldaa OXYGEN_INDEX2 ;retrieve previous index for delay array
adda #$02 ;increment by 2 (16-bit)
staa OXYGEN_INDEX2 ;store next index value
rti ;return from subroutine
;********************************************************************
;OC1_HANDLER -- Toggles the ouptut to PORTP(0-2) on interrupt
;Test state of PORTP and apply the opposite to it
; Incrementing loop is working. checked output of both indexes !
;********************************************************************
OC1_HANDLER:
;bset TFLG1, #$02 ;Acknowledge interupt and clear flag
ldaa FUEL_NUM_STATES
deca
cmpa FUEL_INDEX1
bne COMP2_OK1
bclr FUEL_INDEX2, #$FF
COMP2_OK1:
ldaa FUEL_INDEX1 ;Check Current Index
cmpa FUEL_NUM_STATES
bne INDEX_OK1 ;Index is less than 6
bclr FUEL_INDEX1, #$FF ;reset ENG1_INDEX1 to zero
ldd #$0000
std FUEL_PREV_DELAY
INDEX_OK1:
ldy #FUEL_TIMESTAMP ;put base address of TIMESTAMP Array in Y
ldaa FUEL_INDEX2 ;retrieve current index
ldd a,y ;index the array
subd FUEL_PREV_DELAY
addd TC1 ;Calc next State Change
std TC1 ;Load next State Change.
ldy #FUEL_TIMESTAMP ;put base address of TIMESTAMP Array in Y
ldaa FUEL_INDEX2 ;retrieve current index
ldd a,y ;index the array
std FUEL_PREV_DELAY
ldy #FUEL_STATES ; put base address of STATE Array in X
ldaa FUEL_INDEX1 ;retrieve current index
ldab a,y ;index the array
eorb PTT ;
stab PTT ;make state change on PORT P
inc FUEL_INDEX1 ;retrieve current index
ldaa FUEL_INDEX2 ;retrieve previous index for delay array
adda #$02 ;increment by 2 (16-bit)
staa FUEL_INDEX2 ;store next index value
rti ;return from subroutine
;********************************************************************
;OC2_HANDLER -- Toggles the ouptut to PORTP(0-2) on interrupt
;Test state of PORTP and apply the opposite to it
; Incrementing loop is working. checked output of both indexes !
;********************************************************************
OC2_HANDLER:
;bset TFLG1, #$04 ;Acknowledge interupt and clear flag
ldaa SPARK_NUM_STATES
deca
cmpa SPARK_INDEX1
bne COMP2_OK2
bclr SPARK_INDEX2, #$FF
COMP2_OK2:
ldaa SPARK_INDEX1 ;Check Current Index
cmpa SPARK_NUM_STATES
bne INDEX_OK2 ;Index is less than 6
bclr SPARK_INDEX1, #$FF ;reset ENG1_INDEX1 to zero
ldd #$0000
std SPARK_PREV_DELAY
INDEX_OK2:
ldy #SPARK_TIMESTAMP ;put base address of TIMESTAMP Array in Y
ldaa SPARK_INDEX2 ;retrieve current index
ldd a,y ;index the array
subd SPARK_PREV_DELAY
addd TC2 ;Calc next State Change
std TC2 ;Load next State Change.
ldy #SPARK_TIMESTAMP ;put base address of TIMESTAMP Array in Y
ldaa SPARK_INDEX2 ;retrieve current index
ldd a,y ;index the array
std SPARK_PREV_DELAY
ldy #SPARK_STATES ; put base address of STATE Array in X
ldaa SPARK_INDEX1 ;retrieve current index
ldab a,y ;index the array
eorb PTM ;
stab PTM ;make state change on PORT P
inc SPARK_INDEX1 ;retrieve current index
ldaa SPARK_INDEX2 ;retrieve previous index for delay array
adda #$02 ;increment by 2 (16-bit)
staa SPARK_INDEX2 ;store next index value
rti ;return from subroutine
Lots of Thanks,
Matt
On Fri, May 9, 2008 at 12:06 AM, Edward Karpicz <karpicz@...> wrote:
> Matt wrote:
>
> > Hi guys,
> >
> > So I have two output compare interrupts setup such that the handlers
> > look up in a circulating table (one for each handler) the state a port
> > should be in and when the next interrupt should occur, then sets the
> > port and loads the next interrupt into TC#. This table is dynamic
> > based on user input. Anyway everything seems to work as I planned
> > when interrupts are not occurring at a high speed rate and or close
> > together. However, my needs are for a very close, sometimes the same
> > time, interrupts. The issue (confusion) I'm experiencing is when I
> > need two interrupts to occur at the same time and then the two same
> > interrupts to occur again .1 mS later. So I know I'm limited by the
>
> 100uS is a lot even for 8MHz busclock. Your circulating table etc should
> work.
>
> > length of my interrupt handler, however here's the weird thing. I
> > would expect in this scenario to see:
> > OC_0 Interrupt occur at T(0mS)
> > 0C_1 Interrupt occur at T(0mS+cycle time of OC_0_HANDLER)
> > OC_0 Interrupt occur at T(.1mS, assuming cycle time <.1ms)
> > 0C_1 Interrupt occur at T(.1mS+cycle time of 0C_0_Handler)
> >
>
> I see nothing wrong above.
>
> > However what I see is this:
> > OC_0 Interrupt occur at T(0mS)
> > OC_0 Interrupt occur at T(.1mS)
> > 0C_1 Interrupt occur at T(.1mS+some arbitrary time)
> > 0C_1 Interrupt occur at T(.1mS+some arbitrary time+.1uS)
> >
>
> Let me guess, is this some arbitrary time close to 2^16 * timer_tick? I
> think it's just a well known wrong flag-clear sequence. Show us your code,
> at least show how are you clearing timer flags.
>
> Edward
>
> > So I haven't been a good engineer and calculated exactly the cycle
> > time of the handlers, but I'm assuming since, even though in the wrong
> > order, I see 0C_0 occur twice within the distance they're programmed
> > to occur at, my cycle time is less than .1mS, which will suffice for
> > my tolerance.
> >
> > Any ideas to why I might be seeing this?
> > Thanks,
> > Matt
> >
> >
> > ------------------------------------
> >
> > Yahoo! Groups Links
> >
> >
> >
> >
>
>
>
[Non-text portions of this message have been removed]