Shop OBEX P1 Docs P2 Docs Learn Events
Interrupt firing twice in a row??? — Parallax Forums

Interrupt firing twice in a row???

dkemppaidkemppai Posts: 315
edited 2004-10-29 22:46 in General Discussion
ok guys,

I'm having trouble with an interrupt routine firing twice in a row.

The interrupt is an external interrupt, set on pin RB0.
The interrupt routine fires on RB.0 rising edge. The routine
is a simple routine, that sets Pin RC.1 High, runs a delay, and
then sets RC.1 Low before RETI.

If I debug the code, it runs as expected. However, if I run it at
50Mhz, with a square wave on RB.0, I see that the interrupt runs
twice in a row.

I'm not sure what is going on. Any suggestions?

Thanks,
-Dan

Here is an example code that displays this problem:

;
Program Start
··NOCASE···;No Case Sensitive ASM
··DEVICE·SX28L··;28 pin chip
··DEVICE· OSCHS2··;(OSC or External TTL OSC)
··DEVICE·STACKX··;Use the Extended Stack.
··DEVICE· IFBD··;Disable Internal Feedback.
··DEVICE· TURBO··;Turbo Mode
··IRC_CAL·IRC_FAST·;(Faster programming)
··FREQ·50_000_000 ·;START WITH A 50MHz Clock

··RESET ·ResetVector
;
CONSTANTS
;Setup ADC Pins.
DataIn EQU·RB.0
Debug0·EQU·RC.0
Debug1·EQU·RC.1
Debug2·EQU·RC.2
Debug3· EQU·RC.3

;Setup Bank Constants
Bank7·EQU ·$F0
;
VARIABLES
ORG·$08
Count1··DS·1··;Allocate 1 Byte.
Count2··DS·1··;Allocate 1 Byte.

··ORG·Bank7·;Byte·Start in Memory Bank 7
DataInCnt1·DS·1·; F0·Data In Counter 1
;
INTERRUPT ROUTINE
··ORG·0
··SetB·Debug1
··MOV·DataInCnt1,#10
··;Delay
DataReadLp1·DECSZ·DataInCnt1
··JMP·DataReadLp1

··CLRB·Debug1··;Test Debug Bit.
··;Clear the Pending Register to allow interrupts.
··MODE ·#09··;Set Mode for Pend reg Check.
··MOV ·!rb,#%00000000·;Clears the Pending Register.
··RETI···;Exit The Interrupt Routine
;
End INTERRUPT ROUTINE

;
Reset Vector is here
ORG··$1FE···;Reset on Page $00
ResetVector·JMP·@Page1··;Now Jump to Page $01
;
Start of Pogram on Page 01
ORG ··$200···;Start on Page 01
Page1
··CLRB·Debug0
··CLRB·Debug1
··CLRB·Debug2
··CLRB·Debug3

··;Disable RTCC Interrupts.
··MOV·!OPTION, #%01000000

··;Set Edge Detection Pins (Poat B).
··MODE·$0A··; 0 = Rising Edge, 1 = Falling Edge
··MOV·!rb,#%00000000·;

··;Setup Schmitt Trigger
··MODE ·$0C
··MOV·!rb,#%11111110·;0 = Schmitt, 1 = Normal
··MOV·!rc,#%11111111·;
··;Set Logic Levels
··MODE ·$0D
··MOV·!ra,··· #%1111·; 0 = CMOS, 1 = TTL
··MOV·!rb,#%11111111·;
··MOV·!rc,#%11111111·;
··;Set PULL-UP Resistors
··MODE·$0E
··MOV·!ra,··· #%1111·; 0 = pullup, 1 = Disabled
··MOV·!rb,#%11111111·;
··MOV·!rc,#%11111111·;
··;Set Directions
··MODE ·$0F··
··MOV·!ra,··· #%0000·; 0 = Output, 1 = Input
··MOV·!rb,#%00000001·;
··MOV·!rc,#%00000000·;
··;Clear the Pending Register to allow interrupts.
··MODE ·#09··;Set Mode for Pend reg Check.
··MOV ·!rb,#%00000000·;Clears the Pending Register.
··;Set Mode to allow Wakeup (Edge Interrupts).
··MODE·$0B··; 0 = WakeUp, 1 = Normal
··MOV·!rb,#%11111110·;
··JMP ·@MainProg
;
End of Initialization Routine.
;
Main Program
MainProg·;Main program Polling Loop
··NOP
··SETB ·Debug3
··NOP
··CLRB·Debug3
MainTestloop·NOP
··JMP ·MainProg
;
·End of Main Program Loop
·

