PIC16F84A blink without delay (Timer0 interrupt)
The microcontroller PIC16F84A has 1 timer which is Timer0, this timer has a resolution of 8 bits and an interrupt-on-overflow from FFh to 00h. This topic shows how to use Timer0 interrupt to blink an LED.
This interrupt is generated when the TMR0 register overflows from FFh to 00h.
To enable the Timer0 interrupt GIE bit (INTCON<7>) must be 1 which can be done using the following CCS C command:
enable_interrupts(GLOBAL) ;
Also T0IE bit (INTCON<7>) must be 1 which can be done using the following command:
enable_interrupts(INT_TIMER0) ;
Bit T0IF (INTCON<2>) must be cleared in software by the Timer0 module Interrupt Service Routine before re-enabling this interrupt and this is done using the following command:
clear_interrupt(INT_TIMER0) ;
We can set the timer0 preload value (initial value) using the following command:
set_timer0(preload_value) ;
where preload_value is an unsigned 8-bit number.
The clock source can be internal or external through RA4/T0CKI pin.
Prescaler rate of Timer0 can be: 2, 4, 8, 16, 32, 64, 128 or 256. The clock source and prescaler can be set using the following CCS command:
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_256) ;
To compute the timer0 frequency use the following equation:
Timer0_freq = MCU_freq / {4 * Prescaler * (256 – TMR0)}
where TMR0 is Timer0 preload value.
and: peroid = 1/Timer0_freq which is time to interrupt.
PIC16F84A Timer0 interrupt example circuit:
This is a simple example which uses Timer0 interrupt to make an LED connected to RA0 blinking at a frequency of 1Hz.
PIC16F84A Timer0 interrupt example CCS PIC C code:
The timer is used to interrupt every 50ms and to make the LED ON for 500ms and OFF for 500ms, the interrupt must be interrupted 10 times, that’s why a variable i is used.
HS oscillator is used with frequency of 4MHz.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | // PIC16F84A timer0 interrupt example // Timer0 is interrupted every 49.92ms (approximately 50ms) // Pin RA0 toggles its status every 10 * 49.92ms (approximately 500ms) // http://simple-circuit.com/ #include <16F84A.h> #fuses HS,NOWDT,PUT,NOPROTECT #use delay(crystal=4000000) byte i ; #INT_TIMER0 void timer0_isr(void) { clear_interrupt(INT_TIMER0); // Clear timer0 interrupt flag bit set_timer0(61); i++; if(i > 9) { i = 0; output_toggle(PIN_A0); } } void main() { // Setup timer0 with internal clock and 256 prescaler setup_timer_0(RTCC_INTERNAL|RTCC_DIV_256); set_timer0(61); // Timer0 preload value clear_interrupt(INT_TIMER0); // Clear timer0 interrupt flag bit enable_interrupts(INT_TIMER0); // Enable timer0 interrupt enable_interrupts(GLOBAL); // Enable all unmasked interrupt output_low(PIN_A0); while(TRUE) ; // Endless loop } |
Discover more from Simple Circuit
Subscribe to get the latest posts sent to your email.