Friday, February 03, 2006

Chapter 3: I/O Ports

Chapter 3: I/O Ports

Features and Functions

One of the most important feature of the microcontroller is a number of input/output pins used for connection with peripherals. In this case, there are in total of thirty-five general purpose I/O pins available, which is quite enough for the most applications.
In order pins’ operation can match internal 8-bit organization, all of them are, similar to registers, grouped into five so called ports denoted by A, B, C, D and E. They all have several features in common:
  • For practical reasons, many I/O pins have two or three functions. If a pin is used as any other function, it may not be used as a general purpose input/output pin; and
  • Every port has its “satellite”, i.e. the corresponding TRIS register: TRISA, TRISB, TRISC etc. which determines performance, but not the contents of the port bits.
By clearing some bit of the TRIS register (bit=0), the corresponding port pin is configured as output. Similarly, by setting some bit of the TRIS register (bit=1), the corresponding port pin is configured as input. This rule is easy to remember 0 = Output, 1 = Input.
I/O Ports
Fig. 3-1 I/O Ports

Port A and TRISA Register

Port A is an 8-bit wide, bidirectional port. Bits of the TRISA and ANSEL control the PORTA pins. All Port A pins act as digital inputs/outputs. Five of them can also be analog inputs (denoted as AN):
Port A and TRISA Register
Fig. 3-2 Port A and TRISA Register
Similar to bits of the TRISA register which determine which of the pins will be configured as input and which as output, the appropriate bits of the ANSEL register determine whether the pins will act as analog inputs or digital inputs/outputs.
  • RA0 = AN0 (determined by bit ANS0 of the ANSEL register);
  • RA1 = AN1 (determined by bit ANS1 of the ANSEL register);
  • RA2 = AN2 (determined by bit ANS2 of the ANSEL register);
  • RA3 = AN3 (determined by bit ANS3 of the ANSEL register); and
  • RA5 = AN4 (determined by bit ANS4 of the ANSEL register).
Each bit of this port has an additional function related to some of built-in peripheral units. These additional functions will be described in later chapters. This chapter covers only the RA0 pin’s additional function since it is related to Port A only.

ULPWU Unit

The microcontroller is commonly used in devices which have to operate periodically and, completely independently using a battery power supply. In such cases, minimal power consumption is one of the priorities. Typical examples of such applications are: thermometers, sensors for fire detection and similar. It is known that a reduction in clock frequency reduces the power consumption, so one of the most convenient solutions to this problem is to slow the clock down (use 32KHz quartz crystal instead of 20MHz).
Microcontroller wakes up periodically by itself
Setting the microcontroller to sleep mode is another step in the same direction. However, even when both measures are applied, another problem arises. How to wake the microcontroller and set it to normal mode. It is obviously necessary to have an external signal to change logic state on some of the pins. Thus, the problem still exists. This signal must be generated by additional electronics, which causes higher power consumption of the entire device.
The ideal solution would be the microcontroller wakes up periodically by itself, which is not impossible at all. The circuit which enables that is shown in figure on the right.
Fig. 3-3 ULPWU Unit
The principle of operation is simple:
A pin is configured as output and logic one (1) is brought to it. That causes the capacitor to be charged. Immediately after this, the same pin is configured as an input. The change of logic state enables an interrupt and the microcontroller is set to Sleep mode. Afterwards, there is nothing else to be done except wait for the capacitor to discharge by the leakage current flowing out through the input pin. When it occurs, an interrupt takes place and the microcontroller continues with the program execution in normal mode. The whole sequence is repeated...
Microcontroller wakes up details
Theoretically, this is a perfect solution. The problem is that all pins able to cause an interrupt in this way are digital and have relatively large leakage current when their voltage is not close to the limit values Vdd (1) or Vss (0). In this case, the capacitor is discharged for a short time since the current amounts to several hundreds of microamperes. This is why the ULPWU circuit able to register slow voltage drops with ultra low power consumption was designed. Its output generates an interrupt, while its input is connected to one of the microcontroller pins. It is the RA0 pin. Referring to Fig. 3-4 (R=200 ohms, C=1nF), discharge time is approximately 30mS, while the total consumption of the microcontroller is 1000 times lower (several hundreds of nanoamperes).
Fig. 3-4 Sleep Mode

Port B and TRISB Register

Port B is an 8-bit wide, bidirectional port. Bits of the TRISB register determine the function of its pins.
Port B and TRISB register
Fig. 3-5 Port B and TRISB register
Similar to Port A, a logic one (1) in the TRISB register configures the appropriate port pin as input and vice versa. Six pins on this port can act as analog inputs (AN). The bits of the ANSELH register determine whether these pins act as analog inputs or digital inputs/outputs:
  • RB0 = AN12 (determined by bit ANS12 of the ANSELH register);
  • RB1 = AN10 (determined by bit ANS10 of the ANSELH register);
  • RB2 = AN8 (determined by bit ANS8 of the ANSELH register);
  • RB3 = AN9 (determined by bit ANS9 of the ANSELH register);
  • RB4 = AN11 (determined by bit ANS11 of the ANSELH register); and
  • RB5 = AN13 (determined by bit ANS13 of the ANSELH register).
Each Port B pin has an additional function related to some of the built-in peripheral units, which will be explained in later chapters.
  • All the port pins have built in pull-up resistor, which make them ideal for connection to push-buttons, switches and optocouplers. In order to connect these resistors to the microcontroller ports, the appropriate bit of the WPUB register should be set.*
WPUB register
Fig. 3-6 WPUB register
Having a high level of resistance (several tens of kilo ohms), these “virtual” resistors do not affect pins configured as outputs, but serves as a useful complement to inputs. As such, they are connected to CMOS logic circuit inputs. Otherwise, they would act as if they are floating because of their high input resistance.
Pull-up resistors
Fig. 3-7 Pull-up resistors
* Apart from the bits of the WPUB register, there is another bit affecting pull-up resistors installation. It is RBPU bit of the OPTION_REG. It is a general-purpose bit because it affects installation of all Port resistors.
  • If enabled, each Port B bit configured as an input may cause an interrupt by changeing its logic state. In order to enable pins to cause an interrupt, the appropriate bit of the IOCB register should be set.
IOCB register
Fig. 3-8 IOCB register
Because of these features, the port B pins are commonly used for checking push-buttons on the keyboard because they unerringly register any button press. Therefore, there is no need to “scan” these inputs all the time.
Keyboard Example
Fig. 3-9 Keyboard Example
When the X, Y and Z pins are configured as outputs set to logic one (1), it is only necessary to wait for an interrupt request which arrives upon any button press. By combining zeros and units on these outputs it is checked which push-button is pressed.

Pin RB0/INT

The RB0/INT pin is a single “true” external interrupt source. It can be configured to react to signal raising edge (zero-to-one transition) or signal falling edge (one-to-zero transition). The INTEDG bit of the OPTION_REG register selects the signal.

RB6 and RB7 Pins

You have probably noticed that the PIC16F887 microcontroller does not have any special pins for programming (writing the program to ROM). The Ports pins available as general purpose I/O pins during normal operation are used for this purpose (Port B pins clock (RB6) and data transfer (RB7) during program loading). In addition, it is necessary to apply a power supply voltage Vdd (5V) and Vss (0V), as well as voltage for FLASH memory programming Vpp (12-14V). During programming, Vpp voltage is applied to the MCLR pin. All details concerning this process, as well as which one of these voltages is applied first, are beside the point, the programmers electronics are in charge of that. The point is that the program can be loaded to the microcontroller even when it is soldered onto the target device. Normally, the loaded program can also be changed in the same way. This function is called ICSP (In-Circuit Serial Programming). It is necessary to plan ahead when using it.
ICSP programming connector
It is not complicated at all! It is only necessary to install a 4-pin connector onto the target device so that the necessary programmer voltages may be applied to the microcontroller. In order that these voltages don't interfere with other device electronics, design some sort of circuit breaking into this connection (using resistors or jumpers).
Fig. 3-10 ICSP Connection
Programmer socket signals
These voltages are applied to socket pins in which the microcontroller is to be placed.
Fig. 3-11 Programmer On-Board Connections

Port C and TRISC Register

Port C is an 8-bit wide, bidirectional port. Bits of the TRISC Register determine the function of its pins. Similar to other ports, a logic one (1) in the TRISC Register configures the appropriate port pin as an input.
Port C and TRISC Register
Fig. 3-12 Port C and TRISC Register
All additional functions of this port's bits will be explained later.

Port D and TRISD Register

Port D is an 8-bit wide, bidirectional port. Bits of the TRISD register determine the function of its pins. A logic one (1) in the TRISD register configures the appropriate port pin as input.
Port D and TRISD Register
Fig. 3-13 Port D and TRISD Register

Port E and TRISE Register

Port E is a 4-bit wide, bidirectional port. The TRISE register’s bits determine the function of its pins. Similar to other ports, a logic one (1) in the TRISE register configures the appropriate port pin as input. The exception is RE3 which is input only and its TRIS bit is always read as ‘1’.
Port E and TRISE Register
Fig. 3-14 Port E and TRISE Register
Similar to Ports A and B, three pins can be configured as analog inputs in this case. The ANSELH register bits determine whether a pin will act as analog input (AN) or digital input/output:
  • RE0 = AN5 (determined by bit ANS5 of the ANSELregister);
  • RE1 = AN6 (determined by bit ANS6 of the ANSELregister); and
  • RE2 = AN7 (determined by bit ANS7 of the ANSELregister).

ANSEL and ANSELH Registers

The ANSEL and ANSELH registers are used to configure the input mode of an I/O pin to analog or digital.
ANSEL and ANSELH Registers
Fig. 3-15 ANSEL and ANSELH Registers
The rule is:
To configure a pin as an analog input, the appropriate bit of the ANSEL or ANSELH registers must be set (1). To configure pin as digital input/output, the appropriate bit must be cleared (0).
The state of the ANSEL bits has no affect on digital output functions. The result of any attempt to read some port pin configured as analog input will be 0.
ANSEL and ANSELH Configuration
Fig. 3-16 ANSEL and ANSELH Configuration

In Short:

