You are on page 1of 40

Lecture 6

Free-Run Timer TMR0

Physically, TMR0 timer is a register whose value is continually increasing to 255, and then it starts all over again.
0, 1, 2, 3, 4...255....0,1, 2, 3......etc.

After each count up to 255, TMR0 resets its value to zero and starts with a new cycle of counting to 255. During each transition from 255 to zero, T0IF bit in INTCOM register is set If interrupts are allowed to occur, this can be taken advantage of in generating interrupts and in processing interrupt routine It is up to programmer to reset T0IF bit in interrupt routine, so that new interrupt, or new overflow could be detected

TMR0 Timing
TMR0 is readable and writable

If TMR0 register is written, the increment is inhibited for the following two cycles

TMR0 Clock Source

Beside the internal oscillator clock, timer status can also be increased by the external clock on RA4/TOCKI pin. This is done by setting the T0CS bit (OPTION_REG<5>).

Rising or Falling Edge Triggering

If external clock on RA4/TOCKI pin is used, it is possible to define the edge of a signal (rising or falling), on which timer would increase its value. The edge is determined by T0 source edge select bit, T0SE (OPTION_REG<4>) Clearing bit T0SE selects the rising edge

Write a program to sent a 0xFF to Port B after every 1s. Assume that you have a 250Hz clock at RA4/TOCKI pin.

The 8-bit Prescaler divides oscillator clock before it will reach logic that increases timer status The highest divisor is 256. This actually means that only at every 256th clock, timer value would increase by one For example, if the TMR0 prescaler is set to divide-by-4 and the PIC is running at 4 MHz, the prescaler will send a 250 KHz clock to the TMR0 register.

The prescaler is not readable or writable. The prescale value is defined through first three bits in OPTION register


Prescaler Assignment
The prescaler is shared between TMR0 and WDT It is mutually exclusive between TMR0 and WDT
A prescaler assignment for TMR0 means that there is no prescaler for WDT, and vice-versa

The prescaler assignment is controlled by control bit PSA (OPTION_REG<3>)


Clearing Prescaler
When assigned to TMR0, all instructions writing to TMR0 (e.g., CLRF 1, MOVWF 1, BSF 1,x ....etc.) will clear the prescaler. When assigned to WDT, a CLRWDT instruction will clear the prescaler along with WDT


Switching Prescaler Assignment

To avoid an unintended device RESET, these instructions must be executed when changing prescaler assignment between TMR0 to WDT. This sequence must be taken even if the WDT is disabled.

TMR0 Example
Example showing how to initialize timer to signal falling edges from external clock source with a prescaler 1:4.


TMR0 Interrupt
TMR0 interrupt is generated when the TMR0 register overflows from 0xff to 0x00 This overflow sets the T0IF bit (INTCON<2>). The interrupt can be masked by clearing enable bit T0IE (INTCON<5>). The T0IF bit must be cleared by the TMR0 interrupt service routine before re-enabling this interrupt. TMR0 interrupt cannot wake the processor up from SLEEP since the timer is shut off during SLEEP.

Example showing how to initialize timer to signal falling edges from external clock source with a prescaler 1:4




There are 2 main ways for external I/O devices to communicate with the ucontroller Polling and Interrupt In polling, the ucontroller periodically query input devices to see if data is available
The ucontroller first stops processing its main program and enters the polling routine The I/O device is then queried for data. If there is data, the service routine is executed When the device has been serviced, the ucontroller resumes its main program

Polling can effectively assign priorities among input devices by querying the highest priority device first


Given that 3 devices (A, B and C) are connected to RB0, RB1 and RB2, write a program to poll the devices. If any of the devices is activated, call the XYZ subroutine. The priority for the devices are A, B then C.


For the interrupt method, I/O devices issue a signal (interrupt) to the ucontroller when the device needs to be serviced The interrupt request can come at any time during the execution of a program The interrupt forces a call to the service subroutine which is usually referred to as an interrupt service routine On interrupt, the processor saves the return address on the stack and program control is redirected to the interrupt service routine

An interrupt in its simplest form is like a hardware triggered subroutine.
Main Program 16F84 INT


Interrupt Service Routine



Peripheral Interrupt Vector

The microcontroller needs to be told where the interrupt service routine is located It does this by looking to the peripheral interrupt vector (0x0004). This location informs the CPU where the interrupt service routine is located. Reset directs program flow to location 000H Interrupt direct program flow to location 004H

Program using Interrupts

A program using interrupts is usually structured as follows:
org 000H ;Reset directs program to here goto MAIN org 004H ;Interrupt directs program to here goto INT_SERV MAIN: ; Your main program INT_SERV: ; Your interrupt service routine 24

