OpenVex  0.5.0
Macros | Functions
Low Level Timer Functions

Macros

#define TIMER0_READ8(v)   ((v) = (unsigned char)TMR0L)
 
#define TIMER0_READ16(v)   ((v) = TMR0L, (v) |= (unsigned short)TMR0H << 8)
 
#define TIMER0_ELAPSED_MS   ( timer0_read32() / TIMER0_TICKS_PER_MS )
 
#define TIMER0_PRESCALE   ( (T0CON & 0x08) ? 1 : 2 << (T0CON & 0x07) )
 
#define TIMER0_TICKS_PER_MS   ( 10000 / TIMER0_PRESCALE )
 
#define TIMER0_WRITE16(v)
 
#define TIMER0_WRITE8(v)   (TMR0L = (v))
 
#define TIMER0_SET_PRESCALE(mask)   (T0CON = (T0CON & 0xf0) | (mask))
 
#define TIMER0_CLEAR_INTERRUPT_FLAG()   { INTCONbits.T0IF = 0; }
 
#define TIMER0_START()   { T0CON |= 0X80; }
 
#define TIMER0_STOP()   { T0CON &= ~0x80; }
 
#define TIMER0_ENABLE_INTERRUPTS()
 
#define TIMER0_DISABLE_INTERRUPTS()   { INTCONbits.T0IE = 0; }
 
#define TIMER0_SET_WIDTH_16()   { T0CON &= ~0x40; }
 
#define TIMER0_SET_WIDTH_8()   { T0CON |= 0x40; }
 

Functions

unsigned long timer0_read32 (void)
 

Detailed Description

These functions and macros provide direct access to the PIC 18f8520 timers, each of which has a different set of capabilities.

Note: Timer0 is reserved for use by OpenVex for sonar and delay functions, etc.

Macro Definition Documentation

◆ TIMER0_CLEAR_INTERRUPT_FLAG

#define TIMER0_CLEAR_INTERRUPT_FLAG ( )    { INTCONbits.T0IF = 0; }

Clear the interrupt flag for Timer0. The flag is set when Timer0 overflows (whether or not interrupts are enabled).

◆ TIMER0_DISABLE_INTERRUPTS

#define TIMER0_DISABLE_INTERRUPTS ( )    { INTCONbits.T0IE = 0; }

Disable interrupts for Timer0. Note that the interrupt flag will continue to be set when Timer0 overflows. However, a branch to the interrupt vector will not occur.

◆ TIMER0_ELAPSED_MS

#define TIMER0_ELAPSED_MS   ( timer0_read32() / TIMER0_TICKS_PER_MS )

Return the number of milliseconds passed since the last timer 0 reset. See timer0_read32() for accuracy and period information.

◆ TIMER0_ENABLE_INTERRUPTS

#define TIMER0_ENABLE_INTERRUPTS ( )
Value:
{ \
INTCON2bits.T0IP = 0; \
INTCONbits.T0IE = 1; /* timer0 interrupts */ \
INTCONbits.PEIE = 1; /* Peripheral interrupts */ \
INTCONbits.GIE = 1; /* General interrupts */ \
}

Enable interrupts for Timer0. An interrupt will be signalled and a branch to the appropriate interrupt vector will occur when the timer overflows from 0xFF or 0xFFFF to 0, depending on whether in 8 or 16 bit mode.

◆ TIMER0_PRESCALE

#define TIMER0_PRESCALE   ( (T0CON & 0x08) ? 1 : 2 << (T0CON & 0x07) )

Reports the current timer 0 prescale factor. If prescaling is disabled, this value is 1. Otherwise, it is a power of 2 from 2 to 256, inclusive.

◆ TIMER0_READ16

#define TIMER0_READ16 (   v)    ((v) = TMR0L, (v) |= (unsigned short)TMR0H << 8)

Read both bytes of the Timer0 register, both returning the value and assigning it to v, which must be a 16 bit integer variable.

Note that TMR0L is the low byte of the Timer0 register, but TMR0H is NOT the high byte. Reading TMR0L causes the processor to place a snapshot of the actual Timer0 high byte in TMR0H. This ensures that both bytes are sampled during the same clock cycle, and the 16 bit value taken from TMR0L and TMR0H is coherent. It also means that TMR0L must be read first.

Note that the 16 bit timer value cannot be read using a simple expression like (TMR0L + (unsigned short)TMR0H << 8), since the C standard does not specify which operand of '+' is evaluated first. The ',' operator, on the other hand, guarantees that operands are evaluated left to right. It also guarantees that the value of the overall expression is the value of the last operand. By assigning the 16-bit value to v in the last operand of the ',' operator, this macro is able to return the full 16 bit timer value.