You will probably never write a program which fully utilises all the Ports in an efficient manner to justify learning all there is to know about these Ports. However, they are probably the simplest modules within the microcontroller. This is how they are used:
  • When designing a device, select a port through which the microcontroller will communicate to the peripheral environment. If you intend using only digital inputs/outputs, select any port you want. If you intend using some of the analog inputs, select the appropriate ports supporting such pins configuration (AN0-AN13);
  • Each port pin may be configured as either input or output. Bits of the TRISA, TRISB, TRISC, TRISD and TRISE registers determine how the appropriate ports pins- PORTA, PORTB, PORTC, PORTD and PORTE will act;
  • If you use some of the analog inputs, set the appropriate bits of the ANSEL and ANSELH registers at the beginning of the program;
  • If you use switches and push-buttons as input signal source, connect them to Port B pins because they have pull-up resistors. The use of these resistors is enabled by the RBPU bit of the OPTION_REG register, whereas the installation of individual resistors is enabled by bits of the WPUB register; and
  • It is usually necessary to react as soon as input pins change their logic state. How ever, it is not necessary to write a program for changing pins' logic state. It is far simpler to connect such inputs to the PORTB pins and enable the interrupt on every voltage change. Bits of the registers IOCOB and INTCON are in charge of that.

Thursday, February 02, 2006

Chapter 2:Core SFRs

Chapter 2: Core SFRs

Features and Function

The special function registers can be classified into two categories:
  • Core (CPU) registers - control and monitor operation and processes in the central processor. Even though there are only a few of them, the operation of the whole microcontroller depends on their contents.
  • Peripheral SFRs- control the operation of peripheral units (serial communication module, A/D converter etc.). Each of these registers is mainly specialized for one circuit and for that reason they will be described along with the circuit they are in control of.
The core (CPU) registers of the PIC16F887 microcontroller are described in this chapter. Since their bits control several different circuits within the chip, it is not possible to classify them into some special group. These bits are described along with the processes they control.

STATUS Register

STATUS Register Legend
Fig. 2-1 STATUS Register
The STATUS register contains: the arithmetic status of the W register, the RESET status and the bank select bits for data memory. One should be careful when writing a value to this register because if you do it wrong, the results may be different than expected. For example, if you try to clear all bits using the CLRF STATUS instruction, the result in the register will be 000xx1xx instead of the expected 00000000. Such errors occur because some of the bits of this register are set or cleared according to the hardware as well as because the bits 3 and 4 are readable only. For these reasons, if it is required to change its content (for example, to change active bank), it is recommended to use only instructions which do not affect any Status bits (C, DC and Z). Refer to “Instruction Set Summary”.
  • IRP - Bit selects register bank. It is used for indirect addressing.
    • 1 - Banks 0 and 1 are active (memory location 00h-FFh)
    • 0 - Banks 2 and 3 are active (memory location 100h-1FFh)
  • RP1,RP0 - Bits select register bank. They are used for direct addressing.
RP1 RP0 Active Bank
0 0 Bank0
0 1 Bank1
1 0 Bank2
1 1 Bank3
Table 2-1
  • TO - Time-out bit.
    • 1 - After power-on or after executing CLRWDT instruction which resets watch-dog timer or SLEEP instruction which sets the microcontroller into low-consumption mode.
    • 0 - After watch-dog timer time-out has occurred.
  • PD - Power-down bit.
    • 1 - After power-on or after executing CLRWDT instruction which resets watch-dog timer.
    • 0 - After executing SLEEP instruction which sets the microcontroller into low-consumption mode.
  • Z - Zero bit
    • 1 - The result of an arithmetic or logic operation is zero.
    • 0 - The result of an arithmetic or logic operation is different from zero.
  • DC - Digit carry/borrow bit is changed during addition and subtraction if an “overflow” or a “borrow” of the result occurs.
    • 1 - A carry-out from the 4th low-order bit of the result has occurred.
    • 0 - No carry-out from the 4th low-order bit of the result has occurred.
  • C - Carry/Borrow bit is changed during addition and subtraction if an “overflow” or a “borrow” of the result occurs, i.e. if the result is greater than 255 or less than 0.
    • 1 - A carry-out from the most significant bit of the result has occurred.
    • 0 - No carry-out from the most significant bit of the result has occurred.

OPTION_REG Register

OPTION_REG Register
Fig.2-2
The OPTION_REG register contains various control bits to configure: Timer0/WDT prescaler, timer TMR0, external interrupt and pull-ups on PORTB.
RBPU Port B Pull up Enable bit
  • RBPU - Port B Pull up Enable bit.
    • 1 - PortB pull-ups are disabled.
    • 0 - PortB pull-ups are enabled.
Fig.2-3
RBPU Port B Pull up Enable bit
  • INTEDG - Interrupt Edge Select bit.
    • 1 - Interrupt on rising edge of RB0/INT pin.
    • 0 - Interrupt on falling edge of RB0/INT pin.
Fig.2-4
T0CS - TMR0 Clock Source Select bit
  • T0CS - TMR0 Clock Source Select bit.
    • 1 - Transition on TOCKI pin.
    • 0 - Internal instruction cycle clock (Fosc/4).
Fig.2-5
T0SE - TMR0 Source Edge Select bit
  • T0SE - TMR0 Source Edge Select bit selects pulse edge (rising or falling) counted by the timer TMR0 through the RA4/T0CKI pin.
    • 1 - Increment on high-to-low transition on TOCKI pin.
    • 0 - Increment on low-to-high transition on TOCKI pin.
