4.11 Ejemplo 9
Contador de cuatro dígitos LED, multiplexión
En este ejemplo el microcontrolador funciona como un contador de dos dígitos. La variable i se incrementa (suficiente lentamente para ser visible) y su valor se visualiza en un visualizador de cuatro dígitos LED (9999-0). El punto es habilitar una conversión de un número binario en un decimal y partirlo en cuatro dígitos (en miles, centenas, decenas y unidades). Como los segmentos del visualizador LED se conectan en paralelo, es necesario asegurar que alternen rápidamente para tener una impresión de que emiten la luz simultáneamente (multiplexión por división en tiempo).
En este ejemplo, el temporizador TMR0 está encargado de la multiplexión por división en tiempo, mientras que la función mask convierte un número binario a formato decimal.
'Cabecera******************************************************
program example_9 ' Nombre de programa
dim shifter, portd_index as byte ' Variables shifter y portd_index son de tipo byte
digit, number as word ' Variables digit y number son de tipo word
portd_array as word[4] ' Matriz portd_array tiene 4 miembros de tipo word
sub function mask (dim num as Word) as Word ' Subrutina para enmascarar
select case num ' utilizada para convertir
case 0 result = $3F ' números binarios en la
case 1 result = $06 ' combinación de bits apropiada
case 2 result = $5B ' que se visualizará en el LED
case 3 result = $4F
case 4 result = $66
case 5 result = $6D
case 6 result = $7D
case 7 result = $07
case 8 result = $7F
case 9 result = $6F
end select ' Final de la sentencia Case
end sub ' Final de la subrutina
sub procedure interrupt ' Inicio de la rutina de interrupción
PORTA = 0 ' Apagar todos los visualizadores de 7 segmentos
PORTD = portd_array [portd_index] ' Enviar el valor apropiado al puerto PORTD
PORTA = shifter ' Encender el visualizador apropiado de 7 segmentos
shifter = shifter << 1 ' Mover shifter al siguiente dígito
if (shifter > 8) then
shifter = 1
end if
Inc(portd_index) ' Incrementar portd_index
if (portd_index > 3) then
portd_index = 0 ' Encender el primero, apagar el cuarto visualizador de 7 segmentos
end if
TMR0 = 0 ' Reiniciar el valor del TIMER0
T0IF_bit = 0 ' Borrar la bandera de interrupción del Timer0
end sub ' Final de la rutina de interrupción
main: ' Inicio del programa
ANSEL = 0 ' Configurar los pines analógicos como pines de E/S digitales
ANSELH = 0
OPTION_REG = $80 ' Configuración del Timer0 (Timer0 funciona como temporizador
' con el pre-escalador)
digit = 0 ' Valor inicial de la variable digit
portd_index = 0 ' Encender el primer visualizador LED
shifter = 1 ' Valor inicial de la variable shifter
TMR0 = 0 ' Borrar el Timer0
INTCON = $A0 ' Habilitar interrupción con los bits GIE y T0IE
PORTA = 0 ' Borrar el PORTA
TRISA = 0 ' Configurar el PORTA como salida
PORTD = 0 ' Borrar el PORTD
TRISD = 0 ' Configurar el PORTD como salida
number = 6789 ' Un valor inicial en el visualizador LED
while TRUE ' Bucle infinito
digit = number / 1000 ' Extraer miles
portd_array[3] = mask(digit) ' y almacenarlo en la matriz PORTD
digit = (number / 100) mod 10 ' Extraer centenas
portd_array[2] = mask(digit) ' y almacenarlo en la matriz PORTD
digit = (number / 10) mod 10 ' Extraer decenas
portd_array[1] = mask(digit) ' y almacenarlo en la matriz PORTD
digit = number mod 10 ' Extraer unidades
portd_array[0] = mask(digit) ' y almacenarlo en la matriz PORTD
Delay_ms(1000) ' Retardo de un segundo
Inc(number) ' Incrementar número
if (number > 9999) then ' Empezar a contar de cero
number = 0
end if
wend
end. ' Final de programa