Comments

  • BeanBean Posts: 8,129
    edited 2004-10-29 13:33
    What frequency square wave are you feeding in ?
    Check for ringing at the input.

    Bean.
  • allanlane5allanlane5 Posts: 3,815
    edited 2004-10-29 13:44
    I've had this problem with a PIC. It may be ringing -- that's actually most likely. It may also be that the ISR just fires once for going up, and once for going down. It also may be that the ISR actually does fire twice for each transition.

    Also, you should NEVER NEVER NEVER run a delay in an ISR.· Toggle the pin, if that will work.· Set a flag, and use the flag in your 'main' routine to pulse the pin.·

    An ISR is an Interrupt.· It's something in the real-world saying 'notice me'.· Your ISR should be fast and quick -- do something simple to record the interrupt and return.· While you are in the ISR you are ignoring other things that could interrupt, which is not good.

    Post Edited (allanlane5) : 10/29/2004 1:46:57 PM GMT
  • dkemppaidkemppai Posts: 315
    edited 2004-10-29 15:14
    Hi.

    Just to answer a few questions right off the bat, I've scoped the input and there is no ringing on it. The test signal is a relatively slow rising edge signal from a TTL sig-gen coming down a 50Ohm coax. (It exponentially reaches the logic "high" several uS before the interrupt routine completes)

    I did find a solution that I tried to post earlier, but my ISP died.

    Basically, it seems that you can’t follow the MOV !rb,#%00000000 with the RETI instruction.

    I placed a NOP between them, and the problem goes away. I wish I had my digital camera here at work... ...or my Scope from home (with FDD built in), I'd post a pic of the signal in both cases.

    I think it's a glitch in the chip!





    Try the code with a scope and sig gen...·· ...let me know what you think.



    This code won't work correctly...· ...it runs the Interrupt twice in a row.
    ··MODE ·#09··;Set Mode for Pend reg Check.
    ··MOV ·!rb,#%00000000·;Clears the Pending Register.
    ··RETI···;Exit The Interrupt Routine


    This one will fire only once...
    ··MODE ·#09··;Set Mode for Pend reg Check.
    ··MOV ·!rb,#%00000000·;Clears the Pending Register.
    · NOP
    ··RETI···;Exit The Interrupt Routine
  • BeanBean Posts: 8,129
    edited 2004-10-29 15:26
    It's not a glitch, it has to do with the instruction pipeline.
    The instruction is executed, but the port doesn't change till further down the pipeline.

    Bean.
  • Guenther DaubachGuenther Daubach Posts: 1,321
    edited 2004-10-29 15:34
    Hi,

    actually,

    MOV !rb, #%00000000 is a compound instruction which is replaced by

    mov w, #%00000000
    mov !rb, w

    The mov !rb, w is not a "regular" move instruction here, as it actually exchanges the contents of w and the pending register, i.e. after this instruction w contains the current bit pattern in the pending register, and the pending register is zero.

    Usually, w and the pending register are exchanged close to the entry of an ISR to determine which port B pin fired the interrupt. Of course, when you know that only pin can fire the interrupt only, there is no need to test it. like in your application.

    The nop adds one more clock cycle which overcomes the instruction pipeline effect. On the other hand, you can also place the instruction somewhere at the beginning of the ISR. As clearing the pending bits does not mean that interrupts are enabled again (this is only done by the reti), it does not matter where you do the exchange.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Greetings from Germany,


    G
  • dkemppaidkemppai Posts: 315
    edited 2004-10-29 19:48
    ahhh, it all makes sense now.

    I would have never figured that one out on my own.

    Also, I didn't realize that the interrupts are disabled until RETI is run.
    (Yep, there it is on page 99 of the manual v2.0!)

    The problem is that I'm an analog guy, stuck working with these
    MCU's...·· ...so I struggle with the simple stuff sometimes!


    Thanks all!
    -Dan


    ·
  • Guenther DaubachGuenther Daubach Posts: 1,321
    edited 2004-10-29 22:46
    Dan,

    keep being an "analog guy" this is much more natural to us humans smile.gif .

    Do you know the difference between an analog and a digital clock?

    The digital clock tells you the time, and the analog clock tells you how late it is.

    Have a great weekend!

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Greetings from Germany,


    G
Sign In or Register to comment.