RB0 interrupt and toggle issue


Closed Thread
Results 1 to 36 of 36

Hybrid View

  1. #1


    Did you find this post helpful? Yes | No

    Question interrupts

    Ok for my own sanity, I would like confirmation on my understanding of how RB0 interrupt works or any interrupt for that matter. Once an interrupt condition happens, the interrupt flag is set, then the code is vectored to the interrupt start location.

    In my code, I do the customary saving status, pclath..etc. Then I run my code, then repack status and pclath.
    Retfie statement at the end of the interrupt clears the interrupt flag so now it is enabled to recieve interrupts. So during the time I am running my code in the interrupt, it shouldn't be retriggering the interrupt based on switch bounce until it sees Retfie....or does it? Somewhere, somehow the contents of the variable that I am passing to the case statements is getting hosed (I assume). The variable is specfied as bank0 System, so content must be common across banks.....or is it?

    Lots of questions, I guess I am second guessing everything now.

    Nick

  2. #2
    Join Date
    Aug 2006
    Location
    Look, behind you.
    Posts
    2,818


    Did you find this post helpful? Yes | No

    Default

    It is still a little buggy but it works after a fashion
    Code:
    DEFINE OSC 20
    
    DEFINE DEBUGIN_REG PORTC ' Set portC as software RX in
    DEFINE DEBUG_BAUD 2400   ' Set bit rate
    DEFINE DEBUG_BIT 6
    DEFINE DEBUGIN_BIT 7     ' Set portC bit 7
    DEFINE DEBUGIN_MODE 0    ' Set Debugin mode: 0 = true, 1 = inverted
    
    ASM
    INT_LIST macro ; IntSource, Label, Type, ResetFlag?
        INT_Handler INT_INT, _keys2, PBP, yes
      endm
      INT_CREATE ; Creates the interrupt processor
    ENDASM
    ADCON0 = 0    ' Kill analog Functions
    ADCON1 = 7
    CMCON = 7
    CVRCON = 0
    CCP1CON = 0
    CCP2CON = 0
    
    ; initialize Interrupts
    OPTION_REG.6 = 1   ; option_reg RB0 interrupt rising=1, falling=0 edge
    INTCON = %11010000 ; Enable INTE RB0 interrupt $90
    
    
    
    
    ;set port initializations
    PORTA = %00000000
    PORTE = %00000000
    
    
    TRISA = %00000000 ; set port A to outputs for relays
    TrisB = %00000001 ' b0 input for interrupt
    TRISC = %10000000 'set 7 as input debugin
    TRISD = %00000000 ; 8 button press inputs + RB0 interrupt for all off  Made outputs as unused
    TRISE = %00000000 ; set port E to outputs for relays
    ' Configure internal registers
    
    
    payload  VAR byte ; bank0 system ' data location for selecting relays
    'payload1 var byte ; bank0 system ' previous good data
    chksum   var byte ; bank0 system ' check sum calculated at the TX side and sent over RF link
    
    
    payload = 0
    CHKSUM  = 0
    
    
    goto mainloop
    
    
    
    
    
    keys2: ; called by interrupt to update relay
    
    if payload = 0 then
    portE = 0
    portA = 0
    endif
    if payload = 1 then
    toggle portA.0
    endif
    if payload = 2 then
    toggle portA.1
    endif
    if payload = 4 then
    toggle portA.2
    endif
    if payload = 8 then
    toggle portA.3
    endif
    if payload = 16 then
    toggle portA.4
    endif
    if payload = 32 then
    toggle portA.5
    endif
    if payload = 64 then
    toggle portE.0
    endif
    if payload = 128 then
    toggle portE.1
    endif
    
    @ INT_RETURN
    
    
    
    mainloop:
    INTCON = %11010000 ; Enable INTE RB0 interrupt $90
    ; receive data packets and check sum, throwing out sync byte (255)
    debugin [payload,chksum]
    debug payload,chksum
    if chksum != payload then ; verify good packets by comparing check sums
    goto mainloop ; check sum does not match transmitted data
    endif
    
    update_keys:
    
    if payload = 0 then
    portE = 0
    portA = 0
    endif
    if payload = 1 then
    toggle portA.0
    endif
    if payload = 2 then
    toggle portA.1
    endif
    if payload = 4 then
    toggle portA.2
    endif
    if payload = 8 then
    toggle portA.3
    endif
    if payload = 16 then
    toggle portA.4
    endif
    if payload = 32 then
    toggle portA.5
    endif
    if payload = 64 then
    toggle portE.0
    endif
    if payload = 128 then
    toggle portE.1
    endif
    PAYLOAD = 0  ' Zero here or loaded variable will turn on port next loop after INT
    CHKSUM = 0
    goto mainloop
    Here is what I don't get . . if yoy turn on portE.0 and PortE.1 toggling either, toggles both. ???? I have in the past written code to do what this code does and had the same problem, only I think it was on portA.
    Last edited by Archangel; - 4th May 2009 at 21:28.
    If you do not believe in MAGIC, Consider how currency has value simply by printing it, and is then traded for real assets.
    .
    Gold is the money of kings, silver is the money of gentlemen, barter is the money of peasants - but debt is the money of slaves
    .
    There simply is no "Happy Spam" If you do it you will disappear from this forum.

  3. #3


    Did you find this post helpful? Yes | No

    Question

    Great I am not the only one experiencing the weirdness of trying to use toggle! Thanks for verifying I am not going nuts!!!!! I have a version of the code written where the ports work in terms of toggling...but here is the kicker and I don't know why......I add pauses with in the Call routine, this allows the port to change and even toggle. But Only PortA.0......lol...... If rapid press for a few seconds eventually I get portA.1 but if PortA.0 is set, portA.1 change resets PortA.0.....man am I ready to throw this thing against the wall!

    I want to eventually, when I calm down try to run a timer interrupt fast enough to look at the input port status. I don't know if I am just going to see the same problem or not.

  4. #4
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by Macgman2000 View Post
    Ok for my own sanity, I would like confirmation on my understanding of how RB0 interrupt works or any interrupt for that matter. Once an interrupt condition happens, the interrupt flag is set, then the code is vectored to the interrupt start location.

    In my code, I do the customary saving status, pclath..etc. Then I run my code, then repack status and pclath.
    This HINT, was also a comment from your first code ...
    Code:
    ; Save W, STATUS and PCLATH registers, if not done previously
    Since a 16F877A has more than 2K of code space,
    It was "done previously", and automatically by PBP.
    Doing it again saves/restores the wrong values, which makes everything go Wacko.

    However, you are also trying to CALL basic language routines from an ASM interrupt handler.

    You can't do that.
    At least, not the way your trying.
    <br>
    DT

  5. #5
    Join Date
    Sep 2004
    Location
    montreal, canada
    Posts
    6,898


    Did you find this post helpful? Yes | No

    Default

    try this one
    Code:
            @   __CONFIG _HS_OSC & _LVP_OFF
            DEFINE OSC 20
            
            INCLUDE ".\INCLUDE_ROUTINES\DT_INTS-14.bas"
            INCLUDE ".\INCLUDE_ROUTINES\ReEnterPBP.bas"
            
            ;set port initializations
            PORTA = %00000000
            PORTE = %00000000
            
            TRISA = %00000000 ; set port A to outputs for relays
            TrisB = %00000001 ' b0 input for interrupt
            TRISC = %10000000 'set 7 as input debugin
            TRISD = %00000000 ; 8 button press inputs + RB0 interrupt for all off  Made outputs as unused
            TRISE = %00000000 ; set port E to outputs for relays
           
            ' Configure internal registers
            ADCON1 = 7
            CMCON = 7
    
            DEFINE DEBUGIN_REG PORTC ' Set portC as software RX in
            DEFINE DEBUG_BAUD 2400 ' Set bit rate
            DEFINE DEBUGIN_BIT 7 ' Set portC bit 7
            DEFINE DEBUGIN_MODE 1 ' Set Debugin mode: 0 = true, 1 = inverted
            'DEFINE DEBUG_REG PORTC 'Debug pin port 
            'DEFINE DEBUG_BIT 6 'Debug pin bit    
            'DEFINE DEBUG_MODE 1 'Debug mode: 0 = True, 1 = Inverted      
            
            ; initialize Interrupts
            OPTION_REG.6 = 1   ; option_reg RB0 interrupt rising=1, falling=0 edge
            ASM
    INT_LIST macro ; IntSource, Label, Type, ResetFlag?
            INT_Handler INT_INT, _keys2, PBP, yes
            endm
        
            INT_CREATE ; Creates the interrupt processor
            ENDASM
    
            NewPayload  var Byte
            payload     VAR byte ' data location for selecting relays
            chksum      var byte ' check sum calculated at the TX side and sent over RF link
            INT0IF      var INTCON.1
            
            CLEAR  
            pause 50 ' settle time         
    @       INT_CLEAR  INT_INT  ; make sure INT0IF is cleared
    @       INT_ENABLE INT_INT  ; Enable Interrupt        
    
    mainloop:
            ; receive data packets and check sum, throwing out sync byte (255)
            DEBUGIN [wait(255),NewPayload, chksum]
            'DEBUG NewPayload, chksum
            if chksum != newpayload then MainLoop
            payload=NewPayload
            goto    updatePort
            
    
    keys2: ; Called by Interrupt update relay
            
            pause 20                ' small debounce delay
            if !PORTB.0 then GetOut ' button up?  
                                    ' If so, getout of here... no need for noise call
    UpdatePort:  
            select case payload
                    case 0
                        PORTE = 0
                        PORTA = 0
                    CASE 1
                        toggle portA.0
                    CASE 2
                        toggle portA.1
                    CASE 4
                        toggle portA.2
                    CASE 8
                        TOGGLE PORTA.3
                    CASE 16
                        toggle portA.4
                    CASE 32
                        toggle portA.5
                    CASE 64
                        toggle portE.0
                    CASE 128
                        toggle portE.1
                    END SELECT 
    GetOut:
            If INT0IF THEN  ' called by Interrupt?
                    @ INT_RETURN    
                            ' - Yes, clear the flag and getout
                    ELSE    '
                        GOTO MAINLOOP
                            ' - No, return to Mainloop
                    ENDIF
    Make sure you transmit the right way from your PC...
    Last edited by mister_e; - 5th May 2009 at 06:39.
    Steve

    It's not a bug, it's a random feature.
    There's no problem, only learning opportunities.

  6. #6


    Did you find this post helpful? Yes | No

    Default

    mister_e, I copied and pasted the code, I made one slight modification to the Include statements. I don't have them in the directories you have them in, but instead in the main PBP file. I switched over my assembler to MPASM. I get the following error when I compile.

    "Error [118] c:\pbp\RX_New.asm 103: overwriting previous address contents 2007"

  7. #7
    Join Date
    Nov 2003
    Location
    Greece
    Posts
    4,115


    Did you find this post helpful? Yes | No

  8. #8


    Did you find this post helpful? Yes | No

    Default

    Thanks Ioannis and mister_e, for your help!!!! I appreciate your patience, I feel like a fish out of water on this project.

    The code is not responsive to button presses. I changed the port configuration from output to input on portD. enclosed is my button arrangment, the idea is any button press will also trigger the RB0 interrupt along with the key momentarily held on portD. Also, the code is attached for reference.

    @ __CONFIG _HS_OSC & _LVP_OFF
    DEFINE OSC 20

    INCLUDE ".\DT_INTS-14.bas"
    INCLUDE ".\ReEnterPBP.bas"



    ;set port initializations
    PORTA = %00000000
    PORTE = %00000000

    TRISA = %00000000 ; set port A to outputs for relays
    TrisB = %00000001 ' b0 input for interrupt
    TRISC = %10000000 'set 7 as input debugin
    TRISD = %11111111 ; 8 button press inputs + RB0 interrupt for all off Made outputs as unused
    TRISE = %00000000 ; set port E to outputs for relays

    ' Configure internal registers
    ADCON1 = 7
    CMCON = 7

    DEFINE DEBUGIN_REG PORTC ' Set portC as software RX in
    DEFINE DEBUG_BAUD 2400 ' Set bit rate
    DEFINE DEBUGIN_BIT 7 ' Set portC bit 7
    DEFINE DEBUGIN_MODE 1 ' Set Debugin mode: 0 = true, 1 = inverted
    'DEFINE DEBUG_REG PORTC 'Debug pin port
    'DEFINE DEBUG_BIT 6 'Debug pin bit
    'DEFINE DEBUG_MODE 1 'Debug mode: 0 = True, 1 = Inverted

    ; initialize Interrupts
    OPTION_REG.6 = 1 ; option_reg RB0 interrupt rising=1, falling=0 edge
    ASM
    INT_LIST macro ; IntSource, Label, Type, ResetFlag?
    INT_Handler INT_INT, _keys2, PBP, yes
    endm

    INT_CREATE ; Creates the interrupt processor
    ENDASM

    NewPayload var Byte
    payload VAR byte ' data location for selecting relays
    chksum var byte ' check sum calculated at the TX side and sent over RF link
    INT0IF var INTCON.1

    CLEAR
    pause 50 ' settle time
    @ INT_CLEAR INT_INT ; make sure INT0IF is cleared
    @ INT_ENABLE INT_INT ; Enable Interrupt

    mainloop:
    ; receive data packets and check sum, throwing out sync byte (255)
    DEBUGIN [wait(255),NewPayload, chksum]
    'DEBUG NewPayload, chksum
    if chksum != newpayload then MainLoop
    payload=NewPayload
    goto updatePort


    keys2: ; Called by Interrupt update relay

    pause 20 ' small debounce delay
    if !PORTB.0 then GetOut ' button up?
    ' If so, getout of here... no need for noise call
    UpdatePort:
    select case payload
    case 0
    PORTE = 0
    PORTA = 0
    CASE 1
    toggle portA.0
    CASE 2
    toggle portA.1
    CASE 4
    toggle portA.2
    CASE 8
    TOGGLE PORTA.3
    CASE 16
    toggle portA.4
    CASE 32
    toggle portA.5
    CASE 64
    toggle portE.0
    CASE 128
    toggle portE.1
    END SELECT
    GetOut:
    If INT0IF THEN ' called by Interrupt?
    @ INT_RETURN
    ' - Yes, clear the flag and getout
    ELSE '
    GOTO MAINLOOP
    ' - No, return to Mainloop
    ENDIF ;Make sure you transmit the right way from your PC...
    Attached Images Attached Images

  9. #9
    Join Date
    Sep 2004
    Location
    montreal, canada
    Posts
    6,898


    Did you find this post helpful? Yes | No

    Default

    Well it has to go to the ISR, but probably you want to refresh the Payload value with the PushButton?

    In this case...
    Code:
    keys2: ; Called by Interrupt update relay
    
            pause 20 ' small debounce delay
            if !PORTB.0 then GetOut ' button up?
                                    ' If so, getout of here... no need for noise call
    
            PayLoad = PORTD ' read PushButtons and update Payload Value
    UpdatePort:
    You could also use a timer interrupt and poll PORTD, this will allow you to remove all those diodes, and leave RB0 for something else. As it is user push-button, you'll probably never feel the latency of the Timer interrupt.
    Last edited by mister_e; - 5th May 2009 at 16:42.
    Steve

    It's not a bug, it's a random feature.
    There's no problem, only learning opportunities.

Similar Threads

  1. Instant Interrupts - Revisited
    By Darrel Taylor in forum Code Examples
    Replies: 772
    Last Post: - 17th February 2016, 22:14
  2. TMR0 interrupt and HSERIN
    By boban in forum mel PIC BASIC Pro
    Replies: 2
    Last Post: - 2nd September 2008, 11:48
  3. I have problem with interrupt RB0
    By chai98a in forum mel PIC BASIC Pro
    Replies: 1
    Last Post: - 5th July 2008, 09:55
  4. tmr2 interrupt problem
    By ADCON in forum mel PIC BASIC Pro
    Replies: 27
    Last Post: - 2nd January 2008, 18:49
  5. USART interrupt not interrupting right
    By Morpheus in forum mel PIC BASIC Pro
    Replies: 12
    Last Post: - 6th March 2005, 01:07

Members who have read this thread : 0

You do not have permission to view the list of names.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts