NOTES :: Timer 0 (TMR0) Equation
Posted by Circuit Negma on April 13, 2010
Create By: Hussein Nosair
We need to convert the desired delay time from seconds to HEX:
D = ( Td * Fosc ) / ( 4 * PS ) ………………………………….. eq. 1
Td = Delay time in sec
Fosc = Oscillator Frequency (Instruction cycle or Instruction time)
PS = Prescaler assignment value
D = Delay time in HEX (software level)
Load D into TMR0 register:
(TMR0 + 2) = (2^16) – 1 – D
Note that I have added a 2 to TMR0 value. This is a small fix to TMR0 register behavior. When TMR0 register is written to it, the first increment of TMR0 will happen after 2 instruction cycles.
TMR0 = 65535 – D – 2
TMR0 = 65533 – D
TMR0H = upper 2 bytes of TMR0
TMR0L = Lower 2 bytes of TMR0
Ex:
Td = 1sec
Fosc = 40MHz
PS = 256D = (1sec x 40MHz) / (4×256)
D = 39062TMR0 = 65533 – 39062
TMR0 = 26471
TMR0 = 0×6767TMR0H = 0×67
TMR0L = 0×67
/**********************************************************************
* Create By: Hussein Nosair
* Date : 09/10/2008
* Processor: PIC18F4520
* Compiler : MPLAB C18 V3.21
* Language : C
* Description:
* This code domenstrate the use of TMR0 as counter
* and as a timer.
***********************************************************************/
#include <p18cxxx.h>
#define ClrWdt() asm(“CLRWDT”);
unsigned char dwInternalTicks; // Used as a counter
#pragma interruptlow LowISR
void LowISR(void)
{
if(INTCONbits.TMR0IF)
{
// Increment internal high tick counter
if (dwInternalTicks) // Check if counter is 0
{
dwInternalTicks–; // Decrement counter by 1
}
// Reset Interrupt flag
INTCONbits.TMR0IF = 0;
// Note the order of TMR0H and TMR0L
TMR0H = 0×67; //1.67sec
TMR0L = 0×67;
}
}
#pragma code lowVector=0×18
void LowVector(void){_asm goto LowISR _endasm}
#pragma code // Return to default code section
void init(void)
{
// Set up the timer interrupt
INTCON2bits.TMR0IP = 0; // Low priority
INTCONbits.TMR0IF = 0;
INTCONbits.TMR0IE = 1; // Enable interrupt
// Timer0 on, 16-bit, internal timer, 1:256 prescalar
T0CON = 0×87;
// Digital Pins
ADCON0 = 0×00;
ADCON1 = 0x0F;
CMCON = 0xCF;
//Enable Interrupts
RCONbits.IPEN = 1; // Enable interrupt priorities
INTCONbits.GIEH = 1;
INTCONbits.GIEL = 1;
}
void main(void)
{
init(); // Initialize PIC hardware
while(1) // Enter Infinit loop to prevent the PIC from reseting
{
//…. DO STUFF HERE
// NOTE order of TMR0H and TMR0L
TMR0H = 0xF0;
TMR0L = 0×00;
T0IF = 0
while(!T0IF);
//… DO STUFF HERE
dwInternalTicks = 12;
while(!dwInternalTicks)
{
//…… DO STUFF HERE
}
//…. DO STUFF HERE
//ClrWdt(); <————- Uncomment if WDT is turned on
}
}
EEWeb Electronics Forum