P16F887 PortB internal pull-ups
Posted: Tue Aug 23, 2011 11:28 pm
Internal pull-ups is a great feature of micros, when are enabled eliminate the need of external pull-up resistors when a Port is used as input. Especially in P16F887 internal pull-ups can be individually enabled per each pin of PortB. That is usefull when both "Port" (or IOC) and "INT0" interrupts are used. Let me explain a case:
An IR receiver is connected at Port RB.0 and the INT0 is enabled, so the internal pull-up of this port should be disabled since the IR receiver output is HI in iddle state and when a signal is received it drops to LO state causing the corresponding INT0 interrupt. From RB.3 to RB.7 pins, 5 switches are connected in "Active LO" mode and the "Port Interrupt" is also enabled. When a switch is pressed, applies a logic "0" to the corresponding input and thus the Port interrupt is activated. In old micros, there was the need of external pull-up resistors connected at inputs in conjunction with switches while in new micros this ensured by internal pull-up circuits connected at each pin. Mid familly AVRs like ATmega16 have internal pull-ups in all Port pins individually selectable, while PIC16 familly only in PortB pins (i don't know for higher PIC famillies). The internal weak pull-ups of PICs, are managed by the bit7 of OPTION register which of the name is RBPU. This bit is automatically set to "1" during any reset of PIC, so we have to clear it at the beginning of program. In small PICs like P16F88 when the bit RBPU is cleared activates all internal pull-ups of PortB, while P16F887 includes an extra register named WPUB allowing us to enable or disable the weak pull-up of any pin we want. That is usefull in my case for the reason i described above. After any reset, all bits of WPUB register are automatically set to "1" like the bit RBPU. While the WPUB register is configured separatelly, to take effect (i.e. to enable pull-ups) the RBPU bit should be cleared first. That is obvious ONLY in the schematic diagram of a PortB pin, the description in P16F887 datasheet regarding initialization condition of registers is some messy. Each pin is pulled in HI state by a FET which of the gate is driven by a NAND gate. One of the inputs of this NAND is driven by the RBPU bit of OPTION register. I tried this configuration with success - from a first view - in my project, but i have queries and i am not sure if the C command that i use is correct.
For first, i tried this:
1 option_reg.RBPU = 0;
2 wpub = 0xF8;
but during compiling FlowCode told me that RBPU is unknown.
Then, i tried this:
1 option_reg = 0x7F; (7Fh = 0111 1111b)
2 wpub = 0xF8; (F8h = 1111 1000b).
This time the code compiled by FlowCode with success without error messages and the project it seems to work correctly regarding internal pull-ups.
My questions are:
1) Why RBPU is not recognized like other bits of OPTION register e.g. T0SE, T0CS?
2) For clearing the bit RBPU is correct the "direct" command option_reg = 0x7F; or is better an "indirect" command like option_reg = option_reg & 0x7F;?
Thanks
Fotis
An IR receiver is connected at Port RB.0 and the INT0 is enabled, so the internal pull-up of this port should be disabled since the IR receiver output is HI in iddle state and when a signal is received it drops to LO state causing the corresponding INT0 interrupt. From RB.3 to RB.7 pins, 5 switches are connected in "Active LO" mode and the "Port Interrupt" is also enabled. When a switch is pressed, applies a logic "0" to the corresponding input and thus the Port interrupt is activated. In old micros, there was the need of external pull-up resistors connected at inputs in conjunction with switches while in new micros this ensured by internal pull-up circuits connected at each pin. Mid familly AVRs like ATmega16 have internal pull-ups in all Port pins individually selectable, while PIC16 familly only in PortB pins (i don't know for higher PIC famillies). The internal weak pull-ups of PICs, are managed by the bit7 of OPTION register which of the name is RBPU. This bit is automatically set to "1" during any reset of PIC, so we have to clear it at the beginning of program. In small PICs like P16F88 when the bit RBPU is cleared activates all internal pull-ups of PortB, while P16F887 includes an extra register named WPUB allowing us to enable or disable the weak pull-up of any pin we want. That is usefull in my case for the reason i described above. After any reset, all bits of WPUB register are automatically set to "1" like the bit RBPU. While the WPUB register is configured separatelly, to take effect (i.e. to enable pull-ups) the RBPU bit should be cleared first. That is obvious ONLY in the schematic diagram of a PortB pin, the description in P16F887 datasheet regarding initialization condition of registers is some messy. Each pin is pulled in HI state by a FET which of the gate is driven by a NAND gate. One of the inputs of this NAND is driven by the RBPU bit of OPTION register. I tried this configuration with success - from a first view - in my project, but i have queries and i am not sure if the C command that i use is correct.
For first, i tried this:
1 option_reg.RBPU = 0;
2 wpub = 0xF8;
but during compiling FlowCode told me that RBPU is unknown.
Then, i tried this:
1 option_reg = 0x7F; (7Fh = 0111 1111b)
2 wpub = 0xF8; (F8h = 1111 1000b).
This time the code compiled by FlowCode with success without error messages and the project it seems to work correctly regarding internal pull-ups.
My questions are:
1) Why RBPU is not recognized like other bits of OPTION register e.g. T0SE, T0CS?
2) For clearing the bit RBPU is correct the "direct" command option_reg = 0x7F; or is better an "indirect" command like option_reg = option_reg & 0x7F;?
Thanks
Fotis