PIC16F84 mikroBasic: mux display 7seg

Questo programma per il multiplex di due display sette segmenti, non funziona bene.
Il problema sembrerebbe risiedere nell'interrupt
Proteus dà la stessa risposta della realizzazione: le cifre appaiono random, quando 22, quando 33,
quando alternativamente
Grazie
- Codice: Seleziona tutto
' P16F84A
' 4MHz / XT
' mikroBasic 6.0.0 (free)
program COUNTER_UP
' ---------- G L O B A L D E C L A R A T I O N S -----------------
' Global variables (the ones shared with ISR is qualified as 'volatile')
dim display_on as byte volatile ' which display to activate? D1 or D2
dim mask_D2 as byte volatile ' 7seg mask for D2
dim mask_D1 as byte volatile ' 7seg mask for D1
' ----------- F U N C / P R O C / I S R ---------------------------------------
' The well known 7seg mask function
sub function mask (dim num as byte) as byte
select case (num)
case 0 result = %0111111
case 1 result = %0000110
case 2 result = %1011011
case 3 result = %1001111
case 4 result = %1100110
case 5 result = %1101101
case 6 result = %1111101
case 7 result = %0000111
case 8 result = %1111111
case 9 result = %1101111
end select
end sub
' --- Interrupt routine (unique for all the interrupt)
sub procedure interrupt()
if INTCON.T0IF=1 then ' overflow timer0?
INTCON.T0IF = 0 ' reset flag interrupt Timer 0
select case (display_on)
' --- switch on D1
case 1
PORTA.1 = 0 'switch off D2
PORTA.0 = 1 'switch off D1
PORTB = mask_D1
display_on = 2 'next int. will be switched on D2
' --- switch on D2
case 2
PORTA.1 = 1 'switch on D2
PORTA.0 = 0 'switch off D1
PORTB = mask_D2
display_on = 1 'next int. will be switched on D1
end select
end if
TMR0 = 0 ' reset TMR0
INTCON.INTE = 1 ' enable again all ints.
end sub
' -------------- M A I N ---------------------------------------
main:
' Main program
dim n as byte ' counting variable: 0..99
' --- set direction data
TRISB = 0 ' RB7...RB0 all out (7seg LED)
TRISA.0 = 0 ' RA0 out (drive D1)
TRISA.1 = 0 ' RA1 aout (driver D2)
' --- clear outputs
PORTB = 0 ' Pin RB7..RB0 all at 0V
PORTA.0 = 0 ' Pin RA0 at 0V
PORTA.1 = 0 ' Pin RA1 at 0V
' --- Config. Timer 0
TMR0 = 0
OPTION_REG.PSA = 0 ' int. clock is for timer0 (not for w/dog)
OPTION_REG.PS0 = 1 ' prescaler 16 (256*16)*4*1usec <-> above 100 Hz refresh
OPTION_REG.PS1 = 1 ' " "
OPTION_REG.PS2 = 0 ' " "
INTCON.GIE = 1 'enable all ints
INTCON.T0IE = 1 'enable timer0 int overlow
INTCON.T0IF = 0 'clear flag T0IF
OPTION_REG.T0CS = 0 'start the timer (?)
n = 0 'count start from o
display_on = 1 'the first display to switch on is D1
while 1
mask_D1 = mask(n / 10)
mask_D2 = mask(n mod 10)
delay_ms (500) '**** I have to pass 500 to obtain 1000ms *****
if n = 99 ' reached 99?
then n = 0 ' ... start again from 0
end if
n = n + 1 ' increment of 1
wend
end.