Fig.2-6
PSA - Prescaler Assignment bit
  • PSA - Prescaler Assignment bit assigns prescaler (only one exists) to the timer or watchdog timer.
    • 1 - Prescaler is assigned to the WDT.
    • 0 - Prescaler is assigned to the TMR0.
Fig.2-7
PS2, PS1, PS0 Prescaler Rate Select bits
Prescaler rate is selected by combining these three bits. Described, as shown in the table below, prescaler rate depends on whether prescaler is assigned (TMR0) or watch-dog timer (WDT).
PS2 PS1 PS0 TMR0 WDT
0 0 0 1:2 1:1
0 0 1 1:4 1:2
0 1 0 1:8 1:4
0 1 1 1:16 1:8
1 0 1 1:64 1:32
1 1 0 1:128 1:64
1 1 1 1:256 1:128
Table 2-2
In order to achieve 1:1 prescaler rate when the timer TMR0 counts up pulses, the prescaler should be assigned to the WDT. As a result of this, the timer TMR0 does not use the prescaler, but directly counts pulses generated by the oscillator, which was the objective!

Interrupt System Registers

When an interrupt request arrives it does not mean that interrupt will automatically occur, because it must also be enabled by the user (from within the program). Because of that, there are special bits used to enable or disable interrupts. It is easy to recognize these bits by IE contained in their names (stands for Interrupt Enable). Besides, each interrupt is associated with another bit called the flag which indicates that interrupt request has arrived regardless of whether it is enabled or not. They are also easily recognizable by the last two letters contained in their names- IF (Interrupt Flag).
As seen, everything is based on a simple and efficient idea. When an interrupt request arrives, the flag bit is to be set first.
Interrupt System Registers
Fig. 2-8 Interrupt System Registers
If the appropriate IE bit is not set (0), this event will be completely ignored. Otherwise, an interrupt occurs! In case several interrupt sources are enabled, it is necessary to detect the active one before the interrupt routine starts execution. Source detection is performed by checking flag bits.
It is important to understand that the flag bits are not automatically cleared, but by software during interrupt routine execution. If this detail is neglected, another interrupt will occur immediately upon return to the program, even though there are no more requests for its execution! Simply put, the flag as well as IE bit remained set.
All interrupt sources typical of the PIC16F887 microcontroller are shown on the next page. Note several things:
  • GIE bit - enables all unmasked interrupts and disables all interrupts simultaneously.
  • PEIE bit - enables all unmasked peripheral interrupts and disables all peripheral interrupts (This does not concern Timer TMR0 and port B interrupt sources).
To enable interrupt caused by changing logic state on port B, it is necessary to enable it for each bit separately. In this case, bits of the IOCB register have the function to control IE bits.
Interrupt SFRs
Fig. 2-9 Interrupt SFRs

INTCON Register

The INTCON register contains various enable and flag bits for TMR0 register overflow, PORTB change and external INT pin interrupts.
INTCON Register Legend
Fig. 2-10 INTCON Register
  • GIE - Global Interrupt Enable bit - controls all possible interrupt sources simultaneously.
    • 1 - Enables all unmasked interrupts.
    • 0 - Disables all interrupts.
  • PEIE - Peripheral Interrupt Enable bit acts similar to GIE, but controls interrupts enabled by peripherals. It means that it does not affect interrupts triggered by the timer TMR0 or by changing state on port B or RB0/INT pin.
    • 1 - Enables all unmasked peripheral interrupts.
    • 0 - Disables all peripheral interrupts.
  • T0IE - TMR0 Overflow Interrupt Enable bit controls interrupt enabled by TMR0 overflow.
    • 1 - Enables the TMR0 interrupt.
    • 0 - Disables the TMR0 interrupt.
  • INTE - RB0/INT External Interrupt Enable bit controls interrupt caused by changing logic state on pin RB0/IN (external interrupt).
    • 1 - Enables the INT external interrupt.
    • 0 - Disables the INT external interrupt.
  • RBIE - RB Port Change Interrupt Enable bit. When configured as inputs, port B pins may cause interrupt by changing their logic state (no matter whether it is highto- low transition or vice versa, fact that something is changed only matters). This bit determines whether interrupt is to occur or not.
    • 1 - Enables the port B change interrupt.
    • 0 - Disables the port B change interrupt.
  • T0IF - TMR0 Overflow Interrupt Flag bit registers the timer TMR0 register overflow, when counting starts from zero.
    • 1 - TMR0 register has overflowed (bit must be cleared in software).
    • 0 - TMR0 register has not overflowed.
  • INTF - RB0/INT External Interrupt Flag bit registers change of logic state on the RB0/INT pin.
    • 1 - The INT external interrupt has occurred (must be cleared in software).
    • 0 - The INT external interrupt has not occurred.
  • RBIF - RB Port Change Interrupt Flag bit registers change of logic state of some port B input pins.
    • 1 - At least one of the port B general purpose I/O pins has changed state. Upon reading portB, RBIF (flag bit) must be cleared in software.
    • 0 - None of the port B general purpose I/O pins has changed state.