The value returned will be the timer value during execution of the first instruction of TIMER0_READ16(). The macro itself will consume several timer cycles reading TMR0L, TMR0H, and performing the | operation.

◆ TIMER0_READ8

#define TIMER0_READ8 (   v)    ((v) = (unsigned char)TMR0L)

Read the low byte of timer 0, placing the value in v and returning it. The variable v should be an unsigned char for best results.

◆ TIMER0_SET_PRESCALE

#define TIMER0_SET_PRESCALE (   mask)    (T0CON = (T0CON & 0xf0) | (mask))

Select a prescale value for Timer0. The prescaler slows the timer increments by a given factor. Without prescaling, the timer is incremented at Fosc/4, or 10MHz. ( Every 1/10 microsecond. )

Prescale Period
TIMER0_PRESCALE_MASK_2 0.2 us
TIMER0_PRESCALE_MASK_4 0.4 us
TIMER0_PRESCALE_MASK_8 0.8 us
TIMER0_PRESCALE_MASK_16 1.6 us * Maximum for precise ms timing (625 ticks = 1ms)
TIMER0_PRESCALE_MASK_32 3.2 us
TIMER0_PRESCALE_MASK_64 6.4 us
TIMER0_PRESCALE_MASK_128 12.8 us
TIMER0_PRESCALE_MASK_256 25.6 us

◆ TIMER0_SET_WIDTH_16

#define TIMER0_SET_WIDTH_16 ( )    { T0CON &= ~0x40; }

Set Timer0 to operate in 16 bit mode.

◆ TIMER0_SET_WIDTH_8

#define TIMER0_SET_WIDTH_8 ( )    { T0CON |= 0x40; }

Set Timer0 to operate in 16 bit mode.

◆ TIMER0_START

#define TIMER0_START ( )    { T0CON |= 0X80; }

Start Timer0. ( Allow Timer0 registers to increment. )

◆ TIMER0_STOP

#define TIMER0_STOP ( )    { T0CON &= ~0x80; }

Stop Timer0. ( Disable incrementing of Timer0 registers. )

◆ TIMER0_TICKS_PER_MS

#define TIMER0_TICKS_PER_MS   ( 10000 / TIMER0_PRESCALE )

Reports the number of timer 0 ticks per millisecond, which is 10,000 / the current prescale factor. ( The raw internal timer clock is Fosc/4 = 10 MHz. )

Note that for prescale factors > 16, integer truncation occurs, since 10,000 is not divisible by powers of 2 greater than 16. Hence, the value returned by this macro should not be used in a cumulative fashion if prescaling > 16 is in effect.

◆ TIMER0_WRITE16

#define TIMER0_WRITE16 (   v)
Value:
{ \
TMR0H = ((unsigned short)(v) >> 8) & 0xff; \
TMR0L = ((unsigned short)(v)) & 0xff; \
}

Write the value of Timer0. Both 8 and 16 bit writes can be performed in either 8 or 16 bit mode. ( The mode only determines whether the timer overflows and writes T0IF at 0xFF or 0xFFFF. )

◆ TIMER0_WRITE8

#define TIMER0_WRITE8 (   v)    (TMR0L = (v))

Write the value of Timer0. Both 8 and 16 bit writes can be performed in either 8 or 16 bit mode. ( The mode only determines whether the timer overflows and writes T0IF at 0xFF or 0xFFFF. )

Function Documentation

◆ timer0_read32()

unsigned long timer0_read32 ( void  )

Read the 32-bit value of Timer0, which includes a 16 bit sample from TMR0L and TMR0H, concatenated with the Timer0_overflow counter. ( When Timer0 rolls over from 0xffff to 0x0000, it generates an interrupt. The ISR increments the 16-bit Timer0_overflows, in essence maintaining a 32-bit Timer0 value. )

Before using this function, you must enable Timer0 interrupts with timer0_interrupts_on() and enable the timer with timer0_start(). To make sense of the value returned requires knowing the prescale value, which is set with timer0_set_prescale() and read back with TIMER0_GET_PRESCALE or TIMER0_TICKS_PER_MS.

The value returned contains a lag of a few microseconds due to function calling and computational overhead. In addition, if Timer0 is sampled at the moment it rolls over from 0xffff to 0x0000, there will be an additional lag of roughly 1 microsecond due to resampling to get a coherent value.