1
\$\begingroup\$

I am doing a program where I am toggling an LED at a PIC24F Development Board an Explorer 16/32 development board with a PIC24FJ1024GB610 microcontroller attached to it.

Explorer 16/32 got an LED (D3) connected to pin P17, which corresponds to PORTA RA0

The program consists of configuring the clock signal (oscillator source), setting up the 16-bit Timer 1, and initializing the digital output (TRISAbits.TRISA0 = 0)


CLOCK

  • The clock signal is sourced from OSCFDIV #pragma config FNOSC = OSCFDIV
  • the Prescaler block got its oscillator source from the FRC (Fast Internal RC oscillator) CLKDIVbits.RCDIV = FRC. The FRC got a frequency of 8MHz
  • Set the Prescaler to 1/4 OSCDIV = 4where Foscdiv = 2MHz
  • After the Fosc is divided by 2 by the Postscalar, we shall have Fcy = 1MHz, or Tcy = 1us

The diagram below illustrates how the oscillator was chosen.

enter image description here


TIMER

Timer 1 is a 16 bit Timer.

I have configured the timer's clock signal to be sourced internally (Tcy = 1us).

t = count * Tcy, if t = 50 ms = 50000 us, Tcy = 1 us, then count = 50000

enter image description here

By the logic of the code, when TMR1 = 50000 (50 ms), T1IF will be set then T1IF will be cleared by SW, and LATAbits.LATA0 (LED0) will be toggled, giving us a square wave with Time Period = 100ms.


This is the code of my application

#pragma config FWDTEN = OFF//disable WDT timer
#pragma config ICS = PGD2//allow debugging 

#pragma config FNOSC = OSCFDIV//COSC = OSCFDIV


#include "xc.h"


/*
 I would like to make a pin toggle
 * initialize the clock

 * 
 * fcy = 1MHz, Tcy = 1us   
 * RA0 will toggle every 50 ms
 * hence we get a square pulse of T = 100 ms

 */

#define TMR1_IF IFS0bits.T1IF
#define LED0    LATAbits.LATA0

#define FIFTY_MS 50000
#define FRC (0b000)

void digital_setup (void);
void timer_setup (void);
void clock_setup (void);

int main(void) 
{
    clock_setup ();
    digital_setup ();
    timer_setup ();    


    while(1)
    {
       if(TMR1_IF == 1)//if Timer 1 Interrupt Flag is set
       {
           TMR1_IF = 0;//clear IF
           LED0 = ~LED0;//toggle PORTA RA0 (P17)
       }

    }

    return 0;
}

void digital_setup (void)
{
    //output RA0
    TRISAbits.TRISA0 = 0;//digital
}

void clock_setup (void)
{
    CLKDIVbits.RCDIV = FRC;
    OSCDIV = 4;
}

void timer_setup (void)
{
    PR1 = FIFTY_MS;

    T1CONbits.TCS = 0;//cs internal
    T1CONbits.TGATE = 0;//gate don't accumulate

    T1CONbits.TON = 1;//start timer
}

However, when I compiled and programmed the code into my development board, I got a square wave with twice the timer period (200 ms)

enter image description here

Not sure if this is related, but I tried debugging it, and when I change the value of TMR1 to 50000, the T1IF bit doesn't get set.

Can someone tell me why I am getting a square wave with twice the period. Any help would be appreciated

\$\endgroup\$
1
  • 1
    \$\begingroup\$ Setting OSCDIV to 4 does not give you a /4 - according to to page 126 of the data it gives you /8. \$\endgroup\$ – brhans Apr 12 '20 at 16:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.