Timers Interrupt:
Now lets see the interrupt of timers. As we know Timer0 will generate an interrupt when the TMR0 register overflows from FFh to 00h. The T0IF interrupt flag bit of the INTCON register is set every time the TMR0 register overflows, regardless of whether or not the Timer0 interrupt is enabled. The T0IF bit must be cleared in software. The Timer0 interrupt enable is the T0IE bit of the INTCON register. However we will use TMR0IF bit for interrupt programming.
The Timer1 register pair (TMR1H:TMR1L) increments to FFFFh and rolls over to 0000h. When Timer1 rolls over, the Timer1 interrupt flag bit of the PIR1 register is set. To enable the interrupt on rollover, you must set these bits:
• Timer1 interrupt enable bit of the PIE1 register
• PEIE bit of the INTCON register
• GIE bit of the INTCON register
The interrupt is cleared by clearing the TMR1IF bit in the Interrupt Service Routine.
• Timer1 interrupt enable bit of the PIE1 register
• PEIE bit of the INTCON register
• GIE bit of the INTCON register
The interrupt is cleared by clearing the TMR1IF bit in the Interrupt Service Routine.
For interrupt programming we have to create ISR (interrupt service routine); so that when an interrupt will occur ISR will take care of it. So, to use timers interrupt; first we have to enable the global interrupt by setting the GIE bit of intcon register, then the interrupts of the respective timer.
Code:
unsigned cnt, cnt1, cnt2;
void interrupt() {
if (TMR2IF_bit) {
cnt2++; // increment counter
TMR2IF_bit = 0; // clear TMR2IF
TMR2 = 0;
if (cnt2 >= 122) {
PORTc = ~PORTc; // Toggle PORTc LEDs
cnt2 = 0; // Reset cnt
}
}
if (TMR0IF_bit) {
cnt++; // increment counter
TMR0IF_bit = 0; // clear TMR0IF
TMR0 = 0;
if (cnt >= 122) { //1 sec delay
PORTd = ~PORTd; // Toggle PORTd LEDs
cnt = 0; // Reset cnt
}
}
if(tmr1if_bit){
tmr1if_bit=0;
cnt1++;
tmr1h=128;
tmr1l=0;
if(cnt1>=36){
porta=!porta;
cnt1=0;
}
}
}
void main() {
OPTION_REG = 0x84; // Assign prescaler to TMR0 32
////////////// commect for 877///////////////
if (TMR2IF_bit) {
cnt2++; // increment counter
TMR2IF_bit = 0; // clear TMR2IF
TMR2 = 0;
if (cnt2 >= 122) {
PORTc = ~PORTc; // Toggle PORTc LEDs
cnt2 = 0; // Reset cnt
}
}
if (TMR0IF_bit) {
cnt++; // increment counter
TMR0IF_bit = 0; // clear TMR0IF
TMR0 = 0;
if (cnt >= 122) { //1 sec delay
PORTd = ~PORTd; // Toggle PORTd LEDs
cnt = 0; // Reset cnt
}
}
if(tmr1if_bit){
tmr1if_bit=0;
cnt1++;
tmr1h=128;
tmr1l=0;
if(cnt1>=36){
porta=!porta;
cnt1=0;
}
}
}
void main() {
OPTION_REG = 0x84; // Assign prescaler to TMR0 32
////////////// commect for 877///////////////
ansel=0;
anselh=0;
c1on_bit=0;
c2on_bit=0;
anselh=0;
c1on_bit=0;
c2on_bit=0;
///////////////////////////////////////
TRISc = 0; // PORTc is output
PORTc = 0xFF; // Initialize PORTc
TRISd = 0; // PORTd is output
PORTd = 0xFF; // Initialize PORTd
TRISa = 0; // PORTa is output
PORTa = 1; // Initialize PORTa
TMR0 = 0; // Timer0 initial value
INTCON = 0xA0; // Enable TMRO interrupt
cnt = 0; // Initialize cnt
t1con=1;
tmr1if_bit=0;
tmr1h=128;
tmr1l=0;
tmr1ie_bit=1;
cnt1=0;
intcon=192;
cnt2 = 0; // initialize cnt
PORTc = 0xFF; // Initialize PORTc
TRISc = 0; // PORTc is output
PORTc = 0xFF; // Initialize PORTc
TRISd = 0; // PORTd is output
PORTd = 0xFF; // Initialize PORTd
TRISa = 0; // PORTa is output
PORTa = 1; // Initialize PORTa
TMR0 = 0; // Timer0 initial value
INTCON = 0xA0; // Enable TMRO interrupt
cnt = 0; // Initialize cnt
t1con=1;
tmr1if_bit=0;
tmr1h=128;
tmr1l=0;
tmr1ie_bit=1;
cnt1=0;
intcon=192;
cnt2 = 0; // initialize cnt
PORTc = 0xFF; // Initialize PORTc
TRISc = 0; // PORTc is output
T2CON = 7; // Timer2 settings
TMR2 = 0; // Initialize Timer2 register
TMR2IE_bit = 1; // enable interupt
INTCON = 0xC0; // Set GIE, PEIE
}
T2CON = 7; // Timer2 settings
TMR2 = 0; // Initialize Timer2 register
TMR2IE_bit = 1; // enable interupt
INTCON = 0xC0; // Set GIE, PEIE
}
This code toggle the bits of port a, b and d when the interrupts of timer 1, 0, and 2 respectively. The time duration is about 0.5 sec, 1 sec, and 2 sec.
void interrupt() is the isr taking care of interrupts; handling interrupts and take decision according to them.
Schematic:
Hello sir.
ReplyDeletei need code read ADC to show 7 segment 3-4 display with 16f877a
mikroC programming sir.(DC voltage meter with 7 segments)