Clearing a set interrupt

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

Hi,

I am triggering on the rising edge of a waveform, for ext0 and then I want to ignore the rising edges while I am in that routine. I don't want one to accumulate IOW. The datasheet says that there are two kinds of interrupts, those that will store interrupts while in an interrupt routine, and those that don't. But it doesn't say how to determine which is which.

I am pretty sure that this is one of the ones that is stored, so I want to clear it right before I exit the interrupt.

The datasheet says that when the int0 flag is set, it is written to a one, but it later says that if I want to clear it, that I would write a one to it. So, in both cases, the one is both set and unset, as far as I can tell by the datasheet for the Mega16 (page sixty eight ).

Can someone please explain what they are saying as I find it unlikely that they are really contradicting themselves, and find it more likely that it is me that is not understanding.

Thank you for your time,

Daniel

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

Hi Daniel,

When an interrupt occurs, the flag is set to 1 by the hardware. To clear this flag you write a 1 to it, and the hardware will set it to 0.

-Geir

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

geir wrote:
Hi Daniel,

When an interrupt occurs, the flag is set to 1 by the hardware. To clear this flag you write a 1 to it, and the hardware will set it to 0.

-Geir

But suppose you want to trigger an interrupt with software - how would you do that, if it can indeed be done? I can visualise a situation where you might want to run an ISR without an interrupt actually occuring.

Regards: Jim Ford

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

to have a software interrupt, just write a logic 1 to the interrupt flag, say GIFR for external interrupt. :)

-jay

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

Hi every body,
Does this mean the interrupt bits toggle whenever you write a 1 ?
rgds

Parthasaradhi Nayani

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

Quote:
to have a software interrupt, just write a logic 1 to the interrupt flag, say GIFR for external interrupt.

Um, this is incorrect.

To my knowledge, all bits defined for GIFR/EIFR are write-clear, so it's
impossible for the CPU to directly set them to 1. What you Can do is set
e.g. PD2 to output and write a 1 to that to trigger an INT0.

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

The only way to create a software interrupt (i think) is to configure an external interrupt to be edge triggered, configure the pin as an output and then write to the port.

If you are using the simulator, you can trigger interrupts by clicking on the interrupt flag in the IO view.

-Geir

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

Common misunderstanding here writing a 1 to the interrupt flag by accessing the flag via software clears the interrupt it will not set it.

If you have a think it sort of makes sense. The interrupt has SET a LATCH and you are RESETTING the latch. So you are not just writting a 1 or 0 to a ram location. Think logic gates and it becomes clear.
Mike

Keep it simple it will not bite as hard

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

The problem I am having is that I am attempting to generate a delay on a waveform referenced from the leading edge.

It appears on the scope as if sometimes it will not see anything at all for some time, and then it will work correctly for a time. Below is the code I am using. The values for the delay function are being varied frequently and then recompiled, and it will work correctly with some values for the delay function but not with others.

If someone can determine why sometimes it fails to react to the trigger and generate an interrupt, (or at least appears to) I would appreciate it.

Thanks,

Daniel

// External Interrupt 0 service routine
interrupt [EXT_INT0] void ext_int0_isr(void)
{
// This rising edge triggered interrupt function
//outputs a waveform on PORTA by using delay function
// after generating delay it looks to be sure that the input is not presently high
// clears possible accumulated interrupt and then exits

//delay_ms(3); delay after trigger but before turning on portA

PORTA=0xff; //turn on porta
delay_us(600); //pulse high period in microseconds
//delay_ms(6); //pulse high period in milliseconds
PORTA=0x00; //turn off porta
delay_us(600); //delay until function can exit in microseconds
delay_ms(20); // delay until function can exit in milliseconds

//make sure that wave is not currently high before exiting

while(PIND.2==1 );

//clear possible accumulated interrupt
//if delay is as long as two input pulses, then interrupt needs to be cleared so that the stored one does
//not set another trigger.
#asm
push r16
push r17

in r16,0x3a //0x3a is the address of GIFR
ldi r17,64 /this doesn't quite seem right, but this is
or r16,r17
out 0x3a, r16

pop r17
pop r16
#endasm

}

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

Oops, never mind, it was a problem with the scope.

Also, (remembering that I am a newbie) in reference to the above, I saw a specific statement in the datasheet for the mega16 that said that if PORTD pin 2 was configured as an output and then INT0 was enabled, that one could generate a software interrupt by writing a one to pin 2 on port d.

Sorry for the coding question when it was just a problem with the scope,

Daniel

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

Firstly, there is no need for the inline assembly in your code, you can easily clear any pending interrupts with a single line of C code.

GIFR = 0x40; // clear any pending INT0's - does not clear any other pending INT's

Secondly, your ISR will run for a relatively long time, this may cause other interrupts (if you have them) to go unserviced for a long time. You can use a timer and the OCnX pin to do this for you in hardware.

Thirdly, if you have other interrupts, if one of those is being serviced, it will delay the servicing of this interrupt. Thus resulting in additional delay of your output waveform.

Writing code is like having sex.... make one little mistake, and you're supporting it for life.