Tuesday, November 17, 2015

PIC12F615 Tutorial: Timers and Interrupts

The PIC12F615 has three timers: Timer0 (8-bit), Timer1 (16-bit), and Timer3 (8-bit), these three timers/counters are completely independent and they are marked as TMR0, TMR1 and TMR2.
PIC12F615 Timer0:
this timer has an 8-bit register TMR0 and 8-bit prescaler.
The registers we need which are related to the Timer0 are: Option Register (OPTION_REG), Interrupt Counter Register (INTCON) and Timer0 register (TMR0).
Option Register (OPTION_REG):
The OPTION register is a readable and writable register,which contains various control bits to configure:
• Timer0/WDT prescaler
• External GP2/INT interrupt
• Timer0
• Weak pull-ups on GPIO 
 


pic12f615 timer0
 

Interrupt Counter Register (INTCON): The INTCON register is a readable and writable register, which contains the various enable and flag bits for TMR0 register overflow, GPIO change and external GP2/INT pin interrupts.
pic12f615 timer0 interrupt

Timer0 calculator:
We can easily calculate the frequency of timer0 interrupt using the following equation:

Timer0_freq = MCU_freq / {4 * Prescaler * (256 - TMR0)}

Maximum time for timer0 to interrupt can be found by putting prescaler 1:256 and TMR0 = 0, and assume our mcu frequency is 8MHz, so timer0_freq = 30.5176 Hz    so    time = 32.768 ms.
Timer0 interrupt example: PIC12F615 blink without delay
This example shows how to make an LED blinks with a frequency of 1Hz using timer0 interrupt. this LED is connected to GP0 as shown in the circuit schematic below. First let's make timer0 interrupt times equals to 25ms which means we need the timer0 to overflow 20 times. 
pic timer0 interrupt

 PIC12F615 Timer0 interrupt example mikroC Code:

char i;
void Interrupt(){
  if (TMR0IF_bit){
    TMR0IF_bit  = 0;
    TMR0       = 61;
    i++;
    if (i == 20){
    i = 0;
    GPIO.F0 = ~GPIO.F0; }
  }
}
void main() {
  ANSEL = 0;        // All I/O pins are configured as digital
  GPIO = 0;         // Initial state of GPIO port
  TRISIO = 0;
  OPTION_REG = 7;      // Set prescaler to 1:256
  INTCON = 0xA0;   // Enable Timer0 interrupt
  TMR0 = 61;

  while(1) ;    // Endless loop
}

PIC12F615 Timer0 interrupt example video:

PIC12F615 Timer1:
The Timer1 module is a 16-bit timer/counter with the following features:
• 16-bit timer/counter register pair (TMR1H:TMR1L)
• Programmable internal or external clock source
• 3-bit prescaler
• Optional LP oscillator
• Synchronous or asynchronous operation
• Timer1 gate (count enable) via comparator or T1G pin
• Interrupt on overflow
• Wake-up on overflow (external clock, Asynchronous mode only)
• Time base for the Capture/Compare function
• Special Event Trigger (with ECCP)
• Comparator output synchronization to Timer1 clock

In addition of the Option Register (OPTION_REG) and Interrupt Counter Register (INTCON) there are three more registers we need to use timer1 which are: TMR1H, TMR1L and Timer1 Control Register (T1CON).


pic12f615 timer1

Timer1 calculator:
We can easily calculate the frequency of timer0 interrupt using the following equation:

Timer0_freq = MCU_freq / {4 * Prescaler * (65536 - TMR1)}

Maximum time for timer1 to interrupt can be found by putting prescaler 1:8 and TMR1H = TMR1L = 0, and assume our mcu frequency is 8MHz, so timer1_freq = 3.8147 Hz    so    time = 262.144 ms.
Timer1 interrupt example:
 This example shows how to make 2 LEDs blink at frequency of 1Hz which means that 2X250 ms in needed. To get 250 ms, set the prescaler = 1:8, TMR1H = 0x0B and TMR1L = 0xDC.
The first LED is connected to GP0 and the second is connected to GP1 as shown below:

pic timer1 interrupt

Timer1 interrupt example mikroC Code:

char i;
void Interrupt(){
  if (TMR1IF_bit){
    TMR1IF_bit = 0;
    TMR1H         = 0x0B;
    TMR1L         = 0xDC;
    i++;
    if (i == 2){
    i = 0;
    GPIO.F0 = ~GPIO.F0;
    GPIO.F1 = ~GPIO.F1; }
  }
}
void main() {
  ANSEL = 0;        // All I/O pins are configured as digital
  GPIO = 1;         // Initial state of GPIO port
  TRISIO = 0;
  T1CON         = 0x31;      // Enable Timer1 and set prescaler to 1/8
  TMR1IF_bit         = 0;
  TMR1H         = 0x0B;
  TMR1L         = 0xDC;
  TMR1IE_bit         = 1;
  INTCON = 0xC0;

  while(1) ;    // Endless loop
}

PIC12F615 Timer2 module:
The Timer2 module is an 8-bit timer with the following features:
   • 8-bit timer register (TMR2)
   • 8-bit period register (PR2)
   • Interrupt on TMR2 match with PR2
   • Software programmable prescaler (1:1, 1:4, 1:16)
   • Software programmable postscaler (1:1 to 1:16)

This is a short example shows how to work with Timer2.
Circuit schematic diagram is shown below.
Using Timer2 the two LED blink at a frequency of 1 Hz.

pic timer2 interrupt

Timer2 interrupt example mikroC Code:

char i;
void Interrupt(){
  if (TMR2IF_bit){
    TMR2IF_bit = 0;
    i++;
    if (i == 20){
    i = 0;
    GPIO.F0 = ~GPIO.F0;
    GPIO.F1 = ~GPIO.F1; }
  }
}
void main() {
  ANSEL = 0;        // All I/O pins are configured as digital
  GPIO = 1;         // Initial state of GPIO port
  TRISIO = 0;
  T2CON        = 0x66;
  PR2        = 240;
  TMR2IE_bit = 1;
  INTCON  = 0xC0;


  while(1) ;    // Endless loop
}

Hardware interrupt:
Hardware interrupts are very useful or we can say that they are necessary in some applications like remote controls applications. These interrupts are sent form an external device to the microcontroller.
The PIC12F615 has two types of hardware interrupts: external GP2/INT pin interrupt and GPIO change interrupt.
External GP2/INT pin interrupt:
This interrupt occurs when there is a change at the GP2 pin according to what it has been programmed on rising edge or falling edge.
Registers associated with external GP2/INT pin interrupt:
This interrupt is affected by two registers: OPTION_REG (bit 6) and INTCON register (bits 7, 4, 1).
External GP2/INT pin interrupt example:
This is an example of using the external interrupt to turn on and off an Led connected to GP0 as shown in the following circuit schematic:

pic external hardware interrupt


 External GP2/INT pin interrupt example mikroC Code:

 void Interrupt(){
  if (INTF_bit){
    INTF_bit = 0;
    GPIO.F0 = ~GPIO.F0; // Invert GP0 output
  }
 }
 void main() {
  ANSEL = 0;        // All I/O pins are configured as digital
  GPIO = 0;         // Initial state of GPIO port
  TRISIO = 0x04;    // Configure GP2 as input
  OPTION_REG = 0;   // Enable WPU and set ext int on falling edge
  INTCON  = 0x90;   // Enable external inturrept
  WPU = 0x04;       // Enable GP2 pull-up

  while(1) ;    // Endless loop
 }


GPIO Change Interrupt:
This is another hardware interrupt which makes the microcontroller interrupted when there is a change on one input of GPIO port.
This interrupt is related specially to two registers: INTCON (bits: 7, 3, 0) and IOC (INTERRUPT-ON-CHANGE GPIO REGISTER).
GPIO Change Interrupt example:
This example is a small application that uses GPIO change interrupt to turn on/off an Led connected to GP0 as shown below:

pic gpio change interrupt

GPIO Change Interrupt example mikroC Code:

 void Interrupt(){
  if (GPIF_bit){
    GPIO.F0 = ~GPIO.F0; // Invert GP0 output
    GPIF_bit = 0;
  }
 }
 void main() {
  ANSEL = 0;        // All I/O pins are configured as digital
  GPIO = 0;         // Initial state of GPIO port
  TRISIO = 0x30;    // Configure GP5 and GP6 as inputs
  OPTION_REG = 0;   // Enable WPU pull-up resistors
  INTCON  = 0x88;   // Enable GPIO change inturrept
  WPU = 0x30;       // Enable GP5 and GP4 pull-ups
  IOC = 0x30;       // Enable inturrupt on change for GP5 and GP4

  while(1) ;    // Endless loop
 }

There are some other interrupts which are:
  • A/D Converter (ADC) Interrupt
  • CCP1 Interrupt
  • Comparator Interrupt.
References:
PIC12F615 datasheet