Shop OBEX P1 Docs P2 Docs Learn Events
Interrupts and status — Parallax Forums

Interrupts and status

John CoutureJohn Couture Posts: 370
edited 2005-10-21 21:26 in General Discussion
Problem:· Port B is used to detect interrupts.· Some are random (i.e. rain guage) some are on a schedule (i.e. 1Hz pulse from Real Time Clock).· I can get interrupts to work but the RTC produces a 1Hz pulse with a 50% duty cycle (i.e. 500ms on, 500ms off).· Thus interrupt is caught MANY times (the darn SX52 is FAST!).

I suspect that I need to do something with the WKPND_B register (SX-Key Dev System, pg 169)· but I can't figure out the syntax.

Something like:

'
'· Inside the Interrupt routine, determine if the RTC pulsed
'
IF WKPND_B.7 = 1 then
··· ' handle RTC interrupt
··· WKPND_B.7 = 0··· ' stop listening until next change
ENDIF




▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
John J. Couture

San Diego Miramar College

Comments

  • Guenther DaubachGuenther Daubach Posts: 1,321
    edited 2005-10-17 19:54
    John,

    you can't directly read the WKPND_B register, or single bits in this register.

    To access this register, use the following sequence inside the ISR instead:

    mode $09 ; select the WKPND_B register
    clr w
    mov !rb, w ; exchange WKPND_B and w

    The mov !rb,w instruction does not simply move its contents into the WKPND_B register. Instead, it exchanges the contents of both registers. IOW, after this instruction has been executed, WKPND_B contains 0 (because w was cleared before), and w the status of the WKPND_B bits. This is a bit tricky but a clever method to clear the WKPND_B bits (absolutely necessary to avoid another interrupt after terminating the ISR), and to retrieve the WKPND_B bits with just one instruction using clock cycle. Once you have the WKPND_B bits in the w register, you may evaluate them as necessary.

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

    G
  • John CoutureJohn Couture Posts: 370
    edited 2005-10-18 21:00
    Gunther,

    I guess what I was hoping for was a way to tell the mcu to disregard that port pin until it flip-flopped again. Also, your solution above is in assembler ... is there an SX/B solution? I would normally put pauses in the interrupt code but I already got zapped for doing that (grin)!


    It would seem like it would be something simple like telling the mcu to raise an interrupt ONLY when there is a change from high to low (or visa versa).

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    John J. Couture

    San Diego Miramar College
  • Jon WilliamsJon Williams Posts: 6,491
    edited 2005-10-18 21:15
    John,

    The port B interrupts are edge detecting, so you won't have retriggering until you get a valid transition.· And yes, you can do what you want in SX/B; for example:

    INTERRUPT

    ISR_Start:
    · rbStatus = 0
    · WKPND_B = rbStatus················ ·' get bits that changed

    · IF rbStatus.0 = 1 THEN
    ··· INC secs
    ··· IF secs = 60 THEN
    ····· secs = 0
    ····· mins = mins + 1
    ······IF mins = 60 THEN
    ······· mins = 0
    ······· hours = hours + 1
    ····· ENDIF
    ····ENDIF
    · ENDIF

    · IF rbStatus.1 = 1 THEN
    ··· INC rain
    · ENDIF

    · RETURNINT

    ·

    [noparse][[/noparse]Edit] -- I decided to try it for myself and whipped up the attached program on a PDB (You have one, right? tongue.gif ).· I used the Pulse Generator to drive one of the RB pins.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Jon Williams
    Applications Engineer, Parallax

    Post Edited (Jon Williams (Parallax)) : 10/20/2005 9:58:34 PM GMT
  • John CoutureJohn Couture Posts: 370
    edited 2005-10-20 20:28
    Ah Ha! Thank you Jon,

    I was trying to read the pin directly instead of reading the WKPND_B which is a "latch" that indicates that the pin was toggled.

    Interesting. In "classic" programming, the data goes from right to left on an equals sign, as in:

    a = b + c


    Yet, at the top of your program, you have

    WKPND_B = rbStatus

    which implies that the rbStatus receives the data not the WKPND_B?

    Is that just because the compiler was designed that way?

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    John J. Couture

    San Diego Miramar College
  • SandySandy Posts: 1
    edited 2005-10-20 21:35
    Hi John,

    Humm ... I don't know about what you consider classic but let's take some old FORTRAN for example:

    I = I + 1

    is often used to increment the integer variable I from its old value to a new value one larger and the 'expression' (quotes here because this is _not_ algebra!) is evaluated first on the right with operator precedence and then the result is placed in the location on the left.

    Most programming languages I know operate in much the same way.

    Best,

    Sandy
  • Jon WilliamsJon Williams Posts: 6,491
    edited 2005-10-20 21:57
    If you look under the hood, this line of SX/B:

    · WKPND_B = rbStatus

    ... produces this code:

    · MODE $09
    · MOV !RB, rbStatus
    · MOV rbStatus, W

    So the effect is that WKPND_B and rbStatus are exchanged.· I've updated the program (attached above)·to clear rbStatus before the exchange -- this gets what's in WKPND_B and clears it at the same time.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Jon Williams
    Applications Engineer, Parallax
  • John CoutureJohn Couture Posts: 370
    edited 2005-10-21 00:46
    Sandy,

    Yes, that was my point. Most languages go from right to left (as does Fortran above). I guess I was trying to state that most languages put the receiving operand on the left of the equals sign, yet the WKPND_B = rbStatus seems to defy that logic (grin).

    Jon,

    Thus, it looks like the statement is actually a swap (something very common in assemblers). I never got into compiler design (a magical art in my opinion) so sometimes the syntax of the language is a little mysterious to me.

    I'll have to play around with the syntax and see what kind of assembler code it produces (something I should have done before I posted this, sorry).

    Anyway, it works great. Now to gather it together into a tutorial.

    Thanks again.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    John J. Couture

    San Diego Miramar College
  • Jon WilliamsJon Williams Posts: 6,491
    edited 2005-10-21 01:30
    To your point...

    ·· WKPND_B = rbStatus

    does an exchange, not a simple assignment.· I suppose we could have used:

    · rbStatus = WKPND_B

    but then those looking "under the hood" (as we hope will ultimately happen) would wonder why it generated this code:

    · MODE $09
    · MOV !RB, rbStatus
    · MOV rbStatus, W

    since the MOV instruction is defined as:

    · MOV destination, source

    As I pointed out to a student in one of our other forums, engineers are faced with choices every day -- sometimes the choice will make sense to others without explanation, sometimes not.· This is one of those cases where we thought that one familiar with how the WKPND_B register is handled it would make sense.

    In the FWIW category, this note is in the SX/B help file:

    2· When changed (i.e., Register = Variable), Variable is swapped with Register.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Jon Williams
    Applications Engineer, Parallax
  • Guenther DaubachGuenther Daubach Posts: 1,321
    edited 2005-10-21 08:12
    Hi all!

    MODE $09
    MOV !RB, rbStatus
    MOV rbStatus, W

    may still look mysterious to some readers, wondering about how W gets the correct value. So it is important to note that

    MOV !RB, rbStatus

    is a multi-word instruction. When SASM generates the instruction code, it actually generates the following sequene:

    MODE $09
    W, rbStatus ; replacement for
    MOV !RB, W ; MOV !RB, rbStatus
    MOV rbStatus, W

    As Jon mentioned, the MOW !RB, W does not just copy W into !RB but it exchanges the contents of both registers. So W will hold the status of the WKPND_B bits after this exchange. Provided that rbStatus is cleared before, all WKPND_B bits will be reset after the exchange. Please note that this is very important. When the bits are not all cleared, another interrupt will be fired immediately after leaving the ISR with a RETI, or RETIW instruction.

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

    G
  • Peter VerkaikPeter Verkaik Posts: 3,956
    edited 2005-10-21 09:01
    I usually use

    MASK equ value· ;clear bits for unused inputs

    mode $09

    clr w

    mov !rb,w· ;clear wkpnd_B

    and w,#MASK ;clear unused pins

    or rbstatus,w· ;add new pin interrupts to status byte



    This allows also to delay pin interrupts to main code if allowed

    (for example, a button press). Once a pin interrupt task is completed,

    the appropiate bit in rbstatus is cleared.



    regards peter
  • John CoutureJohn Couture Posts: 370
    edited 2005-10-21 21:26
    Thank you all,

    Alas, of the many languages I have learned in my career, I never really liked assembler and considering how many I have tried (Assembler 360, Knuth's MIX, PDP 11, Honeywell something, HP something else, Z80, 8051 ... ) you'd think I'd be better at it and remember the points that you all brought up (grin).

    Anyway, the SX/B code is working perfectly and again thank you.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    John J. Couture

    San Diego Miramar College
Sign In or Register to comment.