Change On Interrupt, PIC16F884


Closed Thread
Results 1 to 18 of 18

Hybrid View

  1. #1
    Join Date
    Apr 2005
    Location
    Virginia
    Posts
    65


    Did you find this post helpful? Yes | No

    Talking

    Ahh, I was wondering if that might impact it. So, an external interrupt will not interrupt the program while executing a pause command? Is that due to the way PBP works? If I were to go so far as to program in assembly, it's been a while, I would assume I could interrupt a timer function with an external interrupt. Okay though, I see what you mean.

    Alright, I gave it shot and eureka, it works! Thank you Bruce! Here's the updated code.

    INCLUDE "modedefs.bas"
    PORTA = $00 ' Set all port a pins to low
    PORTB = $00 ' Set all port b pins to low
    PORTC = $00 ' Set all port c pins to low
    PORTD = $00 ' Set all port d pins to low
    PORTE = $00 ' Set all port e pins to low

    asm ; The following code is assembly, not Basic
    __CONFIG _CONFIG1, _INTOSCIO & _WDT_OFF & _PWRTE_ON & _CP_OFF & _BOR_OFF & _IESO_OFF & _FCMEN_OFF & _LVP_OFF
    ; Use internal oscillator & make both, OSC pins I/Os, turn off watchdog timer, enable Power-up timer,
    ; code protection off, brown-out off, disable switch over mode, turn off failsafe monitor,
    ; low voltage programming off
    endasm ' End assembly code

    ADCON0.0 = 0 ; Make all analog pins digital I/Os
    CM1CON0.7 = 0 ; Disable comparator C1
    CM2CON0.7 = 0 ; Disable comparator C2
    OSCCON.6 = 1 ; Set the internal oscillator to 8MHz
    OSCCON.5 = 1 ; Set the internal oscillator to 8MHz
    OSCCON.4 = 1 ; Set the internal oscillator to 8MHz
    WDTCON.0 = 0 ; Disable the watchdog timer
    ANSEL = %00000000 ; Set all analog pins on port a to digital I/O
    ANSELH = %00000000 ; Set all analog pins on port b to digital I/O

    DEFINE OSC 8 ' Tell the program the oscillator is running at 8 MHz
    TRISA = %00000000 ' Make all port a pins outputs
    TRISB = %00001111 ' Make port b pins 0-3 inputs and the rest as outputs
    TRISC = %00000000 ' Make all port c pins outputs
    TRISD = %00000000 ' Make all port d pins outputs
    TRISE = %00000000 ' Make all port e pins outputs
    PORTA = $00 ' Set all port a pins to low
    PORTB = $00 ' Set all port b pins to low
    PORTC = $00 ' Set all port c pins to low
    PORTD = $00 ' Set all port d pins to low
    PORTE = $00 ' Set all port e pins to low
    'Variables**************************************** ************************************************** *
    b0 VAR byte ' Required byte variable for toggle button
    i var word
    temp var byte
    '************************************************* ************************************************** *
    INITIALIZE: ' Initialize Routine
    INTCON.0 = 0 ' Clear the interrupt-on-change flag
    On Interrupt goto Halt ' Once an active interrupt port is enabled, go to the Halt routine
    INTCON = %10001000 ' Enable global interrupts, Enable interrupt-on-change on Port b
    IOCB = %00000011 ' Enable interrupt-on-change on RB0-RB3
    PORTE.1 = 0 ' Make sure LED on PORTE.1 is off
    PORTE.2 = 0 ' Make sure LED on PORTE.2 is off
    GOTO MAIN ' Go to Main routine
    '************************************************* ************************************************** *
    MAIN:
    HIGH PORTE.0
    FOR i = 1 to 5000
    PAUSEUS 100
    NEXT
    LOW PORTE.0
    FOR i = 1 to 5000
    PAUSEUS 100
    NEXT
    GOTO MAIN
    '*************************************************
    DISABLE ' do NOT place interrupt checking code below
    Halt: ' Halt Routine
    temp = PORTB
    IF temp.0 = 0 THEN
    WHILE PORTB.0=0 ' wait for button release & end mismatch condition on portb
    WEND
    PAUSE 20 ' Debounce delay
    HIGH PORTE.1
    LOW PORTE.2
    ENDIF
    IF temp.1 = 0 THEN
    WHILE PORTB.1=0 ' wait for button release & end mismatch condition on portb
    WEND
    PAUSE 20 ' Debounce delay
    LOW PORTE.1
    HIGH PORTE.2
    ENDIF
    INTCON.0 = 0 ' Clear the interrupt-on-change flag
    RESUME ' Resume wherever program left off at
    ENABLE ' Enable all active interrupts
    Sorry, I tried the Save As in html to get the color, but I can't save it as html from MPLAB.

    I assume the while loop and 20ms debounce pause are still good to have.

    Charles, I tried using Darrel Teylor's Instant Interrupts without success. I attempted to use the RBC_INT. It didn't work and I read that that command is only designed for ports b4-7. Then I attempted to use INT0_INT and INT1_INT for ports b0 and b1, respectively, but no luck there either. I'm not sure if I'm doing something wrong or if I need configure something. I love the concept, but I wanted to figure out how to fix the PBP interrupt version I'm familar with before I try figuring out a new method. I'm open to suggestions if you have any. Thank you for the suggestion. I definitely want to play with Darrel's solution once I've got this licked.

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


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by elec_mech View Post
    Ahh, I was wondering if that might impact it. So, an external interrupt will not interrupt the program while executing a pause command? Is that due to the way PBP works? If I were to go so far as to program in assembly, it's been a while, I would assume I could interrupt a timer function with an external interrupt. Okay though, I see what you mean.

    Alright, I gave it shot and eureka, it works! Thank you Bruce! Here's the updated code.


    It's due to PBP interrupts being a Psudo interrupt, it detects the hardware interrupt, puts a request on the stack and waits for an opportunity, Whereas an assembly interrupt is like cops, break in and announce it's arrival.
    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
    Join Date
    Apr 2005
    Location
    Virginia
    Posts
    65


    Did you find this post helpful? Yes | No

    Question Multiple Resumes not working

    Joe, thanks for the info!

    Okay, related to interrupts, I've run into another problem. I go into my interrupt routine, detect a button on a port change and then tell the program to resume at a new routine based on which button was pressed. The first button works fine, but whenever I press the second button, it seems to ignore/skip the resume (colored below) and go on to the end of the interrupt routine. I added a toggle to an LED to indicate where the program was going. It works before the colored resume statement and after the end if statement, but not immediately after the resume statement. I also tried it at the beginning of the Score_player2 routine, which of course didn't work. I tried a quick search on the forum, but didn't come across anything similar, at least not yet. Any reason PBP would skip or ignore a resume statement? I've just included the interrupt routine - the rest is very similar to the code posted above.

    I don't know if this is an indication of another problem, but I'm multiplexing two seven segment digits and whenever I press either button, one of the digits goes out, sometimes digit A and sometimes digit B regardless of the button pressed, and comes back on whenever I release the button.

    '************************************************* ************************************************** ***
    DISABLE ' do NOT place interrupt checking code below
    Halt: ' Halt Routine
    temp = PORTB
    TOGGLE PORTE.1
    IF temp.0 = 0 THEN
    WHILE PORTB.0=0 ' wait for button release & end mismatch condition on portb
    WEND
    PAUSE 20 ' Debounce delay
    INTCON.0 = 0 ' Clear the interrupt-on-change flag
    RESUME SCORE_PLAYER1
    ENDIF
    IF temp.1 = 0 THEN
    WHILE PORTB.1=0 ' wait for button release & end mismatch condition on portb
    WEND
    PAUSE 20 ' Debounce delay
    INTCON.0 = 0 ' Clear the interrupt-on-change flag
    RESUME SCORE_PLAYER2
    ENDIF
    INTCON.0 = 0 ' Clear the interrupt-on-change flag
    RESUME Main ' Go to Main routine
    ENABLE ' Enable all active interrupts
    '************************************************* ************************************************** ***

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


    Did you find this post helpful? Yes | No

    Default

    Not a good idea to me to use label with RESUME as you never know where the program was before to jump in the ISR. You should jump (goto) at the end if your ISR, then your program will return where he was before.
    Steve

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

  5. #5
    Join Date
    Apr 2005
    Location
    Virginia
    Posts
    65


    Did you find this post helpful? Yes | No

    Thumbs up

    Steve,

    I'd be lying if I said I completely understood what you meant, but I noticed that I was forcing the program to resume at the start of the Main routine and allowed it to just resume at the end of the ISR. It works! Thank you for your advice. I still have one of the digits going off whenever I press a button, but I'll investigate that further. Likely a hardware issue.

    '************************************************* ************************************************** ***
    DISABLE ' do NOT place interrupt checking code below
    Halt: ' Halt Routine
    temp = PORTB
    TOGGLE PORTE.1
    IF temp.0 = 0 THEN
    WHILE PORTB.0=0 ' wait for button release & end mismatch condition on portb
    WEND
    PAUSE 20 ' Debounce delay
    INTCON.0 = 0 ' Clear the interrupt-on-change flag
    RESUME SCORE_PLAYER1
    ENDIF
    IF temp.1 = 0 THEN
    WHILE PORTB.1=0 ' wait for button release & end mismatch condition on portb
    WEND
    PAUSE 20 ' Debounce delay
    INTCON.0 = 0 ' Clear the interrupt-on-change flag
    RESUME SCORE_PLAYER2
    ENDIF
    INTCON.0 = 0 ' Clear the interrupt-on-change flag
    RESUME ' Resume program running before interrupt occurred
    ENABLE ' Enable all active interrupts
    '************************************************* ************************************************** ***

Similar Threads

  1. A Simple IOC Routine (Interrupt On Change)
    By lugo.p in forum mel PIC BASIC Pro
    Replies: 6
    Last Post: - 8th March 2010, 19:53
  2. Won't go back to SLEEP after 1st Interrupt
    By jellis00 in forum mel PIC BASIC Pro
    Replies: 32
    Last Post: - 29th June 2009, 09:00
  3. Can't ID interrupt source with this IntHandler??
    By jellis00 in forum mel PIC BASIC Pro
    Replies: 7
    Last Post: - 3rd June 2009, 02:35
  4. NEWBIE: Some basic questions using interrupts
    By JackPollack in forum mel PIC BASIC Pro
    Replies: 5
    Last Post: - 8th March 2006, 02:59
  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