Using timers TMR0, TMR1 and TMR2. Using interrupts, declaring new function...
If you have read the previous example, you probably have noticed a disadvantage of providing delays using loops. In all those cases, the microcontroller is ‘captive’ and does nothing. It simply waits for some time to pass. Such waste of time is an unacceptable luxury and some other method should be applied therefore. Do you remember the story about timers? Interrupts? This example makes links between them in a practical way. The schematic is still the same as well as the challenge. It is necessary to provide a delay long enough to notice changes on a port. Timer TMR0 with assigned prescaler is used for this purpose. An interrupt is generated on every timer register overflow and every interrupt routine automatically increments the cnt variable by 1. When it’s value reaches 400, the port B is incremented by 1. The whole procedure is performed ‘behind the scenes’, which enables the microcontroller to do something else./*Header******************************************************/ unsigned cnt; // Define variable cnt void interrupt() { cnt++; // Interrupt causes cnt to be incremented by 1 TMR0 = 96; // Timer TMR0 is returned its initial value INTCON = 0x20; // Bit T0IE is set, bit T0IF is cleared } void main() { OPTION_REG = 0x84; // Prescaler is assigned to timer TMR0 ANSEL = 0; // All I/O pins are configured as digital ANSELH = 0; TRISB = 0; // All port B pins are configured as outputs PORTB = 0x0; // Reset port B TMR0 = 96; // Timer T0 counts from 96 to 255 INTCON = 0xA0; // Enable interrupt TMR0 cnt = 0; // Variable cnt is assigned a 0 do { // Endless loop if (cnt == 400) { // Increment port B after 400 interrupts PORTB = PORTB++; // Increment number on port B by 1 cnt = 0; // Reset variable cnt } } while(1); }Interrupt occurs on every timer register TMR0 overflow.
/*Header******************************************************/ unsigned short cnt; // Define variable cnt void interrupt() { cnt++ ; // Interrupt causes cnt to be incremented by 1 PIR1.TMR1IF = 0; // Reset bit TMR1IF TMR1H = 0x80; // TMR1H and TMR1L timer registers are returned TMR1L = 0x00; // their initial values } void main() { ANSEL = 0; // All I/O pins are configured as digital ANSELH = 0; PORTB = 0xF0; // Initial value of port B bits TRISB = 0; // Port B pins are configured as outputs T1CON = 1; // Set timer TMR1 PIR1.TMR1IF = 0; // Reset bit TMR1IF TMR1H = 0x80; // Set initial value for timer TMR1 TMR1L = 0x00; PIE1.TMR1IE = 1; // Enable interrupt on overflow cnt = 0; // Reset variable cnt INTCON = 0xC0; // Enable interrupt (bits GIE and PEIE) do { // Endless loop if (cnt == 76) { // Change port B state after 76 interrupts PORTB = ~PORTB; // Number in port B is inverted cnt = 0; // Reset variable cnt } } while (1); }In this case, an interrupt is enabled after the timer register TMR1 (TMR1H, TMR1L) overflow occurs. Combination of bits changing on port B is different from that in the previous example.
/*Header******************************************************/ unsigned short cnt; // Define variable cnt void Replace() { PORTB = ~PORTB; // Define new function ‘Replace’ } // Function inverts port state void interrupt() { if (PIR1.TMR2IF) { // If bit TMR2IF = 1, cnt++ ; // Increment variable cnt by 1 PIR1.TMR2IF = 0;// Reset bit and TMR2 = 0; // reset register TMR2 } } // main void main() { cnt = 0; // Reset variable cnt ANSEL = 0; // All I/O pins are configured as digital ANSELH = 0; PORTB = 0b10101010; // Logic state on port B pins TRISB = 0; // All port B pins are configured as outputs T2CON = 0xFF; // Set timer T2 TMR2 = 0; // Initial value of timer register TMR2 PIE1.TMR2IE = 1; // Enable interrupt INTCON = 0xC0; // Set bits GIE and PEIE while (1) { // Endless loop if (cnt > 30) { // Change PORTB after more than 30 interrupts Replace(); // Function Replace inverts the port B state cnt = 0; // Reset variable cnt } } }This time, an interrupt occurs after timer register TMR2 overflow occurs. The Replace function, which normally doesn’t belong to C, is used in this example to invert port pins state.