CONFIGURING AND CONTROLLING THE PROPERTIES OF THE PORTS
The PIC 16F877A provides 33 I/O pins distributed across five ports. Each of the ports has unique capabilities built into it. This chapter discusses the capabilities of each of the ports with special attention to these special properties.
The descriptions are cursory and are designed to provide a quick and ready refer- ence. Refer to the actual data sheet for detailed information on these ports. The data sheet provides information at a level that cannot be provided in a short introductory text like this.
PORTA
PORTA is a 6-bit wide bidirectional port with both analog and digital capability.
The general rule is that if a PIC device has any analog inputs built into it, it will come up as an analog input device on reset and startup. The PIC 16F877A has analog capability on PORTA (and PORTE), so it comes up as an analog device on startup. If you are going to use it as a digital device, you have to set register ADCON1 to
%00000111. This line of code will be seen in many of the programs in this book and is explained in Chapter 9 on using LCD displays. See Table 9.8 to see how to set the various lines in PORTA and PORTE to analog or digital. (%00000111 sets all the analog pins to digital; there are many other choices.)
The PIC 16F877A supports external access to only 6 of the 8 pins on this port. Each of the 6 pins may be set to function as an input or output by appropriately loading the TRISA register. A zero in this register bit sets the corresponding pin to function as an output and a one sets it to function as an input.
Thus setting the following:
TRISA=%00111000
would make lines A0, A1, and A2 outputs and lines A3, A4, and A5 inputs. The most significant two bits are ignored (and could be set to 1s or 0s) because PORTA has only six active lines. (However, the two ignored bits are used by the processor and can be read when necessary. We can omit this here. See data sheet, Page 43, for specific details on how Pins 6 and 7 are used by the in circuit debugger.)
Note The % symbol means that this is a binary number. We will use this binary notation throughout the book because it makes it easier to see what each bit is being set to. Bit 7, the most significant bit, is on the left, bit 0 the least significant is on the right).
The specific functions of the pins are controlled with the ADCON1 (the first A to D control) register.
All the pins have TTL level inputs and full CMOS level output drivers. This makes it easy to connect these lines directly to standard logic components, meaning that usu- ally no intermediate resistors are needed between components if TTL or CMOS com- ponents are connected.
PORTA designations are somewhat complicated. Pins A0, A1, A2, A3 (skip A4), and Pin A5 can be configured as analog inputs by setting the ADCON1 register. Pin A3 is also used as a voltage input for comparing with the analog voltage inputs. Pin PORT A4 is used for the TIMER0 input and is then called T0CK1. This is Pin 6 of the PIC, and it is used as the input pin for TIMER0 only when configured as such. It is a Schmitt-triggered input with open drain output. Open drain means that it acts like the contacts of a tiny relay that go to 0 volts when closed but float when open and not connected to anything. Schmitt-triggered inputs have increased noise immunity.
The two registers that control PORTA are TRISA and ADCON1.
ADCON1 controls the A to D and voltage reference functions or PORTA. The setting of the various bits selects a complicated set of conditions that are described in detail in Table 9.8. (In the preceding discussion when ADCON1 was set to %00000111, we were accessing this feature.)
Pin A4 has special needs when used as an output. It can be pulled down low but will float when set high. It must be pulled up with a (10K to 100K) resistor to tie it high. This pin has an open drain output rather than the usual bipolar state of the other pins. This pin is skipped in the A to D conversion table.
PORTB
PORTB is a full 8-bit wide bidirectional port.
Internal circuitry (built into the MCU) allows all the pins on PORTB to be pulled up to a high state (very weakly) by setting pin 7 of the Option Register (OPTION_REG.7) to 0. These pull-ups are disabled on startup and on reset.
Pins B3, B6, and B7 are used for the low voltage programming of the PIC. Bit 3 in TRISB must be cleared (set to 0 or pulled down to 0) to negate the pull-up on this pin to allow programming to take place. See Pages 42 and 142 in the data sheet for more information on the B3 pin. It is important to keep this in mind because if for any reason Pin B3 cannot be made low it will not be possible to program the device.
Pins B4 to B7 will cause an interrupt to occur when their state changes if they are configured as inputs and the appropriate interrupts are configured. Pins that are configured as outputs will be excluded from the interrupt feature. The interrupts are controlled by the INTCON (Interrupt Control) register. This PORTB interrupt capability has the special feature that it can be used to awaken a sleeping MCU.
Pin B0 has separate (external) interrupt functions that are controlled through the INTEDG bit which is bit 6 of the OPTION_REG. (See the data sheet for more infor- mation.) External interrupts are routed to the PIC through this pin.
The three registers that control PORTB are TRISB, INTCON, and the OPTION_ REG.
OPTION_REG controls the optional functions of PORTB as follows:
N Bit 7 of OPTION_REG sets the pull-ups; programming uses
N Bit 6 of OPTION_REG sets edge selection for interrupts; programming uses
N Bit 5 of OPTION_REG sets the clock selection
N Bit 4 of OPTION_REG sets Timer 0 input pulse edge condition
N Bit 3 of OPTION_REG sets the pre-scaler option; used in low voltage programming
N Bit 2 of OPTION_REG sets pre-scaler value N Bit 1 of OPTION_REG sets pre-scaler value N Bit 0 of OPTION_REG sets pre-scaler value
PORTC
PORTC is a full 8-bit wide bidirectional port.
All the pins on PORTC have Schmitt-trigger input buffers. This means that they are designed to be more immune to noise on the input lines.
The alternate functions of the PORTC pins are defined as follows:
N Pin C0 I/O pin or Timer1 oscillator output or Timer1 Clock input
N Pin C1 I/O pin or Timer1 oscillator input or Capture 2 input or Compare 2 output or Hardware PWM2 output
N Pin C2 I/O pin or Capture 1 input or Compare 1 output or Hardware PWM1 output
N Pin C3 I/O pin or Synchronous clock for both SPI and I2C memory modes
N Pin C4 I/O pin or SPI data or data I/O for I2C mode
N Pin C5 I/O pin or Synchronous serial port data output
N Pin C6 I/O pin or USART Asynchronous transmit or synchronous clock
N Pin C7 I/O pin or USART Asynchronous receive or synchronous data
Special care has to be taken when using PORTC’s special function capabilities in that certain of these functions will change or set the I/O status of certain other pins when in use, and this can cause unforeseen complications in the function of other capabilities. See the data sheet for details.
The register that controls PORTC is the TRISC register. No other registers are involved. DEFINEs are used to control certain functions. (Using the DEFINEs is cov- ered in the PROBASIC PRO compiler language manual. This is the manual for the language we will be using to program the PIC 16F877A. The manual is provided, as a part of the compiler documentation, by microEngineering Labs.)
The speaker on the LAB-X1 board is connected to pin C1, so the use of this pin is limited because the noise generated by the speaker when this pin is used can be very irritating. Since this is one of the lines that allows the generation of continuous back- ground PWM signals (HPWM 2), it compromises the clean use of this pin unless the speaker is removed. However, I recommend that you avoid modifications to the board if you can. The load of the tiny speaker loads the pin and can compromise a few other uses but is okay for most uses.
PORTD
PORTD is a full 8-bit wide bidirectional port.
All the pins on PORTD have Schmitt-trigger input buffers. This means that they are designed to be more immune to noise on the input lines.
PORTD can also be configured as a microprocessor port by setting PSPMODE TRISE.4 to 1. (Note that you are specifying bit 4 of PORTE here internally; there is no external pin 4.) In this mode all the input pins are in TTL mode.
The alternate function of the PORTD pins are defined as follows:
N Pin D0 or parallel slave port bit 0 N Pin D1 or parallel slave port bit 1 N Pin D2 or parallel slave port bit 2 N Pin D3 or parallel slave port bit 3 N Pin D4 or parallel slave port bit 4 N Pin D5 or parallel slave port bit 5 N Pin D6 or parallel slave port bit 6 N Pin D7 or parallel slave port bit 7
The registers that control PORTD are the TRISD register and the TRISE register. TRISE controls the operation of the PORTD parallel slave port mode when Bit PORTE.4 is set to 1. (Again, only pins E0, E1, and E2 are available external to the MCU on PORTE.)
Slave port functions as set by PORTE when Bit PORTE.4 is set to 1 are as follows:
N Bit TRISE.0 direction control of Pin PORTE.0 / RD / AN5 N Bit TRISE.1 direction control of Pin PORTE.1 / WR / AN6 N Bit TRISE.2 direction control of Pin PORTE.2 / CS / AN7 N Bit TRISE.3. NOT USED
N Bit TRISE.4 Slave port select, 1 = Port selected, 0 = Use as standard I/O port
N Bit TRISE.5 Buffer overflow detect, 1 = Write occurred before reading old data, 0 = No error occurred
N Bit TRISE.6 Buffer status, 1 = still holds word, 0 = has been read
N Bit TRISE.7 Input buffer status, 1 = full, 0 = nothing received
Read the data sheets to get a better understanding of these operations. The preced- ing list is a very quick overview and is intended only to alert you and to give you an idea of what the possibilities are.
PORTE
PORTE is only three external bits wide and is a bidirectional port. The other bits are internal and are used as mentioned in the PORTD section (to which they are related). The pins on PORTE can be configured as analog or digital.
All the pins on PORTE have Schmitt-trigger input buffers.
The alternate function of the PORTE pins are defined as follows:
N Pin RE0 direction control of Pin PORTE.0 / RD / AN5 N Pin RE1 direction control of Pin PORTE.1 / WR / AN6 N Pin RE2 direction control of Pin PORTE.2 / CS / AN7
TIMERS
The three timers in the PIC 16F877A allow the accurate timing and counting of chronological events. Timers are discussed is much greater detail in Chapter 6, which is devoted exclusively to timers and counters. A fourth timer provides a watchdog function. Each timer occupies a 1- or 2-byte location in the memory.
Some of the timers have pre-scalers associated with them that can be used to multi- ply the timer setting by an integer amount. As you can imagine, the scaling ability is not adequate to allow all exact time intervals to be created. You also have to consider the uncertainty in the frequency of the clocking crystal, which is usually not exactly what it is stated to be and may drift with its temperature. This means that though fairly accurate timings can be achieved with the hardware as received, additional soft- ware adjustments may have to be added if more accurate results are desired. You do this by having the software make a correction to the timing every so often. (This also means that an external source that is at least as accurate as the result you want is needed to verify the timing accuracy of the device created.)
The three timers in the microcontroller are clocked at a fourth of the oscillator speed, meaning that a timer using a 4 MHz clock gets a counting signal at 1 MHz.
Very simply stated, an 8-bit timer will count from 0 up to 255 and then flip to 0 and start counting from 0 to 255 again. An interrupt occurs every time the timer reg- isters overflows from 255 to 0. You respond to the interrupt by doing whatever needs to be done and then resetting the interrupt flag. On timers that permit the use of a prescalar, the prescalar allows you to increase the time between interrupts by multi- plying the time between interrupts with a definable value in a 2-, 3-, or 4-bit location. On timers that can be written to, you can start the counter wherever you like to change the interrupt timing; on timers that can be read, you can read the contents whenever you like. For example, a 1-second timer setting with a prescalar set to 16 would provide you with an interrupt every 16 seconds. You will have 16 seconds to do whatever you wanted to do between the interrupts before you will miss the next interrupt.
If you needed an interrupt every 14.5 seconds, you would use a timer set to 0.5 seconds and a prescalar of 29, if 29 was specifiable (which it is not here). So not all time intervals can be created with this strategy because there are limits as to what can be put in the timer and what can be put in the prescalar when you are using 8-bit registers and specific oscillator speeds.
Pre-scalers The value of the scaling factor that will be applied to the timer is deter- mined by the contents of 2 or 3 bits in the interrupt control register. These bits multiply
the time between interrupts by powers of 2 as explained in Chapter 6. Pre-scalers and post-scalers have the same effect on the interrupts: they delay them.
Watchdog Timer A watchdog timer sets an interrupt when it runs out to tell you that for some reason the program has hung up or otherwise gone awry. As such, it is expected that in a properly written program the watchdog timer will never set an inter- rupt. This is accomplished by resetting the watchdog timer every so often within the program. The compiler does this automatically if the watchdog timer option is set. Setting the option does not guarantee a program that cannot hang up. Software errors and infinite loops that reset the timer within them can still cause hangups.
Counters Both Timer0 and Timer1 can be used as counters. Timer2 cannot be used as a counter because it has no internal or external input pin. The timers and the counters are covered in detail in Chapter 6.
The following address and web sites may be used to contact Microchip Technologies. The website provides downloads for the data sheets.
Microchip Technology Corporation, Inc. 2355 West Chandler Boulevard Chandler, Arizona 85224-6199
phone: (480) 792-7200
fax: (480) 899-9210
Website: www.microchip.com
microEngineering Labs maintains a very useful and helpful web site that will also be a tremendous aid to you as you learn about the PIC microcontrollers by using their LAB-X1. They can be reached at:
microEngineering Labs Inc. Box 60039
Colorado Springs, CO 80960-0039 or:
microEngineering Labs 1750 Brantfeather Grove
Colorado Springs, CO 80960 phone: (719) 520-5253
fax: (719) 520-1867
e-mail: support@microengineeringlabs.com Website: www.microengineeringlabs.com/index.htm