Electrical – 1 sec delay using PIC18F TImer 0

pictimer

I am trying to generate a 1 s delay using Timer0 of PIC18F2520. I am using the internal 8 MHz oscillator. The timer works with FOSC/4 so I have :

8 Mhz/4 = 2 Mhz
T = 1/2 MHz = 0.5 µs

Now the number of counts for rollover is 0xFFFF (65536) so according to the delay I want I need to set the values of TMR0L and TMR0H. Now let's say I want a delay of 1000 ms, so:

65536 - 64536 = 1000 ms
64536 (0xFC18) is the value which I need to put in TMR0L and TMR0H.

If the above calculations are correct then the following code should work properly (using the C18 compiler):

#include <p18F2520>

#pragma config WDT = OFF       //Disable watchdog timer
#pragma config OSC = INTIO67   //Internal oscillator
#pragma config LVP = OFF

void main()
{

 //8Mhz oscillator
 OSCCONbits.IRCF0 = 1;
 OSCCONbits.IRCF1 = 1;
 OSCCONbits.IRCF2 = 1;
 OSCCONbits.SCS = 1;

 TRISCbits.TRISC2 = 0;    //output led

 while(1)
 {
    LATCbits.LATC2 = 1;
    DelayMs();
    LATCbits.LATC2 = 0;
    DelayMs();
 }
}

void DelayMs()
{
  T0CONbits.PSA = 0;         //Prescaler assignment bits
  T0CONbits.T0CS=0;          //clock source select bit
  T0CONbits.T0PS = 0x01;     //1:4 prescaler 

  TMR0H= 0xFC;       
  TMR0L=0x18;
  T0CONbits.TMR0ON = 1;       //enable timer1
  while(INTCONbits.TMR0IF==0);
  T0CONbits.TMR0ON = 0;
  INTCONbits.TMR0IF=0;

}

When I programmed the device with the code above, the LED was on. It didn't turn off even after 4-5 minutes.

Best Answer

According to what you described the timer clocks at 2MHz. That is equivalent to 500nsec per tick of the timer.

When you program the timer to 64536 you are specifying that the timer should count for 1000 cycles before timing out.

1000 cycles at 500 nsec per cycle = 500,000 nsec = 500 usec

So in your while loop where you are trying to toggle the port pin to flash the LED the DelayMs() call is giving your LED a cycle time of 1 msec (500 usec off + 500 usec on).

With the LED flashing at 1msec rate (a.k.a 1kHz) the LED will appear to be on all the time!!

If your real goal was to have the LED on for 0.5 second and off for 0.5 second then you will need to increase your delays by 1000. So put each of the calls to DelayMs() within your while loop inside a for loop that would iterate the delay 1000 times.