#include typedef unsigned char uint8_t; __sfr __at(0x70) UART_TX; __sfr __at(0x72) UART_STATUS; /* * OPTION_REG, T0IF, T0IE, GIE are all provided by pic16f84a.h. * OPTION_REG 0x07: T0CS=0 (Fosc/4), PSA=0, PS=111 (1:256) * At 50 MHz: overflow every 256*256 / (50M/4) = 5.24 ms → ~191 ovf/sec */ #define OVF_PER_SEC 191 static volatile uint8_t ovf_count = 0; void isr(void) __interrupt(0) { if (INTCON & 0x04) { /* T0IF = bit 2 */ ovf_count++; INTCON &= ~(uint8_t)0x04; } } static void uart_send(uint8_t b) { while (UART_STATUS & 0x01); UART_TX = b; } static void uart_puts(const char *s) { while (*s) uart_send((uint8_t)*s++); } static void print_uint8(uint8_t v) { uint8_t started = 0; if (v >= 200) { uart_send('2'); v -= 200; started = 1; } else if (v >= 100) { uart_send('1'); v -= 100; started = 1; } { uint8_t t = '0'; while (v >= 10) { v -= 10; t++; } if (started || t != '0') uart_send(t); } uart_send(v + '0'); } void main(void) { uint8_t seconds = 0; /* T0CS=0 (Fosc/4), PSA=0, PS=111 (1:256 prescaler) */ OPTION_REG = 0x07; TMR0 = 0; INTCON = 0xa0; /* T0IE | GIE */ uart_puts("\x1B[2J\x1B[H"); uart_puts("Timer0 test\r\n"); uart_puts("-----------\r\n"); while (1) { ovf_count = 0; while (ovf_count < OVF_PER_SEC); uart_puts("t = "); print_uint8(seconds); uart_puts(" s\r\n"); PORTA ^= 0x01; seconds++; } }