3
\$\begingroup\$

I have a PIC16f877 with PORTB configured as follows:

RB0 Output
RB1 Output
RB2 Output
RB3 Output
RB4 Input
RB5 Input
RB6 Output
RB7 Output

RB4..5 are used for detecting 2 simple push button switches, and I want to make used of the RBIF interrupt flag to handle the event of a button press, rather than polling.

Looking at the datasheet on page 31, is says this:

The user, in the Interrupt Service Routine, can clear the interrupt in the following manner:

a) Any read or write of PORTB. This will end the mismatch condition.

b) Clear flag bit RBIF.

A mismatch condition will continue to set flag bit RBIF. Reading PORTB will end the mismatch condition and allow flag bit RBIF to be cleared.

My concern is that it specifically says "Any WRITE of portb". The other pins on PORTB that are set to output are used for PWM dimmed LEDs, and therefore written to very frequently. I don't want an input change on RB4 or RB5 occurring a few cycles before a PORTB write to clear a mismatch condition and not fire the interrupt.

However, the datasheet contradicts itself in the previous paragraph:

Only pins configured as inputs can cause this interrupt to occur (i.e., any RB7:RB4 pin configured as an output is excluded from the interrupt on-change comparison).

Which would mean I'm gonna be ok and not have to worry about writes to PORTB affecting the interrupt.

Is this something I need to worry about? I can't move the outputs to another port as I don't have enough spare pins on the chip.

\$\endgroup\$
  • 3
    \$\begingroup\$ My reading is that as it says, any Write to port B can turn the interrupt off. But only pins RB4:RB7, and then only when inputs, can turn it on. If interrupts are taken immediately they are raised, you should be OK. But don't write RB3:0 with interrupts disabled! Alternatively, explicitly check RB4,5 after writing PortB - you don't have to wait for an interrupt! \$\endgroup\$ – Brian Drummond Jan 11 '13 at 16:57
6
\$\begingroup\$

The mismatch condition will set the interrupt flag, and reading the port removes the mismatch, but doing so does not clear the flag, you must still clear it manually inside the isr.

From port B circuitry shown in the datasheet (Figure 3-4) you can tell that there is no way that WR (asserted during port writes) could remove the mismatch when the pin is configured as an input (TRIS bit is 1), because the WR signal does not affect anything but the "Data Latch", and the output of the data latch doesn't go anywhere because the tri-state buffer is in high impedance when the TRIS bit is 1.

The information missing here is that a port write also triggers port read, because all writes are really read-modify-write operations. The datasheet says this explicitly about port A, but I suspect it works the same way on port B. This means that when you write to the port, a read is actually performed as well, so RD is asserted, removing the mismatch.

However, the mismatch being removed when you write to the port does not affect the fact that the interrupt is called, because the flag is still set, which is the only thing you need to worry about. Your code does not change, you would still perform a read and then clear the flag when you enter the isr.

You may be wondering if a read or a read-modify-write operation occurs at exactly the same time as the input change may make it miss a mismatch condition. It does not, the flag is should still be set. This is because of the input latch controlled by a signal Q1 (which is not mentioned in the text). It basically keeps the input value for the mismatch comparison during the part of the read cycle in which the RD is being asserted, so that the mismatch is still caught.

\$\endgroup\$
  • \$\begingroup\$ That's a great explanation of what's going on, thank you! \$\endgroup\$ – BG100 Jan 11 '13 at 19:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.