PIE1 Register

The PIE1 register contains the peripheral interrupt enable bits.
PIE1 register Legend
Fig. 2-11 PIE1 register
  • ADIE - A/D Converter Interrupt Enable bit.
    • 1 - Enables the ADC interrupt.
    • 0 - Disables the ADC interrupt.
  • RCIE - EUSART Receive Interrupt Enable bit.
    • 1 - Enables the EUSART receive interrupt.
    • 0 - Disables the EUSART receive interrupt.
  • TXIE - EUSART Transmit Interrupt Enable bit.
    • 1 - Enables the EUSART transmit interrupt.
    • 0 - Disables the EUSART transmit interrupt.
  • SSPIE - Master Synchronous Serial Port (MSSP) Interrupt Enable bit - enables an interrupt request to be generated after each data transfer via synchronous serial communication module (SPI or I2C mode).
    • 1 - Enables the MSSP interrupt.
    • 0 - Disables the MSSP interrupt.
  • CCP1IE - CCP1 Interrupt Enable bit enables an interrupt request to be generated in CCP1 module used for PWM signal processing.
    • 1 - Enables the CCP1 interrupt.
    • 0 - Disables the CCP1 interrupt.
  • TMR2IE - TMR2 to PR2 Match Interrupt Enable bit
    • 1 - Enables the TMR2 to PR2 match interrupt.
    • 0 - Disables the TMR2 to PR2 match interrupt.
  • TMR1IE - TMR1 Overflow Interrupt Enable bit enables an interrupt request to be generated after each timer TMR1 register overflow, i.e. when the counting starts from zero.
    • 1 - Enables the TMR1 overflow interrupt.
    • 0 - Disables the TMR1 overflow interrupt.

PIE2 Register

The PIE2 Register also contains the various interrupt enable bits.
PIE2 Register Legend
Fig. 2-12 PIE2 Register
  • OSFIE - Oscillator Fail Interrupt Enable bit.
    • 1 - Enables oscillator fail interrupt.
    • 0 - Disables oscillator fail interrupt.
  • C2IE - Comparator C2 Interrupt Enable bit.
    • 1 - Enables Comparator C2 interrupt.
    • 0 - Disables Comparator C2 interrupt.
  • C1IE - Comparator C1 Interrupt Enable bit.
    • 1 - Enables Comparator C1 interrupt.
    • 0 - Disables Comparator C1 interrupt.
  • EEIE - EEPROM Write Operation Interrupt Enable bit.
    • 1 - Enables EEPROM write operation interrupt.
    • 0 - Disables EEPROM write operation interrupt.
  • BCLIE - Bus Collision Interrupt Enable bit.
    • 1 - Enables bus collision interrupt.
    • 0 - Disables bus collision interrupt.
  • ULPWUIE - Ultra Low-Power Wake-up Interrupt Enable bit.
    • 1 - Enables Ultra Low-Power Wake-up interrupt.
    • 0 - Disables Ultra Low-Power Wake-up interrupt.
  • CCP2IE - CCP2 Interrupt Enable bit.
    • 1 - Enables CCP2 interrupt.
    • 0 - Disables CCP2 interrupt.

PIR1 Register

The PIR1 register contains the interrupt flag bits.
PIR1 Register Legend
Fig. 2-13 PIR1 Register
  • ADIF - A/D Converter Interrupt Flag bit.
    • 1 - A/D conversion is completed (bit must be cleared in software).
    • 0 - A/D conversion is not completed or has not started.
  • RCIF - EUSART Receive Interrupt Flag bit.
    • 1 - The EUSART receive buffer is full. Bit is cleared by reading the RCREG register.
    • 0 - The EUSART receive buffer is not full.
  • TXIF - EUSART Transmit Interrupt Flag bit.
    • 1 - The EUSART transmit buffer is empty. Bit is cleared by writing to the TXREG register.
    • 0 - The EUSART transmit buffer is full.
  • SSPIF - Master Synchronous Serial Port (MSSP) Interrupt Flag bit.
    • 1 - The MSSP interrupt condition during data transmit/receive has occurred. These conditions differ depending on MSSP operating mode (SPI or I2C) This bit must be cleared in software before returning from the interrupt service routine.
    • 0 - No MSSP interrupt condition has occurred.
  • CCP1IF - CCP1 Interrupt Flag bit.
    • 1 - CCP1 interrupt condition has occurred (CCP1 is unit for capturing, comparing and generating PWM signal). Depending on operating mode, capture or compare match has occurred. In both cases, bit must be cleared in software. This bit is not used in PWM mode.
    • 0 - No CCP1 interrupt condition has occurred.
  • TMR2IF - Timer2 to PR2 Interrupt Flag bit
    • 1 - TMR2 (8-bit register) to PR2 match has occurred. This bit must be cleared in software before returning from the interrupt service routine.
    • 0 - No TMR2 to PR2 match has occurred.
  • TMR1IF - Timer1 Overflow Interrupt Flag bit
    • 1 - The TMR1 register has overflowed. This bit must be cleared in software.
    • 0 - The TMR1 register has not overflowed.

PIR2 Register

