Tienes razón, se puede desabilitar el prescaler y es más preciso.
El timer1 lo quiero utilizar para contar pulsos de entrada (la temporización con el timer0 servirá después para hacer un frecuencímetro)
El timer0 quiero utilizarle en modo 8bit para que el programa valga para un 16F628 o un 16F88.
Por ahora programo un reloj para poder compararlo con otro reloj digital y medir el error del cuarzo. Luego compenso el error por software.
Al final he conseguido un error muy bueno (menos de 10ppm):
/****************************************************************************
SECOND COUNTER
****************************************************************************/
#include <p18cxxx.h>
#include <stdio.h>
#include <string.h>
/****************************************************************************
GLOBAL VARIABLES AND DEFINITIONS
****************************************************************************/
#define FOSC 20000000
#define BAUD 57600
#define FOSC_ERROR_PPM 70
#define FOSC_REAL (FOSC + FOSC_ERROR_PPM*(FOSC/1000000))
#define TMR0_COUNT (FOSC_REAL/(4*256)+1) // Number of carrys per second
#define TMR0_OFFSET (TMR0_COUNT*256-(FOSC_REAL/4)) // TMR0L preset every second
unsigned int sys_clk, seconds, old_seconds;
/****************************************************************************
INTERRUPT SERVICE ROUTINE
****************************************************************************/
// Rutinas de Interrupcion.-
#pragma interrupt isr_main
void isr_main(void) {
if (INTCONbits.TMR0IF==1) { // if TIMER0 overflow interrupt
INTCONbits.TMR0IF = 0; // Clear Timer0 interrupt flag
sys_clk--;
if (sys_clk == 0) {
TMR0L += TMR0_OFFSET + 3;
sys_clk = TMR0_COUNT;
seconds++;
}
}
}
#pragma code high_vector=0x08
void isr_high(void) {
_asm GOTO isr_main _endasm
}
/****************************************************************************
MAIN PROGRAM
****************************************************************************/
#pragma code
/*
MAIN ROUTINE
*/
void main(void) {
// Configure Timer0
sys_clk = 1;
seconds = 0;
T0CON = 0b11001000; // Timer0 ON, 8bit count, No prescaler
INTCON = 0b11100000; // Global Interrupt, Peripheral Interrupt, TMR0 interrupt
// Configure UART
BAUDCONbits.BRG16 = 0; // BRG16: 16-Bit Baud Rate Register Enable bit
SPBRGH = 0;
SPBRG = (FOSC/(16*BAUD))-1; // Configure UART speed
TXSTA = 0b00100110;
RCSTA = 0b10010000;
TRISCbits.TRISC6 = 0; // Enable TX output
PIE1bits.TXIE = 0; // Disable RS232 interrupts
// Main loop
old_seconds = -1;
while(1) {
if (seconds != old_seconds) {
old_seconds = seconds;
fprintf(_H_USART, "Seconds=%u\r\n", seconds);
}
if (seconds == 60000)
seconds = 0;
}
}
Saludos!