Manually Setting TIFR

Go To Last Post
8 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I was wondering if it would be possible to trigger a timer overflow interrupt by writing to the TOV0 bit in the TIFR. The TIMSK is set and the Global interreupts are enabled of course.

My attempt to do this in VMLab with the following code for the ATtiny22 has failed to trip the interrupt and resulted the int0 bit in the GIFR flag getting set instead without trigging any interrupt at all.

forever:
   sbic $16,3      ; Is key pressed?
   rjmp forever    ; No
   ldi tmp,$02     ; Yes
   out $38,tmp     ; Attempt to manually set TOV0 flag
rjmp forever 

Is this how the device would actually respond or is this a bug in the device model?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I don't know for the tiny22, but usually the datasheet states "TOV1 is automatically cleared when the Timer/Counter1 Overflow Interrupt Vector is executed. Alternatively, TOV1 can be cleared by writing a logic one to its bit location." So trying to trigger the interrupt by writing 1 to TOV1 will result in actually clearing any pending TOV1-interrupt.

/Martin.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The timer is stopped. I'm was just wondering if I create a software interrupt that way.

Although you just gave me an idea. If I have the timer count set to 255 to start with, the overflow will happen immediately.

I suppose it would just be less work to call a subroutine.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
I was wondering if it would be possible to trigger a timer overflow interrupt by writing to the TOV0 bit in the TIFR.

Nope. Writing an interrupt flag to 1 clears the flag. There is no way to manually set it.

Regards,
Steve A.

The Board helps those that help themselves.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

if you want a 'soft' interrupt, then the usual method is to enable an external interrupt and toggle that port bit with your code. However the need to do this suggests that you're wanting to do what could become an ugly kludge.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Kartman wrote:
if you want a 'soft' interrupt, then the usual method is to enable an external interrupt and toggle that port bit with your code. However the need to do this suggests that you're wanting to do what could become an ugly kludge.
Actually I had thought about that too. This whole question was just a what if that came to mind as I explore the basics of the ATtiny22. Seeing as it lacks a soft interrupt I got to wondering what possible work around there might be. And giving it some thought, I decided that is was all just extraneous elaboration, that a call would just be easier and simpler.

Thanks,

Fred

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Instead of this kind of software interrupt you could just call a function or a routine written from you.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

This was just a little thought experiment rather than a serious idea.

And, I got it working. :)

Pressing button 1 connected to pb1/int0 will cause an external interrupt and light up LED 1.

Pressing button 2 connected to pb3 will cause a soft interrupt and light up LED 2.

Pressing button 0 will reset the whole thing and turn off all LEDs.

k0 vss reset
r0 vdd reset 100k
k1 vss pb1
k2 vss pb3
d1 vdd n001
r2 n001 pb0 300
d2 vdd n002
r3 n002 pb2 300

***

.def  tmp	=r16
.def  flg	=r17

; Define here Reset and interrupt vectors, if any


	rjmp reset	; Addr $00
	rjmp interrupt	; Addr $01
	reti		; Addr $02

; Program starts here after Reset

reset:
	ldi tmp,RAMEND
	out spl,tmp    		; Initialize stack pointer
	ldi flg,0	
	ldi tmp,0				
	out $34,tmp		; Clear MCUSR
	sbi $18,0		; Set pb0 high--LED off
	sbi $17,0		; Set pbo for output
	sbi $18,1		; Set pb1 high--ready for pull down
	sbi $17,1		; Set pb0 for output--k1
	sbi $18,2		; Set pb2 high--LED off
	sbi $17,2		; Set pb2 for output
	sbi $18,3		; Set pb3 high--ready for pull down
	cbi $17,3		; Set pb3 for input--k2
	ldi tmp,2
	out $39,tmp		; Set TIMK
	ldi tmp,$40
	out $3b,tmp    		; Set GIMSK
	ldi tmp,$80
	out $3f,tmp    		; Enable interrupts

forever:
	sbic $16,3		; Key 2 pressed
	rjmp forever
	ldi flg,1		; Set flag for soft interrupt
	cbi $18,1		; Set bp1 low--triggering int0
	rjmp forever

interrupt:
	sbrc flg,0		; Was interrupt external?
	rjmp soft_int			
	cbi $18,0      		; Yes, turn on LED 1
	rjmp restart

soft_int:
	cbi $18,2		; No, turn on LED 2

restart:
	sbi $18,1		; Reset pb1 high
	ldi flg,0  		; Reset interrupt flag
	out $3f,tmp    		; Re-enable interrupts
	reti           		; Onward...