The PIR2 register contains the interrupt flag bits.
PIR2 register Legend
Fig. 2-14 PIR2 register
  • OSFIF - Oscillator Fail Interrupt Flag bit.
    • 1 - System oscillator failed and clock input has changed to internal oscillator INTOSC. This bit must be cleared in software.
    • 0 - System oscillator operates normally.
  • C2IF - Comparator C2 Interrupt Flag bit.
    • 1 - Comparator C2 output has changed (bit C2OUT). This bit must be cleared in software.
    • 0 - Comparator C2 output has not changed.
  • C1IF - Comparator C1 Interrupt Flag bit.
    • 1 - Comparator C1 output has changed (bit C1OUT). This bit must be cleared in software.
    • 0 - Comparator C1 output has not changed.
  • EEIF - EE Write Operation Interrupt Flag bit.
    • 1 - EEPROM write completed. This bit must be cleared in software.
    • 0 - EEPROM write is not completed or has not started.
  • BCLIF - Bus Collision Interrupt Flag bit.
    • 1 - A bus collision has occurred in the MSSP when configured for I2C Master mode. This bit must be cleared in software.
    • 0 - No bus collision has occurred.
  • ULPWUIF - Ultra Low-power Wake-up Interrupt Flag bit.
    • 1 - Wake-up condition has occurred. This bit must be cleared in software.
    • 0 - No Wake-up condition has occurred.
  • CCP2IF - CCP2 Interrupt Flag bit.
    • 1 - CCP2 interrupt condition has occurred (unit for capturing, comparing and generating PWM signal). Depending on operating mode, capture or compare match has occurred. In both cases, the bit must be cleared in software. This bit is not used in PWM mode.
    • 0 - No CCP2 interrupt condition has occurred.

PCON register

The PCON register contains only two flag bits used to differentiate between a: power-on reset, brown-out reset, Watchdog Timer Reset and external reset (through MCLR pin).
PIR2 register Legend
Fig. 2-15 PCON register
  • ULPWUE - Ultra Low-Power Wake-up Enable bit
    • 1 - Ultra Low-Power Wake-up enabled.
    • 0 - Ultra Low-Power Wake-up disabled.
  • SBOREN - Software BOR Enable bit
    • 1 - Brown-out Reset enabled.
    • 0 - Brown-out Reset disabled.
  • POR - Power-on Reset Status bit
    • 1 - No Power-on reset has occurred.
    • 0 - Power-on reset has occurred. This bit must be set in software after a Power-on Reset occurs.
  • BOR - Brown-out Reset Status bit
    • 1 - No Brown-out reset has occurred.
    • 0 - Brown-out reset has occurred. This bit must be set in software after a Brown-out Reset occurs.

PCL and PCLATH Registers

The size of the program memory of the PIC16F887 is 8K. Therefore, it has 8192 locations for program storing. For this reason the program counter must be 13-bits wide (2^13 = 8192). In order that the contents of some location may be changed in software during operation, its address must be accessible through some SFR. Since all SFRs are 8-bits wide, this register is “artificially” created by dividing its 13 bits into two independent registers: PCLATH and PCL.
If the program execution does not affect the program counter, the value of this register is automatically and constantly incremented +1, +1, +1, +1... In that way, the program is executed just as it is written- instruction by instruction, followed by a constant address increment.
PCL and PCLATH Registers
Fig. 2-16 PCL and PCLATH Registers
If the program counter is changed in software, then there are several things that should be kept in mind in order to avoid problems:
  • Eight lower bits (the low byte) come from the PCL register which is readable and writable, whereas five upper bits coming from the PCLATH register are writable only.
  • The PCLATH register is cleared on any reset.
  • In assembly language, the value of the program counter is marked with PCL, but it obviously refers to 8 lower bits only. One should take care when using the “ADDWF PCL” instruction. This is a jump instruction which specifies the target location by adding some number to the current address. It is often used when jumping into a look-up table or program branch table to read them. A problem arises if the current address is such that addition causes change on some bit belonging to the higher byte of the PCLATH register. Do you see what is going on?
    Executing any instruction upon the PCL register simultaneously causes the Prog ram Counter bits to be replaced by the contents of the PCLATH register. However, the PCL register has access to only 8 lower bits of the instruction result and the following jump will be completely incorrect. The problem is solved by setting such instructions at addresses ending by xx00h. This enables the program to jump up to 255 locations. If longer jumps are executed by this instruction, the PCLATH register must be incremented by 1 for each PCL register overflow.
  • On subroutine call or jump execution (instructions CALL and GOTO), the microcontroller is able to provide only 11-bit addressing. For this reason, similar to RAM which is divided in “banks”, ROM is divided in four “pages” in size of 2K each. Such instructions are executed within these pages without any problems. Simply, since the processor is provided with 11-bit address from the program, it is able to address any location within 2KB. Figure 2-17 below illustrates this situation as a jump to the subroutine PP1 address.
    However, if a subroutine or jump address are not within the same page as the location from where the jump is, two “missing”- higher bits should be provided by writing to the PCLATH register. It is illustrated in figure 2-17 below as a jump to the subroutine PP2 address.
PCLATH Registers
Fig. 2-17 PCLATH Registers
In both cases, when the subroutine reaches instructions RETURN, RETLW or RETFIE (to return to the main program), the microcontroller will simply continue program execution from where it left off because the return address is pushed and saved onto the stack which, as mentioned, consists of 13-bit registers.

