Maybe I'm missing something here but on a dsPIC33FJ16GS502, I designed Timer1 to toggle a pin at 200 Hz but when implemented, the frequency is actually 100 Hz. I have the following configurations:
XT (HS): 16 MHz
FCY: 8 MHz
Prescaler: 64
PR1: 8 MHz / (200 Hz * 64) = 625
Here's the code:
_FOSC( POSCMD_HS & OSCIOFNC_OFF );
_FOSCSEL( FNOSC_PRI & IESO_OFF );
_FWDT( FWDTEN_OFF );
int main(int argc, char** argv) {
OSCCONbits.COSC = 0b010; // HSXT no PLL
OSCCONbits.CLKLOCK = 1;
OSCCONbits.IOLOCK = 1;
CLKDIVbits.ROI = 0;
CLKDIVbits.DOZEN = 0;
// Set TMR1 Registers
T1CONbits.TON = 0; // Shut off timer for configuration
T1CONbits.TSIDL = 1;
T1CONbits.TGATE = 0;
T1CONbits.TCKPS = 0b10; // 1:64 Prescaler
T1CONbits.TCS = 0; // Use internal clock
TMR1= 0x0000;
PR1 = 625;
IPC0bits.T1IP = 0x01;
IFS0bits.T1IF = 0;
IEC0bits.T1IE = 1;
T1CONbits.TON = 1; // Turn on Timer
TRISBbits.TRISB8 = 0;
LATBbits.LATB8 = 1;
while(1);
}
void __attribute__((__interrupt__, no_auto_psv)) _T1Interrupt(void){
LATBbits.LATB8 = ~LATBbits.LATB8;
IFS0bits.T1IF = 0;
}
If PR1 was set to 312, then I would get the 200 Hz frequency but according to my calculations, PR1 set to 312 would result in a frequency of 400 Hz. I have no idea why I'm out by a factor of 2. I'm pretty sure I'm configuring the registers right.
Best Answer
Your code is right, you are actually toggling the pin at 200Hz... That means its frequency is 100Hz.
The period you are setting in the timer is the distance between a rising edge and a falling edge, and vice versa, so the wave period will be twice the timer period because the wave period is defined as the distance between two rising (or falling) edges.
Go with the value that works and you will be fine.