PDA

View Full Version : I need help with Interrupt



wildbilly
- 28th August 2007, 19:40
Hello to all. I have taken the plunge and tried interrupt for the first time and I thought I understood it but I have stumbled in this simple code and would like someone to show me where I am going wrong. The interrupt works but when I added the LCDOUT command in the main loop things go wrong. I want to see how many times the button is pressed. The first time I press the button connected on RB0 the led on RB7 flashes. The second time it does not work. My understanding of interrupt is that it jumps to the ISR and then jumps back to the main loop and continues. Why would adding the LCDOUT command in the main loop cause the interrupt not work after the first time an interrupt occurs? When the button is pressed the LED does not flash indicating that it did not leave the ISR or that it is not seeing the interrupt occur. Any help would appreciated.

16F877A
MicroCode Studio Plus


' External Interrupt example
' PortB pin 7 Turn LED on
' Interrupt on Portb.0 (INTE) turns LED off
' Program waits .3 secs and turns LED back on


'LCD Parameters
'==============
Define LCD_DREG PORTD
Define LCD_DBIT 4
Define LCD_RSREG PORTD
Define LCD_RSBIT 2
Define LCD_EREG PORTD
Define LCD_EBIT 3
DEFINE LCD_LINES 2 'Number lines on LCD

define OSC 20



led var PORTB.7 'Establish name for portb.7
counter var byte

OPTION_REG = %01111111 'Enable portb pullups and
'rising edge on B0 interrupt
On interrupt goto myint 'Define interrupt handler
INTCON = %10010000 'Enable INTE interrupt
counter = 0
'**** Main Loop ***
loop:
lcdout $fe,2 'return to beginning of line
lcdout "Count = ",# counter 'display count value
high led 'turn led on
goto loop 'Do it forever

'*****Interrupt Handler *****
Disable 'No interrupts pass this point
myint:
low led 'if we get here turn led off
Pause 300 'wait .3 seconds
counter = counter + 1
INTCON.1 = 0 'clear interrupt flag
resume 'return to main program
enable

end

mackrackit
- 28th August 2007, 23:21
This line is wrong.

lcdout "Count = ",# counter 'display count value

Should be.


lcdout $FE,"Count = ",# counter 'display count value

Might cause the program to hang?

wildbilly
- 29th August 2007, 17:54
Thanks for the correction. I was hoping that was the culprit but it has not corrected the problem. Strange!!
Thanks again

Archangel
- 30th August 2007, 05:21
Hello Wildbilly,
Data sheet says Port B 4-7, interrupt on change. Port B0
should interrupt when taken low assuming pullups on ( I think).
Even though data sheet says POR and BOR TrisB will reset as 11111111
I think I would add tris statement early in code to advise PIC it is an input.
Have you tried interrupt on any of ports b 4-7 ?

mackrackit
- 31st August 2007, 00:23
I just tested you code and every time PORTB.0 is connected to 0 volts(ground) the LED blinks and the LCD counts.

Here is what I have with a couple small changes. Look at comments.


DEFINE OSC 20

Define LCD_DREG PORTD
Define LCD_DBIT 4
Define LCD_RSREG PORTD
Define LCD_RSBIT 2
Define LCD_EREG PORTD
Define LCD_EBIT 3
DEFINE LCD_LINES 2 'Number lines on LCD

TRISB.0 = 1

led var PORTB.5 'CHANGED BECAUSE ICSP
counter var byte

OPTION_REG = %01111111 'Enable portb pullups and
'rising edge on B0 interrupt
On interrupt goto myint 'Define interrupt handler
INTCON = %10010000 'Enable INTE interrupt
counter = 0
'**** Main Loop ***
loop:
lcdout $fe,1 'CLEAR SCREEN
lcdout "Count=",# counter 'display count value
pause 50 'TIME TO DISPLAY
high led 'turn led on
goto loop 'Do it forever

'*****Interrupt Handler *****
Disable 'No interrupts pass this point
myint:
low led 'if we get here turn led off
Pause 300 'wait .3 seconds
counter = counter + 1
INTCON.1 = 0 'clear interrupt flag
resume 'return to main program
enable

end

wildbilly
- 1st September 2007, 01:41
Hi Dave thanks for your help. I have tried your suggestions and still have the same problem. I even copied your code directly and still no fix. You said you have it counting. I can only get it to count to one and then it stops. You said when you pushed the button to ground, it would count. Did you have it counting pass one? Another thing is the Option_Reg bit 6 is set for "Rising edge". You said you pushed the button low. It should not work if the bit is set for rising edge.
I guess I should also disclose that I am using the "EasyPic4 Development Board". I wonder if that is my problem.

mackrackit
- 1st September 2007, 11:56
If you want it to interrupt when RB0 goes high, comment out the OPTION_REG line and use external resistor from RB0 to ground.

With the OPTION_REG set as you have it "pull-up""set" the pin will need to go LOW to trigger the interrupt. No external resistor.
From data sheet.


External interrupt on the RB0/INT pin is edge triggered,
either rising, if bit INTEDG (OPTION_REG<6>) is set,
or falling, if the INTEDG bit is clear.


I counted to 255 then of course it rolls back to 0 and starts over.

I guess I should also disclose that I am using the "EasyPic4 Development Board". I wonder if that is my problem.
Not sure, never used the "EasyPic".

I am using Ubuntu (linux) for an OS, running MPLAB with PBP as the language set via Wine hooked to a PICSTART PLUS rigged as an ICSP.

wildbilly
- 1st September 2007, 18:46
Thank for you suggestion JOE.S I will have to try the other Inputs as well, 4-7. Thank you to mackrackit. I have found the problem. There is a jumper on the board that was set for "Pull down" and I had the "Pull up" set in Option_Reg. They were fighting each other. I disabled the Option_Reg and it works very well. Thanks very much for your input. All that you said was spot on.

This is fun.
Wildbilly.

mackrackit
- 1st September 2007, 19:16
This is fun.
Wildbilly.
That is all that matters!:D