Indirect addressing

In addition to direct addressing which is logical and clear by itself (it is sufficient to specify address of some register to read its contents), this microcontroller is able to perform indirect addressing by means of the INDF and FSR registers. It sometimes considerably simplifies program writing. The whole procedure is enabled because the INDF register is not true one (physically does not exist), but only specifies the register whose address is located in the FSR register. Because of this, write or read from the INDF register actually means write or read from the register whose address is located in the FSR register. In other words, registers’ addresses are specified in the FSR register, and their contents are stored in the INDF register. The difference between direct and indirect addressing is illustrated in the figure 2-18 below:
As seen, the problem with the “missing addressing bits” is solved by “borrowing” from another register. This time, it is the seventh bit called IRP from the STATUS register.
Direct and Indirect addressing
Fig. 2-18 Direct and Indirect addressing

Wednesday, February 01, 2006

PIC16F887 Microcontroller

Chapter 1: PIC16F887 Microcontroller - Device Overview

The PIC16F887 is one of the latest products from Microchip. It features all the components which modern microcontrollers normally have. For its low price, wide range of application, high quality and easy availability, it is an ideal solution in applications such as: the control of different processes in industry, machine control devices, measurement of different values etc. Some of its main features are listed below.
  • RISC architecture
    • Only 35 instructions to learn
    • All single-cycle instructions except branches
  • Operating frequency 0-20 MHz
  • Precision internal oscillator
    • Factory calibrated
    • Software selectable frequency range of 8MHz to 31KHz
  • Power supply voltage 2.0-5.5V
    • Consumption: 220uA (2.0V, 4MHz), 11uA (2.0 V, 32 KHz) 50nA (stand-by mode)
  • Power-Saving Sleep Mode
  • Brown-out Reset (BOR) with software control option
  • 35 input/output pins
    • High current source/sink for direct LED drive
    • software and individually programmable pull-up resistor
    • Interrupt-on-Change pin
  • 8K ROM memory in FLASH technology
    • Chip can be reprogrammed up to 100.000 times
  • In-Circuit Serial Programming Option
    • Chip can be programmed even embedded in the target device
  • 256 bytes EEPROM memory
    • Data can be written more than 1.000.000 times
  • 368 bytes RAM memory
  • A/D converter:
    • 14-channels
    • 10-bit resolution
  • 3 independent timers/counters
  • Watch-dog timer
  • Analogue comparator module with
    • Two analogue comparators
    • Fixed voltage reference (0.6V)
    • Programmable on-chip voltage reference
  • PWM output steering control
  • Enhanced USART module
    • Supports RS-485, RS-232 and LIN2.0
    • Auto-Baud Detect
  • Master Synchronous Serial Port (MSSP)
    • supports SPI and I2C mode
PIC16F887 PDIP 40 Microcontroller
Fig. 1-1 PIC16F887 PDIP 40 Microcontroller
PIC16F887 QFN 44 Microcontroller
Fig. 1-2 PIC16F887 QFN 44 Microcontroller
PIC16F887 Block Diagram
Fig. 1-3 PIC16F887 Block Diagram

Pin Description

As seen in Fig. 1-1 above, the most pins are multi-functional. For example, designator RA3/AN3/Vref+/C1IN+ for the fifth pin specifies the following functions:
  • RA3 Port A third digital input/output
  • AN3 Third analog input
  • Vref+ Positive voltage reference
  • C1IN+ Comparator C1positive input
This small trick is often used because it makes the microcontroller package more compact without affecting its functionality. These various pin functions cannot be used simultaneously, but can be changed at any point during operation.
The following tables, refer to the PDIP 40 microcontroller.
Pin Assignment (a)
Table 1-1 Pin Assignment
Pin Assignment (b)
Table 1-1 cont. Pin Assignment
Pin Assignment (c)
Table 1-1 cont. Pin Assignment

Central Processor Unit (CPU)

I’m not going to bore you with the operation of the CPU at this stage, however it is important to state that the CPU is manufactured with in RISC technology an important factor when deciding which microprocessor to use.
RISC Reduced Instruction Set Computer, gives the PIC16F887 two great advantages:
  • The CPU can recognizes only 35 simple instructions (In order to program some other microcontrollers it is necessary to know more than 200 instructions by heart).
  • The execution time is the same for all instructions except two and lasts 4 clock cycles (oscillator frequency is stabilized by a quartz crystal). The Jump and Branch instructions execution time is 2 clock cycles. It means that if the microcontroller’s operating speed is 20MHz, execution time of each instruc tion will be 200nS, i.e. the program will be executed at the speed of 5 million instructions per second!
CPU Memory
Fig. 1-4 CPU Memory

Memory

This microcontroller has three types of memory- ROM, RAM and EEPROM. All of them will be separately discussed since each has specific functions, features and organization.

ROM Memory

ROM memory is used to permanently save the program being executed. This is why it is often called “program memory”. The PIC16F887 has 8Kb of ROM (in total of 8192 locations). Since this ROM is made with FLASH technology, its contents can be changed by providing a special programming voltage (13V).
Anyway, there is no need to explain it in detail because it is automatically performed by means of a special program on the PC and a simple electronic device called the Programmer.
ROM Memory Consept
Fig. 1-5 ROM Memory Consept

