Introduction to microprocessors Feisal Mohammed 3rd January 2001 Additional features 1 Input/Output Ports One of the features that differentiates a microcontroller from a microprocessor is the presence of I/O ports. The PIC16F8x has two ports, PORTA, which is 5-bits wide, and PORTB, 8-bits wide. Some of the port pins are multiplexed with an alternate function to support other features. Each port has a direction register associated with it that controls the setting of the direction of each of the lines a port. 1.1 PORTA and TRISA Registers PORTA is at address 0x05 and its direction register, TRISA, is at address 0x85, which means that PORTA is in Bank 0 and TRISA is in Bank 1. Therefore either indirect addressing or bank switching must be performed to access the direction register. PORTA is a 5-bit wide latch with its pins labeled as RA0 to RA4. RA4 is a Schmitt Trigger input and an open drain output. All other RAx port pins have TTL input levels and full CMOS output drivers. All the pins have direction bits which are contained within the TRISA register and thus can be individually configured as either input or output. Setting a TRISA bit will make the corresponding PORTA bit an input and conversely clearing a TRISA bit will make the corresponding PORTA pin an output. A read of the PORTA register reads the status of the pins whereas writing to it will write to the port latch. All write operations are read-modify-write operations which means that writing to a port implies that the port pins are first read, then this value is modified and then written to the port data latch. Name Bit Buffer Type Function RA0 bit0 TTL Input/Output RA1 bit1 TTL Input/Output RA2 bit2 TTL Input/Output RA3 bit3 TTL Input/Output RA4/T0CK1 bit4 ST Input/Output or external clock input for TMR0 Table 1: PORTA Functions Address Name Bit 7 Bit 6 Bit 5 Bit 4 Bit 3 Bit 2 Bit 1 Bit 0 Power-on value Normal value 0x05 PORTA - - - RA4/T0CK1 RA3 RA2 RA1 RA0 x xxxx u uuuu 0x85 TRISA - - - TRISA4 TRISA3 TRISA2 TRISA1 TRISA0 1 1111 1 1111 Table 2: Summary of registers associated with PORTA
The following example shows how PORTA can be initialized, ; assume that we are in Bank 0 clrf PORTA ; Set the output latches of PORTA to zero bsf STATUS,RP0 ; Switch to Bank 1 movlw 0x0F ; Value for data direction movwf TRISA ; set RA<3:0> as inputs and RA4 as output bcf STATUS,RP0 ; switch back to Bank 0 or alternatively using indirect addressing. clrf PORTA ; Set the output latches of PORTA to zero movlw TRISA ; Setup for indirect addressing movwf FSR ;...by moving address to FSR movlw 0x0F ; Value for data direction movwf INDF ; set RA<3:0> as inputs and RA4 as output 1.2 PORTB and TRISB Registers PORTB is very similar to PORTA. It is an 8-bit wide bi-directional port with the pin directions being controlled by the TRISB register. Each of the PORTB pins can have a weak internal pull-up, which can all be turned on by a single control bit. This bit being the RBPU (OPTION_REG<7>) bit. The weak pull-up is automatically disabled when the port pin is configured as an output. The pull-ups are also disabled by a power-on reset. The first pin, RB<0>, can be used as an external interrupt input. Four of the port pins, RB<7:4>, have an interrupt on change feature where pins that are configured as inputs generate an interrupt when a change occurs. The change is obtained by comparing the pins value in input mode with the old value latched on the last read of PORTB. The mismatched outputs of the pins are OR ed together to generate the port change interrupt. This interrupt can be used to wake the device from SLEEP. Within the interrupt service routine the interrupt can be cleared by: Read (or write) PORTB. This will end the mismatch condition. Clear bit flag RBIF in the INTCON register. As long as there is a mismatch condition the RBIF bit will be set and it can only be cleared after the mismatch condition has ended. Initialization of PORTB is done in a similar fashion to PORTA. The following table shows the bit assignments in the Option register that pertain to to PORTB. bit 7: bit 6: Option Register RBPU: PORTB Pull-up Enable bit 1 = PORTB pull-ups are disabled 0 = PORTB pull-ups are enabled (by individual port latch values) INTEDG: Interrupt Edge Select bit 1 = Interrupt on rising edge of RB0/INT pin 0 = Interrupt on falling edge of RB0/INT pin 2
Name Bit Buffer Type Function RB0/INT bit0 TTL/ST Input/Output or external interrupt input RB1 bit1 TTL Input/Output RB2 bit2 TTL Input/Output RB3 bit3 TTL Input/Output RB4 bit4 TTL Input/Output with interrupt on change RB5 bit4 TTL Input/Output with interrupt on change RB6 bit4 TTL/ST Input/Output with interrupt on change. Serial programming clock. RB7 bit4 TTL/ST Input/Output with interrupt on change. Serial programming data. Table 3: PORTB Functions Address Name Bit 7 Bit 6 Bit 5 Bit 4 Bit 3 Bit 2 Bit 1 Bit 0 Power-on value Normal value 0x06 PORTB RB7 RB6 RB5 RB4 RB3 RB2 RB1 RB0/INT xxxx xxxx uuuu uuuu 0x86 TRISB TRISB7 TRISB6 TRISB5 TRISB4 TRISB3 TRISB2 TRISB1 TRISB0 1111 1111 1111 1111 0x81 OPTION_REG RBPU INTEDG - - - - - - 1111 1111 1111 1111 Table 4: Summary of registers associated with PORTB 1.3 I/O Programming Considerations Any instruction which writes, operates internally as a read followed by a write operation. For example, the bsf and bcf instructions first read a register into the CPU, execute the bit clear/set operation and write the result back to the register. Care must be taken when these instructions are applied to a port that is configured for both input and output. A bsf operation on bit 5 of PORTB will cause all eight bits of PORTB to be read into the CPU. Then the bit set operation takes place on bit 5 and the result is written to the output latches. If another bit, say bit 0, of PORTB is defined as an input at this time, the input signal present on the pin itself would be read into the CPU and rewritten to the data latch of this particular pin, overwriting the previous content. As long as the pin stays in the input mode, no problem occurs. However when bit 0 is switched into output mode later on, the content of the data latch is unknown. An example is shown below: ; Initial port settings: PORTB<7:4> Input ; PORTB<3:0> Output ; PORTB<7:6> have external pullups are not connected ; to any other circuitry ; ; Port Latch Port pins ; ---------- --------- 1 bcf PORTB,7 ; 01pp pppp 11pp pppp 2 bcf PORTB,6 ; 10pp pppp 11pp pppp 3 bsf STATUS,RP0 ; 4 bcf TRISB,7 ; 10pp pppp 11pp pppp 5 bcf TRISB,6 ; 10pp pppp 10pp pppp At line 2, it would seem that the port latch s high byte should be 00pp but when the instruction is executed, the port pins are read again, thus the bit clear acts on 11pp pppp. 3
2 Timers There are two built-in timers on the PIC16F8x, Timer 0 (TMR0) and the WatchDog Timer (WDT). These timers both share a single programmable prescaler which can be used to extend their ranges. When TMR0 uses the internal clock it is said to operate in timer mode and it uses an external clock it is said to operate in counter mode. The WatchDog timer generates a device reset whenever it overflows and is normally used to recover from any malfunction that corrupts the contents of the program counter. For example, in unattended operations if a failure occurs in the program and the device gets into a perpetual loop, the watchdog timer can be used to reset the microcontroller and thus exit the loop. It can also be used in low-power battery applications to awaken the CPU periodically. 2.1 Timer 0 The Timer 0 timer/counter has the following features: 8-bit timer/counter 8-bit software programmable prescalar Internal or external clock select Interrupt on overflow from 0xFF to 0x00 Edge select for external clock Timer mode is selected by clearing the T0CS bit (OPTION_REG<5>). In timer mode, the TMR0 will increment on every instruction cycle. Counter mode is selected by setting the T0CS bit. In this mode, TMR0 will increment either on every rising or falling edge of pin RA4/T0CK1. The incrementing edge is determined by the T0 Source Edge select bit, T0SE (OPTION_REG<4>). Clearing bit T0SE selects the rising edge. The prescaler is shared between the Timer 0 and the Watchdog Timer. The prescaler assignment is controlled by bit PSA (OPTION_REG<3>). Clearing bit PSA will assign the prescaler to Timer 0. When this is done the prescale value is software selectable using the bits PS2:PS0 (OPTION_REG<2:0>). The prescaler is neither readable or writeable. Table 5 show the bits from the Option register that pertain to TMR0. When the prescaler is assigned to Timer 0, all instructions that write to the TMR0 register will clear the contents of the prescaler. When it is assigned to the WDT, a clrwdt instruction will clear the contents of the prescaler along with the Watchdog Timer. The TMR0 interrupt is generated when the TMR0 register overflows from 0xFF to 0x00. This overflow sets the TOIF bit (INTCON<2>). The interrupt can be masked by clearing the TOIE bit (INTCON<5>). The TOIF bit must be cleared in software, by the Timer 0 interrupt service routine, before re-enabling this interrupt. 2.1.1 Operation of the prescaler The prescaler is like an additional counter that is placed in series with Timer 0. Assume that the prescaler is set to 1:4 and both it and the Timer 0 are initialized to zero. The first clock pulse will increment the prescaler 4
Table 5: Option Register bits associated with TMR0 bit 5: bit 4: bit 3: bit 2-0: Option Register TOCS: TMR0 Clock Source Select bit 1 = Transition on RA4/T0CK1 pin 0 = Internal instruction cycle clock T0SE: TMR0 Source Edge Select bit 1 = Increment on high-to-low transition on RA4/T0CK1 pin 0 = Increment on low-to-high transition on RA4/T0CK1 pin PSA: Prescaler Assignment bit 1 = Prescaler assigned to the WDT 0 = Prescaler assigned to TMR0 PS2:PS0: Prescaler Rate Select bits Bit value TMR0 rate WDT rate 000 1:2 1:1 001 1:4 1:2 010 1:8 1:4 011 1:16 1:8 100 1:32 1:16 101 1:64 1:32 110 1:128 1:64 111 1:256 1:128 to 1, while the timer will remain on zero. Subsequent clock pulses will continue incrementing the prescaler only, until it contains 3. The next clock pulse will cause the prescaler to rollover to 0 and the timer will increment to 1. Since the prescaler cannot be read, a timer reading of say 10 with a prescale value of 1:4 can correspond to number of clock ticks from anywhere between 40 and 43. 2.1.2 Changing the prescaler assignment In order to avoid an unintended device reset the following two routines must be used when switching the assignment from Timer 0 to the WDT and vice versa. These are only needed if the WDT is used. ; Changing from Timer 0 to WDT (assumes Bank 0 i.e. RP0 cleared) clrf TMR0 ; clear TMR0 and prescaler bsf STATUS,RP0 ; switch to Bank 1 clrwdt ; clear Watchdog timer movlw b xxxxx1xxx ; select new assignment and prescale value movwf OPTION_REG bcf STATUS,RP0 ; back to Bank 0 ; Changing from WDT to Timer 0 (assumes in Bank 0) clrwdt ; clear WDT and prescaler 5
bsf STATUS,RP0 ; switch to Bank 1 movlw b xxxx0xxx ; select Timer 0 movwf OPTION_REG bcf STATUS, RP0 ; back to Bank 0 2.2 Watchdog timer The Watchdog Timer (WDT) is a free running on-chip RC oscillator which does not require any external components. This oscillator is separate from any other oscillator on the microcontroller, which means that it will continue running even if the other oscillators have been stopped, for example during a sleep instruction. During normal operation a WDT time-out generates a device RESET. If the device is in SLEEP mode, a WDT Wake-up causes the device to wake-up and continue with normal operation. The same prescaler that was used with Timer 0 can also be assigned to the WDT but it is used as a postscaler instead. The clrwdt and sleep instructions clear the WDT and the postscaler (if assigned to the WDT) and prevent it from timing out and generating a device RESET condition. 6