The 100 āsecond ticksā deals with timers and interrupts. If you look at Peteās InterruptHandlerLow(); (Low Priority interrupt handler) you will see that that he has
// Timer 2 interrupt.
if (PIR1bits.TMR2IF) // expires every 10Ms at 10 Mhz
{
PIR1bits.TMR2IF = 0;
tmr2_expire_cnt++;
if (tmr2_expire_cnt >= second_ticks)
{
// Do this stuff every second.
tmr2_expire_cnt = 0;
// Trigger a blink of the heartbeat LED.
heartbeat = TRUE;
}
}
Every 10ms it checks to see if 100 āticksā passed by (AKA the timer is going at 100Hz). If it does, then the heartbeat will become true. This variable is used in the main while loop to trigger an LED and do some i2c related things.
Why is this? Lets look at the 10MHz settings:
// Settings for 10 Mhz oscillator:
OSCCON = 0b11000000; // external xtal OSC, 10 Mhz
Osc_Freq_Mhz = 10;
second_ticks = 100;
We know that the PIC is operating at 10MHz. So the proper OSCCON is set, and OSC_Freq_Mhz (used in his delay library) is set to 10. And second_ticks is set to 100 as needed. But why? The answer lies in the Timer settings. Timer2 to be exact!
If we scroll up a bit, we will find this nice blob of code:
// Setup Timer 2.
T2CON = 0b01001010; // 10 post scale, timer off, 16 prescale
PR2 = 156; // create 10ms clock at 10 Mhz
TMR2 = 0;
PIR1bits.TMR2IF = 0;
//TMR2IP = 1; // high priority
PIE1bits.TMR2IE = 1; // enable interrupt
tmr2_expire_cnt = 0;
T2CONbits.TMR2ON = 1;
Whats it all mean? I wonāt get into bit details but I will explain the reasoning and behind it.
Remember FOSC/4? Thats your new best friend. FOSC is written in units of Hz, so at 10MHz it will be equal to 10,000,000Hz. There are 4 operations per Hz so we divide by 4.
We then take a look at the first line of the setup:
T2CON = 0b01001010; // 10 post scale, timer off, 16 prescale
Thanks to the comments, it saves me from some bit picking. Check the 4620 manual under āREGISTER 13-1: T2CON: TIMER2 CONTROL REGISTERā for more info.
Basically there are two important numbers here. A 10 post scale, and a 16 prescale.
Prescale is applied before so we first divide by 16 and get:
WAIT! We need something else. Timer2 is an 8-bit timer. So there are 256 counts. It starts at 0, by default, and counts upto 255 and then āoverflowsā or āwraps aroundā back to 0.
(I am rusty on this part, so forgive is my wording is wrong or if my explanation is wrong)
PR2 = 156; // create 10ms clock at 10 Mhz
We have a register called PR2. PR2 is the āstartingā position for the Timer2. Since we are starting at 156 we only have 100 counts to go (256 - 156 = 100). We need to multiply the prescaler by the number of counts the timer will make.
Then we apply the post-scaler of 10:
So at 10MHz with a prescaler of 16, post scaler of 10, and PR2 of 156, there will be 100 interrupts per second.
Fairly simple!
So what is it for the other frequencies?
20MHz: ((20000000/4)/(15616))/10 = 200
40MHz: ((40000000/4)/(15616))/10 = 400.6 = ~401
48MHz: ((48000000/4)/(156*16))/10 = 480.7 = ~481
Or simply: (FOSC / 4) / (COUNTS * PRESCALER) / POSTSCALER
So basically, its about 10x of the MHz with these settings!
I hope I got it right >_< I havenāt done this stuff in a while. Nick exaplained it to me a lonnnng time ago, back in like feb/march! I didnāt understand it very well but I read for a bit and seem to understand it better. Sorry if my wording is wrong.
-robodude666