Circuit Negma

C++, C, VB.NET, PCB, Electronics, Circuit Design

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 = 256

D = (1sec x 40MHz) / (4×256)
D = 39062

TMR0 = 65533 – 39062
TMR0 = 26471
TMR0 = 0x6767

TMR0H = 0x67
TMR0L = 0x67

 

/**********************************************************************
* 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 = 0x67;            //1.67sec
        TMR0L = 0x67;
    }
}

#pragma code lowVector=0x18
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 = 0x87;

    // Digital Pins
    ADCON0 = 0x00;
    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 = 0x00;
        T0IF = 0
        while(!T0IF);

        //… DO STUFF HERE

        dwInternalTicks = 12;
        while(!dwInternalTicks)
        {
            //…… DO STUFF HERE
        }

        //…. DO STUFF HERE

        //ClrWdt();  <————- Uncomment if WDT is turned on
    }
}

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

 
%d bloggers like this: