nerdegutta.no
PIC16F690 - Day 6: Precision Timing with Timer1
26.11.25
Embedded
#define _XTAL_FREQ 4000000
#include < xc.h >
#include < stdint.h >
// CONFIG
#pragma config FOSC = INTRCIO
#pragma config WDTE = OFF
#pragma config PWRTE = OFF
#pragma config MCLRE = OFF
#pragma config BOREN = OFF
#pragma config CP = OFF
#pragma config CPD = OFF
void timer1_init(void) {
T1CON = 0b00110001; // Timer1 ON, 1:8 prescale
TMR1 = 0; // Clear timer
}
void main(void) {
TRISB0 = 0; // RB0 output
ANSEL = 0;
ANSELH = 0;
PORTB = 0;
timer1_init();
uint8_t overflow_count = 0;
while (1) {
if (PIR1bits.TMR1IF) { // Timer1 overflow flag
PIR1bits.TMR1IF = 0;
overflow_count++;
if (overflow_count >= 2) { // ~1 sec
RB0 = !RB0;
overflow_count = 0;
}
}
}
}
Code 2: Using Timer1 with Interrupt
#define _XTAL_FREQ 4000000
#include < xc.h >
#include < stdint.h >
// CONFIG
#pragma config FOSC = INTRCIO
#pragma config WDTE = OFF
#pragma config PWRTE = OFF
#pragma config MCLRE = OFF
#pragma config BOREN = OFF
#pragma config CP = OFF
#pragma config CPD = OFF
volatile uint8_t t1_overflows = 0;
void __interrupt() isr(void) {
if (PIR1bits.TMR1IF) {
PIR1bits.TMR1IF = 0;
t1_overflows++;
if (t1_overflows >= 2) {
RB0 = !RB0;
t1_overflows = 0;
}
}
}
void main(void) {
TRISB0 = 0;
ANSEL = 0;
ANSELH = 0;
PORTB = 0;
// Timer1 setup
T1CON = 0b00110001; // TMR1 ON, 1:8 prescaler
TMR1 = 0;
TMR1IE = 1; // Enable Timer1 interrupt
PEIE = 1; // Peripheral interrupt
GIE = 1; // Global interrupt
while (1) {
// Main loop idle – ISR handles timing
}
}