Use Timer0, Timer1 and Timer2. Use interrupts, declare new procedure...
If you have read previous examples, you have probably noticed a disadvantage of using time delays. In all those cases, the microcontroller is ‘captive’ and does nothing. It simply waits for some time to pass. Such waste of time is often an unacceptable luxury and some other method should be employed here. Do you remember the story about timers? Interrupts? This example makes connection between them in a practical way. The schematic is still the same and challenge as well. It is necessary to provide a time 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 increments the cnt variable by 1. When it reaches 50, the PORTB is incremented by 1. The whole procedure is performed ‘behind the scenes’, which enables the microcontroller to do something else.' Header****************************************************** program example_4a ' Start of program dim cnt as byte ' Define variable cnt as byte sub procedure interrupt ' This subprocedure determines what should ' be done when an interrupt is generated cnt = cnt + 1 ' 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 end sub ' End of interrupt routine main: ' Start of program OPTION_REG = 0x84 ' Prescaler is assigned to timer TMR0 ANSEL = 0 ' All I/O pins are configured as digital ANSELH = 0 TRISB = 0 ' All PORTB pins are configured as outputs PORTB = 0x0 ' Reset PORTB TMR0 = 96 ' Timer T0 counts from 96 to 255 INTCON = 0xA0 ' Enable interrupt TMR0 cnt = 0 ' Variable cnt is assigned a 0 while 1 ' Endless loop if cnt = 50 then ' Increment PORTB after 50 interrupts PORTB = PORTB + 1 ' Increment number on PORTB by 1 cnt = 0 ' Reset variable cnt end if wend end. ' End of programAn interrupt is generated on every timer register TMR0 overflow.
'Header****************************************************** program example_4b ' Program name dim cnt as byte ' Define variable cnt sub procedure interrupt ' Define interrupt subprocedure cnt = cnt+1 ' 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 end sub ' End of interrupt routine main: ' Start of program ANSEL = 0 ' All I/O pins are configured as digital ANSELH = 0 PORTB = 0xF0 ' Initial value of PORTB bits TRISB = 0 ' PORTB 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) while 1 ' Endless loop if cnt = 76 then ' Change PORTB state after 76 interrupts PORTB = not PORTB ' Number in PORTB is inverted cnt = 0 ' Reset variable cnt end if wend end. ' End of programIn this case, an interrupt is enabled after the timer register TMR1 (TMR1H and TMR1L) overflow occurs. The combination of bits changing on PORTB is different from that in the previous example.
'Header****************************************************** program example_4c ' Program name dim cnt as byte ' Define variable cnt as byte sub procedure Replace ' Define procedure Replace PORTB = not PORTB ' Define new procedure ‘Replace’ end sub ' Procedure inverts port state sub procedure interrupt ' Define interrupt subprocedure if PIR1.TMR2IF then ' If bit TMR2IF = 1, cnt = cnt +1 ' Increment variable cnt by 1 PIR1.TMR2IF = 0 ' Reset bit and TMR2 = 0 ' reset register TMR2 end if end sub ' End of interrupt routine main: ' Start of program cnt = 0 ' Reset variable cnt ANSEL = 0 ' All I/O pins are configured as digital ANSELH = 0 PORTB = %10101010 ' Logic state on PORTB pins TRISB = 0 ' All PORTB 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 then ' Change PORTB after more than 30 interrupts Replace ' Function Replace inverts the PORTB state cnt = 0 ' Reset variable cnt end if wend end. ' End of programThis time, an interrupt is generated after timer register TMR2 overflow occurs. The Replace procedure, which normally doesn’t belong to mikroBasic, is used in this example to invert port pins state.