Monday, September 6, 2010

PIC16F887/877 programming in C Tutorial 3-1 (Timer 0)

Both PIC16f887 and 877 have three timers; timer 0, timer 1, and timer 2. Timer 0 is 8-bit and can also be use as counter, Timer 1 is 16-bit timer as well as a counter, where as Timer 2 is 8-bit timer and can be used as the PWM time base for the PWM mode of the CCP module(s). 

Timer 0:
The Timer0 module timer/counter has the following features:
  • 8-bit timer/counter
  • Readable and writable
  • 8-bit software programmable prescaler
  • Internal or external clock select
  • Interrupt on overflow from FFh to 00h
  • Edge select (rising or falling) for external clock
Timer mode is selected by clearing bit T0CS (OPTION_REG<5>). In Timer mode, the Timer0 module will increment every instruction cycle (without prescaler).

Counter mode is selected by setting bit T0CS (OPTION_REG<5>). In Counter mode, Timer0 will increment either on every rising or falling edge of pin RA4/T0CKI. The incrementing edge is determined by the Timer0 Source Edge Select bit, T0SE
(OPTION_REG<4>). Clearing bit T0SE selects the rising edge.

Timer0 has a register called TMR0 Register, which is 8 bits of size. We can write the desired value into the register which will be increment as the program progresses. Frequency varies depending on the Prescaler. Maximum value that can be assigned to this register is 255.

TMR0IF - TMR0 Overflow Interrupt Flag bit.
The TMR0 interrupt is generated when the TMR0 register overflows from FFh to 00h. This overflow sets bit TMR0IF (INTCON<2>).

Prescaler - Frequency divider.
We can use prescaler to further divide the clock frequency, the options ere: 
      PS2:PS0             TMR0 rate
         000                       1:2
         001                       1:4
         010                       1:8

         011                       1:16
         100                       1:32

         101                       1:64
         110                       1:128

         111                       1:256

Option Register:
Option reg is a 8-bit register used to initialize the timer0.

Calculating Count, Fout, and TMR0 values:

If using INTERNAL crystal as clock, the division is performed as follow: 

TIMER0 formula

Fout– The output frequency after the division.

Tout – The Cycle Time after the division.

4 - The division of the original clock by 4, when using internal crystal as clock (and not external oscillator).

Count - A numeric value to be placed to obtain the desired output frequency - Fout.

(256 - TMR0) - The number of times in the timer will count based on the register TMR0.

 If using EXTERNAL clock source (oscillator), the division is performed as follow:

TIMER0 formula

In this case there is no division by 4 of the original clock. We use the external frequency as it is.

Now lets write the code for 0.5 sec delay;

void main() {
   // using 4MHz ext xtal
     int count=0;

 ///////////////// comment 4 pic16f877/////////

     t0se_bit=0;          //  low to high edge trigger
     t0cs_bit=0;          // using internal clk
     psa_bit=0;            //using prescaler
     ps0_bit=1;            //prescaler 256



     if(cunt==8){                       //delay 0.5 sec(256*256u*8)


1 comment:

  1. Nice variable names in the above code snippet!!