Electronic – Timers acting weirdly

microchiposcillatorpictimer

  • PIC24FJ1024GB610 from Microchip

  • Debugger Pikit On Board from Explorer 16/32 Development Board from Microchip

I wrote a program, where I tried to create a 250 ms Delay using Timer 1, and whenever the Timer 1 Interrupt Flag IFS0bits.T1IF is set, the pin connected to the LED PORTAbits.RA7 / LATAbits.LATA7 will toggle.

this is the following code:

#include <xc.h>

#pragma config FWDTEN = OFF //watchdog timer off
#pragma config FNOSC = FRC //Osc source from FRC (8MHz)
#pragma config ICS = PGD2

#define LED LATAbits.LATA7
#define TMR1_IF IFS0bits.T1IF
#define GLOBAL_INT INTCON2bits.GIE 
#define TRIS_LED TRISAbits.TRISA7

void Set_LED (void)
{
    TRISAbits.TRISA7 = 0;//output
    ANSAbits.ANSA7 = 0;//Digital Not Analogue
    LED = 0;  
}

void Set_Timer1 (void)
{
    T1CONbits.TCS = 1;//Clock Source internal from Tcy 
    T1CONbits.TCKPS = 2;//1:64
    T1CONbits.TSIDL = 0;//continues through idle mode

    /*
     Fosc = 8MHz, Fosc/2 = Fcy = 4MHz
     Tcy = 1/Fcy = 1/4 us = 0.25 us
     t = 250 ms = 250,000 us
     t = Tcy*(PRESCALAR)*PR1
     PR1 = t/(Tcy*PRESCALAR)
     PR1 = 250,000 / (0.25*64)
     PR1 = 15625
    */

    PR1 = 15625;

   T1CONbits.TON = 1;//run timer
}

int main (void)
{
    Set_LED ();//Set LEDs
    Set_Timer1 ();//Set Timers


    while(1)
    {
        while(!TMR1_IF);//stay till IFS0bits.T1IF = 0

        LED = !LED;//Toggle LED / LATAbits.LATA7

        TMR1_IF = 0; //Clear Interrupt Flag

    }

    return 0;
}

I run the program into the PIC24, and I expect the LED to blink very fast but instead, it takes (approximately) 40 sec to toggle the LED.

This confuses me, because I checked OSC Datasheet page, and the Timer 1 Datasheet page from the PIC24FJ1024GB610 Datasheet, it seems fine, and I should expect a 250 ms toggle.

Looking at the DS, this is what I deducted:

enter image description here

  • FNOSC = FRC hence source is FRC (Fosc = 8MHz)
  • Fosc gets divided by 2, insctruction frequence (4MHz)
  • Register associated with DOZE is CLKDIV
  • CLKDIVbits.DOZEN = 0, CPU Peripheral Clock ratio is 1:1, hence Fcy = 4MHz
  • Tcy = 1/Fcy, Tcy = 1/4 us = 0.25 us

enter image description here

  • T1CONbits.TCS = 1 Clock Source is internal from FRC Oscillator
    • Clock Source is internal Tcy which in our case is 0.25 us
    • No Gate operation
  • T1CONbits.TCKPS = 0b10 Prescalar is 1:64, (each 64 Clock Source tick will increment TMR1 register by 1
  • if TMR1 == PR1,T1IFwill be set. TMR1 counts till it is equal to the value in PR1

giving the information I have to make a 250 ms (250,000 us) time delay, I used to following equation:

  • t = Tcy*(PRE)*(PR1)
  • 250,000 = 0.25*64*(PR1)
  • PR1 = 250,000/(0.25*64)
  • PR1 = 15625

I thought that it is straight forward, can someone help me with my question.

Thank you in advance.

Best Answer

You are clocking the timer with SOSC, check your T1CON bits again.

TCS should be 0.