Saving Register Data

When an interrupt occurs (it can happen at any time), it is wise to save the contents of both the STATUS and the W register This is trickier than it might appear. Note that instruction MOVWF does not affect any status bits. Thus, the W register is easily saved; MOVWF W_SAVE But, saving STATUS involves moving it to W and unfortunately, MOVF STATUS, W will change status bits. However, SWAPF STATUS, W doesn't. Thus, the STATUS register may be saved. SWAPF STATUS, W MOVWF STATUS_SAVE


Saving and Restoring W


Sources of Interrupts
PIC16F84 has 4 sources of interrupt:
External interrupt RB0/INT pin Timer overflow interrupt Port B interrupt on change (pins RB7:RB4) EEPROM write complete interrupt

These interrupts are disabled/enabled through the interrupt control register (INTCON)


The Interrupt Control Register

The interrupt control register (INTCON)
Contains the individual and global interrupt enable bits Records individual interrupt requests in flag bits.

The global interrupt enable bit (GIE) enables/disables all interrupts

BSF INTCON, GIE ; enable all interrupt BCF INTCON, GIE ; disable all interrupt

On RESET, the GIE bit is cleared


Individual Interrupt Enable Bits

Individual interrupts can also be enabled or disabled through their corresponding enable bits
BSF INTCON, INTE ;enable RB0/INT interrupt BSF INTCON, RBIE ;enable RB4-7 change interrupt BSF INTCON, TOIE ;enable timer interrupt

Any of these may be used alone, or several sources may be enabled, depending on your application. At any time in the program, the user may turn any of the sources off by clearing these mask bits;

On RESET, these bits are cleared.


Interrupts (INTCON) Register



Interrupt Flag Bit

On interrupt, a flag bit associated with the type of interrupt is set by the processor. These flag bits are used to determine the source of the interrupt and perform the appropriate action


Interrupt Procedure
When an interrupt occurs:
GIE bit is cleared to disable any further interrupt. Return address is pushed onto the stack. Program counter is loaded with 0x0004 Once in the interrupt service routine, the source(s) of the interrupt can be determined by polling the interrupt flag bits The GIE bit is again set on execution of the return from interrupts (RETFIE)


Interrupt Procedure
The occurrence of an interrupt event sets the flag bit (if GIE and the mask bit are set) It is the user's responsibility to clear the flag bit within the service routine
BCF INTCON, INTF ; clear external INT flag BCF INTCON, RBIF ; clear RB4 - RB7 interrupt flag BCF INTCON, TOIF ; clear timeout flag

Failure to clear the flag bit is interpreted by the processor as "a previous interrupt occurred, but the user has yet to service the interrupt". Thus, although an interrupt event may occur, GIE may be enabled and a mask bit may be set, the actual interrupt will not occur unless the corresponding flag bit is clear

Interrupt Example



INT Interrupts
The INT interrupt is an external interrupt on RB0/INT pin It is edge triggered: either rising if INTEDG bit (OPTION<6>) is set or falling if INTEDG is clear When a valid edge appears on the RB0/INT pin the INTF bit (INTCON<1>) is set This interrupt can be disabled by clearing control bit INTE (INTCON<4>) The INT interrupt can wake the processor from SLEEP only if the INTE bit was set prior to going into SLEEP.

Write a program to count the number of positive transitions on input RB0/INT. Display the last two bits of the count on 2 LEDS connected to RB6 and RB7.


Example: Cont.
INT_SERV: INCF COUNTER, F BTFSS COUNTER, 0 BCF PORTB, 6 BTFSC COUNTER, 0 BSF PORTB, 6 BTFSS COUNTER, 1 BCF PORTB, 7 BTFSC COUNTER, 1 BSF PORTB, 7 BCF INTCON, INTF ; clear the appropriate flag RETFIE ; this also set global interrupt enable END


TMR0 Interrupts
The TMR0 interrupt is triggered by an overflow (0xff to 0x00) in TMR0 The overflow sets the flag bit TOIF (INTCON<2>) The interrupt can be enabled/disabled by setting/clearing enable bit TOIE (INTCON<5>).


Using interrupt, write a program to sent 0xFF to Port B after approximately 1s. Assume that you have a 1KHz clock at RA4/TOCKI pin.


PORT RB Interrupts
PORT RB Interrupt is triggered by input changes on portb<7:4> The interrupt sets the flag bit RBIF (INTCON<0>) The interrupt can be enabled/disabled by setting/clearing enable bit RBIE (INTCON<3>). This interrupt is useful for a keypad interface.