1. When writing to Timer 0 registers you MUST write to TMR0H first then TMR0L
2. When reading from the registers you must read TMR0L first then TMR0H
3. Set the timer on by T0CON = 0b10000xxx; Where xxx is the prescale value, between 1:2 and 1:256
Code: Select all
////////////////////////////////////////////////////////////////////////////////
// Project: Timer 0 in 16 bit mode //
// File: Main.c //
// Function: Use interrupt as a delay timer //
// MCU: P18F8722 with 2 RS232 and 2 SPI/I2C peripheral //
// Board: BIGPIC5 //
// Oscillator: 10MHz Xtal X 4 = 40MHz. Max is 48MHz //
// Power 5.5V //
// Compiler: mikroC PRO version 7.6.0 //
// Programmer: Onboard //
// Author: WVL //
// Date: May 2023 //
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
// WARNING //
// UART on RC6/Tx1 RC7/Rx1 and RG1/Tx2 RG2/Rx2 //
// SCl1/RC3 SDA1/RC4 and SCL2/RD6 SDA2/RD5 - use I2C1 to avoid RD5 clash //
// GLCD pins on ports J0,1,2,3,4,5 and D0 to D7 inclusive //
// Mikro LCD adaptor on port H2,3,4,5,6,7 //
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
// Global variables //
bit TIMER0_FLAG; // set in Timer 0 interrupt, cleared in delay function //
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
// Timer0 in 6 bit mode. One Tick = 4/(40MHz Xtal) = 0.1uS //
// Prescale 1:2 0b000 Tick = 2*0.1 = 0.2[uS] //
// Prescale 1:4 0b001 Tick = 4*0.1 = 0.4[uS] //
// Prescale 1:8 0b010 Tick = 6*0.1 = 0.8[uS] //
// Prescale 1:16 0b011 Tick = 16*0.1 = 1.6[uS] //
// Prescale 1:32 0b100 Tick = 32*0.1 = 3.2[uS] //
// Prescale 1:64 0b101 Tick = 64*0.1 = 6.4[uS] //
// Prescale 1:128 0b110 Tick = 128*0.1 = 12.8[uS] //
// Prescale 1:256 0b111 Tick = 256*0.1 = 25.6[uS] //
// Turn Timer 0 on, 16 bit mode and prescale 1:256 so each tick is 25.6[uS] //
// Minimum delay = 25.6[uS] Max delay = 65535*25.6 = 1.677[S] //
void Timer0_init(){ //
T0CON = 0b10000111; //
TMR0H = 0; // MUST write TMR0H first in 16 bit mode //
TMR0L = 0; // MUST write TMR0L second in 16 bit mode //
TMR0IF_bit = 0; // clear interrupt flag //
TMR0IE_bit = 1; // enable Timer 0 interrupt //
} //
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
// Timer 0. 16 bit mode interrupts when counter rolls from 0xFFFF to 0x0000 //
// Delay before interrupt = (0xFFFF - (TMR0H<<8 + TMR0L))*25.6[uS] //
void Timer0_Interrupt() iv 0x0008 ics ICS_AUTO { //
if(TMR0IF_bit){ //
TMR0IF_bit = 0; // flag off //
TMR0IE_bit = 0; // disable Timer 0 interrupt //
TIMER0_FLAG = 1; // flag on, cleared in Main function //
} //
} //
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
// Function. Delay using Timer 0 //
// Timer 0. Tick = 25.6[uS]*Prescale value //
char V_us_delay(unsigned int ticks){ //
unsigned int count = 0xFFFF - ticks; //
TMR0H = (count&0xFF00)>>8; // MUST write TMR0H first in 16 bit mode //
TMR0L = count & 0x00FF; // MUST write TMR0L second in 16 bit mode //
T0CON = 0b10000111; // timer 0 on //
TIMER0_FLAG = 0; // clear the flag, set in interrupt //
TMR0IP_bit = 1; // make Timer 0 IP high //
TMR0IF_bit = 0; // clear interrupt flag //
TMR0IE_bit = 1; // enable Timer 0 interrupt //
} //
////////////////////////////////////////////////////////////////////////////////
void main() {
unsigned int t = 10; // ADC result
unsigned int x = 0; // reusable
// Init MCU
INTCON2 = 0; // PORTB pullups enabled
ADC_Init(); // 10 bit ADC 0-1023 or 0-3FF
// Init ports
TRISA0_bit = 1; // input for ADC
TRISG0_bit = 0; // for LEDE flash
LATG0_bit = 0;
delay_ms(100);
// Set interrupts
IPEN_bit = 1; // enable priority interrupt levels low and high
GIEH_bit = 1; // enable all high priority interrupts
GIEL_bit = 1; // enable all low priority interrupts
while(1){
t = 30*ADC_Read(1); // (0-1023)*30=30,697. Full delay 65535 = 1.575 Seconds
V_us_delay(t);
while(TIMER0_FLAG==0);
LATG0_bit = ~LATG0_bit;
}
}
Good uck. Regards Bill Legge in Australia