PDA

View Full Version : Interrupt on PORTB.....



robert0
- 27th March 2006, 18:22
Please,
in interrupt handler how do you understand which pin of PORTB (RB7:RB4)changed its state and caused the interrupt ?

Int_Handler:
If INTCON.0=1 then

' here i must understand which one..

INTCON.0=0
resume.....

Thanks

Melanie
- 27th March 2006, 19:14
Basically you DON'T KNOW which one caused the interrupt.

The only way is to first read the state of RB7:RB4 bits into a variable, then Reset the RB Port Change Interrupt Flag Bit in the INTCON register. You may need to do this at the start of your program, and thereafter each time you reset the RBIF Flag in your Interrupt Service Routine. The next time when the RBIF flag trips, compare the current state of RB7:RB4 against what you had previously read.

BGreen
- 21st April 2006, 03:40
I know this is a very basic question and I have gone thru the data sheet for a 16f676 trying to figure out how to do what you were telling robert to do. could you give a code example? I actually found this thread looking for how to do it.

Melanie
- 21st April 2006, 07:18
Well the 16F676 hasn't got a PortB, so you're going to be looking for a long time for an Interrupt on that Port. But this chip has an Interrupt on PortA (Datasheet section 2.2.2.3, 9.4.1 and 9.4.3).

Let's assume in this instance PortA is configured for Input... somewhere at the start when we initialise our interrupts, we first have to clear the interrupt Flag RAIF, so at that time read the contents of PortA to be used for later comparative purposes...

OldPortA=PortA
INTCON=10001000
On Interrupt goto InterruptServiceRoutine
ENABLE

Compare my Register settings above with 2.2.2.3 and with the Interrupt Logic Diagram at Figure 9-10.

Now we go and do whatever we're going to do in our code... when an interrupt happens, in our Interrupt Service Routine (ISR) we first need to know if PortA caused it... if it's the ONLY interrupt configured in our PIC (ie other peripherals like the Timer, Comparators etc are not configured for interrupt), this IF INTCON.0 THEN (below) can be omitted...

DISABLE
If INTCON.0=1 then

We now need to read the content of PortA and determine which pin caused the interrupt...

NewPortA=PortA
If NewPortA.0<>OldPortA.0 then goto PortA0CausedInterrupt
If NewPortA.1<>OldPortA.1 then goto PortA1CausedInterrupt
If etc etc...

and finally when all is done, just prior to exiting our ISR, remember to reset your PortA Interrupt Flag and Read the Port once more...

OldPortA=PortA
INTCON.0=0
RESUME
ENABLE

The description is a little crude just as an example, but you'll get the idea of the kind of things you need to do. If further Interrupts could happen whilst you are in your ISR, then your code needs to be a little more recursive, but that's a topic for another time...

Example in a typical Rover Robot application... when sensors hit an object, the Rover performs an opposite action to clear from the obstruction...



DISABLE
InterruptHandler:
If PIR1.3=1 then
gosub LowBatteryWarning
PIR1.3=0
endif
If INTCON.0=1 then
NewPortA=PortA
If NewPortA.2<>OldPortA.2 then gosub MotorForward
If NewPortA.3<>OldPortA.3 then gosub MotorBackward
If NewPortA.4<>OldPortA.4 then gosub TurnLeft
If NewPortA.5<>OldPortA.5 then gosub TurnRight
OldPortA=PortA
INTCON.0=0
endif
RESUME
ENABLE

BGreen
- 21st April 2006, 11:50
Melanie, thank you for the reply. I did understand the 676 just had Port A & C. Sorry for not clarifying the port. This was exactly what I needed and want to thank you for the assistance. I had gotten confused on wheather I had to addres it like you did or in some type of register configuration. Guess I'm just getting old and some of my reasoning has deteriorated. Than you again.

charudatt
- 25th April 2006, 03:47
Thank you Melanie. Your explaination helped me also because , even i extensively use the F676 in my project work and now shall use your idea for trapping INT's.