EE2801 -- Lecture 22 Using The PIC I/O Ports EE2801-L22P01
The Variety Of Available IO Ports The PIC 16F874 microcontroller has five different IO ports, accounting for thirty three of the processors forty pins! The ports are defined as: Port A: 6 bit wide bi-directional port. Most of the pins double as analog input pins. The exception is RA4, which doubles as an input for one of the internal timers. Port B: Port C: Port D: Port E: 8 bit wide bi-directional port. These are primarily general-purpose IO pins. One special feature is that these pins also contain an internal pull-up resistor that is useful to save components in some designs. (Like the keypad on the development board!) These pins can also be used to receive hardware interrupts. 8 bit wide bi-directional port. These pins also may be configured to support the serial IO functions of the microcontroller. 8 bit wide bi-directional port. These pins can be configured to act as an microprocessor-style data bus, but are most commonly used as simple digital IO. 3 bit wide bi-directional port. This port is also a general-purpose digital IO port, but it may be configured to control Port D when that port is being used as a microprocessor-style bus. EE2801-L22P02
Port D - Simple, Straightahead Digital IO A block diagram of Port D is shown below. Notice that this is actually a complicated piece of logic. Also notice that there are several control signals that must be used to setup the port to operate the way we intend: To/from the processor s data bus Active on write Data Bus WR PORT D CK Q I/O pin Data Latch D Q Active on TRIS write Active on TRIS read WR TRIS CK TRIS Latch RD TRIS Q Schmitt Trigger Input Buffer D There are eight of these circuits, one for each IO pin. EN EN Active on read RD PORT EE2801-L22P03
The TRIS, Or Tri-State Enable Registers From the block diagram of the IO port, we see that writing a 0 into the TRIS latch for Port D (TRISD) will enable the active low buffer that is attached to the output pin. This means that anything written into the data latch will be seen on the IO Pin. That same data also goes through another buffer and appears at the input of the read latch. If we write a 1 into the TRISD latch, the output buffer is turned off, and nothing will be output from the IO pin. In this case, anything present on the input pin can be read by the processor. It s interesting to note that there is a path in the block diagram that allows the TRIS Latch to be read, but there is no path that allows the TRIS Latch to drive the IO pin. Each bit of the port has a bit in the TRIS register associated with it, so each IO bit can be assigned to be an input or an output. It would even be possible to do both under program control! At some point in the program pins can be output and at another some or all of them can be reassigned! This provides a very flexible way to IO. EE2801-L22P04
An Example Of Setting Up An Output Pin The following program goes through the process of setting up a subset of Port D pins as outputs, that also implies that the rest are set up as inputs (why?). After setting up the port, I write an FFh to it, meaning that all of the output latches will contain 1s. What is the expected result when I execute this? include p16f877.inc org 0x000 ; Start program at address 000 nop ; Required for debugger ; Initialize the tri-state register to make alternating ins and outs. ; Start bsf STATUS,RP0 ; Go to BANK 1 by setting bcf STATUS,RP1 ; RP1, RP0 = 01. movlw 0xAA ; W = 1010 1010. movwf TRISD ; Set Port D for In, Out, etc. ; Now, write an FF to the outptu port. bcf STATUS,RP0 ; Go back to bank 0! movlw 0xFF ; W = FFh. movwf PORTD ; Write to Port D. Here goto Here End EE2801-L22P05
Think Carefully About What We Just Did! Let s make a minor modification to our program and now read the content of Port D. The we ll read again after setting the TRISD register to FFh. How do we explain this behavior? include p16f877.inc org 0x000 ; Start program at address 000 nop ; Required for debugger ; Initialize the tri-state register to make alternating ins and outs. ; Start bsf STATUS,RP0 ; Go to BANK 1 by setting bcf STATUS,RP1 ; RP1, RP0 = 01. movlw 0xAA ; W = 1010 1010. movwf TRISD ; Set Port D for In, Out, etc. ; Now, write an FF to the outptu port. bcf STATUS,RP0 ; Go back to bank 0! movlw 0xFF ; W = FFh. movwf PORTD ; Write to Port D. movf PORTD,W ; Get D into W. bsf STATUS, RP0 ; Go to Bank 1. clrf TRISD ; Set everything to output. bcf STATUS, RP0 ; Return to Bank 0. movf PORTD,W ; Get D into W. Here goto Here End EE2801-L22P06