EEPROM Memory

Similar to program memory, the contents of EEPROM is permanently saved, even the power goes off. However, unlike ROM, the contents of the EEPROM can be changed during operation of the microcontroller. That is why this memory (256 locations) is a perfect one for permanently saving results created and used during the operation.

RAM Memory

This is the third and the most complex part of microcontroller memory. In this case, it consists of two parts: general-purpose registers and special-function registers (SFR).
Even though both groups of registers are cleared when power goes off and even though they are manufactured in the same way and act in the similar way, their functions do not have many things in common.
SFR and General Purpose Registers
Fig. 1-6 SFR and General Purpose Registers

General-Purpose Registers

General-Purpose registers are used for storing temporary data and results created during operation. For example, if the program performs a counting (for example, counting products on the assembly line), it is necessary to have a register which stands for what we in everyday life call “sum”. Since the microcontroller is not creative at all, it is necessary to specify the address of some general purpose register and assign it a new function. A simple program to increment the value of this register by 1, after each product passes through a sensor, should be created.
Therefore, the microcontroller can execute that program because it now knows what and where the sum which must be incremented is. Similarly to this simple example, each program variable must be preassigned some of general-purpose register.

SFR Registers

Special-Function registers are also RAM memory locations, but unlike general-purpose registers, their purpose is predetermined during manufacturing process and cannot be changed. Since their bits are physically connected to particular circuits on the chip (A/D converter, serial communication module, etc.), any change of their contents directly affects the operation of the microcontroller or some of its circuits. For example, by changing the TRISA register, the function of each port A pin can be changed in a way it acts as input or output. Another feature of these memory locations is that they have their names (registers and their bits), which considerably facilitates program writing. Since high-level programming language can use the list of all registers with their exact addresses, it is enough to specify the register’s name in order to read or change its contents.

RAM Memory Banks

The data memory is partitioned into four banks. Prior to accessing some register during program writing (in order to read or change its contents), it is necessary to select the bank which contains that register. Two bits of the STATUS register are used for bank selecting, which will be discussed later. In order to facilitate operation, the most commonly used SFRs have the same address in all banks which enables them to be easily accessed.
RAM Memory Banks Overview
Table 1-2 Address Banks
SFR Bank 0
Table 1-3 SFR Bank 0
SFR Bank 1
Table 1-4 SFR Bank 1
SFR Bank 2
Table 1-5 SFR Bank 2
SFR Bank 3
Table 1-6 SFR Bank 3

STACK

A part of the RAM used for the stack consists of eight 13-bit registers. Before the microcontroller starts to execute a subroutine (CALL instruction) or when an interrupt occurs, the address of first next instruction being currently executed is pushed onto the stack, i.e. onto one of its registers. In that way, upon subroutine or interrupt execution, the microcontroller knows from where to continue regular program execution. This address is cleared upon return to the main program because there is no need to save it any longer, and one location of the stack is automatically available for further use.
It is important to understand that data is always circularly pushed onto the stack. It means that after the stack has been pushed eight times, the ninth push overwrites the value that was stored with the first push. The tenth push overwrites the second push and so on. Data overwritten in this way is not recoverable. In addition, the programmer cannot access these registers for write or read and there is no Status bit to indicate stack overflow or stack underflow conditions. For that reason, one should take special care of it during program writing.

Interrupt System

The first thing that the microcontroller does when an interrupt request arrives is to execute the current instruction and then stop regular program execution. Immediately after that, the current program memory address is automatically pushed onto the stack and the default address (predefined by the manufacturer) is written to the program counter. That location from where the program continues execution is called the interrupt vector. For the PIC16F887 microcontroller, this address is 0004h. As seen in Fig. 1-7 below, the location containing interrupt vector is passed over during regular program execution.
Part of the program being activated when an interrupt request arrives is called the interrupt routine. Its first instruction is located at the interrupt vector. How long this subroutine will be and what it will be like depends on the skills of the programmer as well as the interrupt source itself. Some microcontrollers have more interrupt vectors (every interrupt request has its vector), but in this case there is only one. Consequently, the first part of the interrupt routine consists in interrupt source recognition.
Finally, when the interrupt source is recognized and interrupt routine is executed, the microcontroller reaches the RETFIE instruction, pops the address from the stack and continues program execution from where it left off.
Interrupt System
Fig.1-7 Interrupt System

How to use SFRs

You have bought the microcontroller and have a good idea how to use it...There is a long list of SFRs with all bits. Each of them controls some process. All in all, it looks like a big control table with a lot of instruments and switches. Now you are concerned about whether you will manage to learn how to use them all? You will probably not, but don’t worry, you don’t have to! Such powerful microcontrollers are similar to a supermarkets: they offer so many things at low prices and it is only up to you to choose. Therefore, select the field you are interested in and study only what you need to know. Afterwards, when you completely understand hardware operation, study SFRs which are in control of it ( there are usually a few of them). To reiterate, during program writing and prior to changing some bits of these registers, do not forget to select the appropriate bank. This is why they are listed in the tables above.