Está en la página 1de 11

Cartel de Leds en ASM

Posted on 14 Septiembre, 2010 by Suky

Aqu voy a mostrar una forma sencilla de hacer un cartel de leds en asm que tendr algunas limitaciones, pero entendiendo como es el funcionamiento y el esfuerzo de ustedes podrn romper esas barreras! Para mostrar un ejemplo sencillo vamos a usar una tabla para guardar el mensaje a mostrar y una sola variable (8 bits) para indicar el largo y control de la posicin a enviar. Por ello el largo del mensaje estar restringido a 255 bytes que se reducen en 6 por La la forma posicin de de la cada tabla letra en del la memoria mensaje ser de la programa.siguiente: guardar

Cada byte indica una columna de la letra, donde un 0 es led apagado y 1 led encendido. Nota: Es una forma de hacerlo, la cual la aprend del amigo BrunoF en uno de sus tantos aportes Luego el mensaje puede ser mayor al cartel utilizado para mostrarlo as que es necesario efectuar un desplazamiento del mensaje sobre el cartel o lo que es lo mismo desplazar el cartel sobre el mensaje. Para ello se utilizar una variable que indica la posicin inicial dentro del mensaje, en la cual comienza a mostrarse en el cartel. Como deseamos que el mensaje sea rotativo el problema se presenta en las ltimas posiciones donde se debe mostrar la parte final del mensaje y empezar a mostrar el inicio Lo que hacemos es dividir en 2 la forma de mostrar el mensaje, cuando Posicin Inicial + Largo del Cartel sea menor a Largo del mensaje y cuando sea mayor:

Bueno, ms o menos se ha explicado como vamos a trabajar con el mensaje, ahora se debe entender como va a funcionar el multiplexo de los leds. Vamos a realizar la multiplexacin por filas, sea que vamos a seleccionar una fila y vamos a actualizar sus valores por medio de registros de desplazamientos. El tiempo de actualizacin no debe superar los 20ms! Para actualizar usaremos una variable que indique que fila ha de actualizarse, por ejemplo para actualizar la fila uno la variable FilaActual ser 00000001. Ahora para saber que valores tenemos que mandar a los registros de desplazamiento iremos tomando cada una de las columnas (PosicionEnviar) a actualizar, aremos un AND con FilaActual y determinaremos si enviar un 1 o un 0.( PosicionEnviar (AND) FilaActual ) = FilaActual? Si -> Enviamos un 1 No-> Enviamos un 0 Hardware para simulacin:

; CARTEL DE LEDS. de 32x8. ; Si las letras son de 8x8, maxima cantidad de letras en el mensaje 31.; **** Encabezado **** list p=16F628A ; Microcontrolador utilizado.#include P16F628A.inc ; Definicion de registros SFR.__CONFIG _HS_OSC & _PWRTE_ON & _WDT_OFF & _CP_OFF & _MCLRE_ON & _BOREN_OFF & _LVP_OFF & _DATA_CP_OFF ;**** Definicion de Variables **** CBLOCK 0x20 (GPR) STATUS_Temp W_Temp Banderas FilaActual ; En esta posicion se declaran los registros de usuario ; Registro para guardar temporalmete STATUS

; Registro para guardar temporalmete W ; Registro para almacenar banderas.; Fila Actual a refrescar.-

PosicionInicial ; Posicion inicial dentro del mensaje a visualizar en el cartel.- (Entre 0 y LargoMsj-1) PosicionEnviar ; Posicion del registro a enviar.CuentaRefrescos ; Cuenta la cantidad de refrescos realizados. LargoCartel ; Guarda largo del cartel.- 32 LargoMsj ; largo del mesaje a visualizar-> Max 249 Bytes.-Para aumentar modificar manejo de tabla.TempH TempL ENDC Velocidad ; Temporal para guardar calculos matemticos.; Temporal...

VelMovimiento ; Para fijar velocidad de movimiento.equ d'4' ; Para fijar velocidad de desplazamiento.; Bandera que indica que han pasado 2ms.-

kbhit_tiempo equ 0 kbhit_cuadro equ 1 BData BClock Strobe equ 0 equ 1 equ 2

;**** Inicio del Microcontrolador **** Reset org 0x00 ; Salto a inicio del programa.goto Inicio

;**** Vector de Interrupcion **** org 0x04 goto Inicio_ISR ; Atiendo Interrupcion.-

;**** Mensaje a Mostrar ***** org 0x05

Mensaje addwf PCL,1 ; Se incrementa el contador del programa.DT 0x38, 0x7C, 0xFE, 0x82, 0x82, 0x82, 0x44, 0x00 ; C DT 0x60, 0xF4, 0x94, 0x94, 0xFC, 0xF8, 0x00, 0x00 ; a DT 0xFC, 0xFC, 0x08, 0x04, 0x04, 0x00, 0x00, 0x00 ; r DT 0x04, 0xFE, 0xFE, 0x84, 0x40, 0x00, 0x00, 0x00 ; t DT 0x78, 0xFC, 0x94, 0x9C, 0x58, 0x00, 0x00, 0x00 ; e DT 0xFE, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ; l DT 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ; Espacio DT 0x78, 0xFC, 0x84, 0x48, 0xFE, 0xFE, 0x00, 0x00 ; d DT 0x78, 0xFC, 0x94, 0x9C, 0x58, 0x00, 0x00, 0x00 ; e DT 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ; Espacio DT 0xFE, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ; l DT 0x78, 0xFC, 0x94, 0x9C, 0x58, 0x00, 0x00, 0x00 ; e DT 0x78, 0xFC, 0x84, 0x48, 0xFE, 0xFE, 0x00, 0x00 ; d DT 0x88, 0x9C, 0x94, 0xF4, 0x64, 0x00, 0x00, 0x00 ; s DT 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ; Espacio DT 0x8C, 0x9E, 0xFE, 0xFA, 0x62, 0x00, 0x00, 0x00 ; S DT 0x7C, 0xFC, 0x80, 0x80, 0xFC, 0xFC, 0x00, 0x00 ; u DT 0xFE, 0xFE, 0x10, 0x38, 0x64, 0xC4, 0x80, 0x00 ; k DT 0x04, 0x8C, 0xB8, 0x70, 0x30, 0x08, 0x04, 0x00 ; y DT 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ; Espacio DT 0x82, 0xC1, 0xA1, 0x91, 0xCE, 0x00, 0x00, 0x00 ; 2 DT 0x80, 0x86, 0x85, 0x89, 0x71, 0x00, 0x00, 0x00 ; 5 DT 0xC0, 0x3C, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00 ; / DT 0x81, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00 ; 1 DT 0x7E, 0x81, 0x81, 0x81, 0x7E, 0x00, 0x00, 0x00 ; 0 DT 0xC0, 0x3C, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00 ; / DT 0x7E, 0x81, 0x81, 0x81, 0x7E, 0x00, 0x00, 0x00 ; 0 DT 0x8E, 0x91, 0x51, 0x71, 0x1E, 0x00, 0x00, 0x00 ; 9 DT 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ; Espacio ;**** Programa principal **** Inicio ;---- Configuraciones ---bsf STATUS,RP0 ; Banco 1.movlw 0xF8 movwf TRISA ;eeeeesss movlw 0x00 movwf TRISB ;ssssssss movlw 0xDF movwf OPTION_REG ; Pull-Up deshabiltado, , Timer0|interno, 1:1 bcf STATUS,RP0 ; Banco 0.-

movlw 0x07

; Configuro Comparador Analogico

movwf CMCON ; V1in-=GND, V1in+=GND, C1out=Off| V2in-=GND, V2in+=GND, C2out=Off clrf PORTA clrf PORTB movlw 0x4D movwf T2CON ; Timer2: Pre=1:4, Post=1:10 movlw Velocidad ; Cargamos velocidad de desplazamiento.-

movwf VelMovimiento movlw d'32' ; Cargamos largo del cartel.movwf LargoCartel movlw d'232' ; Cargamos largo del mensaje.movwf LargoMsj clrf PosicionInicial clrf Banderas movlw 0x01 movwf FilaActual movlw 0x08 movwf CuentaRefrescos clrf bsf bsf bcf bsf bsf Bucle btfss Banderas,kbhit_tiempo ; Se espera a que pasen 2 ms.goto $-1 bcf Banderas,kbhit_tiempo call ActualizarCartel ; Se actuliza fila del cartel.goto Bucle PIR1 ; Limpiamos Banderas

STATUS,RP0 ; Banco 1.PIE1,TMR2IE ; Habilitamos interrupcion por Timer2 STATUS,RP0 ; Banco 0.INTCON,GIE ; Habilitacion general de interrupciones INTCON,PEIE ; Habilitacion de interrupciones Perifericas

;************************************************************************** ;**** Rutina de servicio de Interrupcion **** Inicio_ISR ;---- Guardado de registro W y STATUS ---movwf W_Temp ; Copiamos W a un registro Temporario swapf STATUS,W ; Invertimos nibles de STATUS

movwf STATUS_Temp ; Guardamos STATUS en un registro temporal ;---- Interrupciones ---btfsc PIR1,TMR2IF ; Interrupcion por Timer2? goto ISR_TIMER2 ; Si, se trata interrupcion ;............................. Fin_ISR ;---- Restauramos los valores de W y STATUS ---swapf STATUS_Temp,W movwf STATUS swapf W_Temp,f swapf W_Temp,W retfie ;....................... ISR_TIMER2 ; Tratamiento de Interrupcion decfsz CuentaRefrescos,1 ; Se refrescaron las 8 filas (Momento adecuado para realizar algun cambio.-) goto SetBandera ; No, seguimos.. decfsz VelMovimiento,1 ; Si, ya pasaron 16ms x VelMovimiento? goto RecargarData ; No, seguimos... movlw Velocidad ; Recargamos Velocidad movwf VelMovimiento incf PosicionInicial ; Si, incrementamos PosicionInicial para efectuar ; Verificamos si ya se llego al final del Mensaje."movimiento" movfw LargoMsj subwf PosicionInicial,0 btfss STATUS,Z goto RecargarData clrf PosicionInicial RecargarData movlw 0x01 movwf FilaActual movlw 0x08 movwf CuentaRefrescos SetBandera bsf bcf Banderas,kbhit_tiempo ; Indicamos que han pasado 2 ms, y es PIR1,TMR2IF ; Borramos bandera necesario actualizar.goto Fin_ISR ;....................... ;************************************************************************* ActualizarCartel ; No, seguimos.. ; Si, reseteamos PosicionInicial.-

; Es (PosicionInicial + LargoCartel <= LargoMsj)? clrf bcf TempH STATUS,C ; Borramos Byte alto de variable de 16bits temporal.; Aseguramos que el carry sea 0 :P ; Sumamos PosicionInicial + largoCartel.-

movfw PosicionInicial

addwf LargoCartel,0 ; Y lo guardamos en W.movwf TempL ; Cargamos el resultado bajo en variable temporal.btfsc STATUS,C resultado temporal.incf TempH ; y si hay carry incrementamos registro alto del ; (Esto se da porque el resultado es mayor a 255) ; Es mayor a 255? ; (Solo lo hacemos as porque LargoMsj debe ser ; No es mayor a 255, verficamos Byte bajo.-

btfsc TempH,0 goto $+4 menor o igual a 255) movfw TempL subwf LargoMsj,0

btfss STATUS,C goto DividoEnDosPartes ; Es mayor... ;**************************************************************************** ; Es menor... ; Hay que de la posicion actual sumar el largo de leds y despues comenzar a actualizar el cartel.movfw TempL mensaje.movwf PosicionEnviar CicloEnvio call decf EnviaBit ; Se envia bits actual del byte seleccionado.; Se decrementa direccionador del byte a ; Es igual a la posicion inicial de donde se PosicionEnviar,1 ; Cargamos posicion de donde comenzar a cargar

enviar.movfw PosicionInicial

comienza a visualizar mensaje?? subwf PosicionEnviar,0 btfss STATUS,Z ; goto goto CicloEnvio Efectivizamos ; No, seguimos con el siguiente byte.; Ahora se habilitar Strobe para efectivizar los

cambios y activaremos la Fila correspondiente.;****************************************************************************** ; Es mayor... DividoEnDosPartes ;(LargoMsj - PosicionInicial): movfw PosicionInicial

subwf LargoMsj,0 movwf TempL temporal.movfw TempL subwf LargoCartel,0 movwf PosicionEnviar ; Guardamos desde donde comenzamos a enviar disminuyendo hasta 1... CicloEnvio_1 call EnviaBit ; Se envia bits actual del byte seleccionado.; Se decrementa direccionador del byte a decf PosicionEnviar,1 enviar.movlw 0x00 subwf PosicionEnviar,0 btfss STATUS,Z goto CicloEnvio_1 ; Enviamos Segunda parte.movfw LargoMsj movwf PosicionEnviar CicloEnvio_2 call EnviaBit ; Se envia bits actual del byte seleccionado.decf PosicionEnviar,1 ; Se decrementa direccionador del byte a enviar.movfw PosicionInicial subwf PosicionEnviar,0 btfss STATUS,Z goto goto CicloEnvio_2 Efectivizamos ; No, seguimos con el siguiente byte.; Ahora se habilitar Strobe para efectivizar los ; Es igual a la posicion inicial de donde se comienza a visualizar mensaje?? ; Es igual a 0x00?? ; Guardamos resultado de la resta en registro

;[LargoCartel - (LargoMsj - PosicionInicial)]:

cambios y activaremos la Fila correspondiente.;******************************************************************************* ***** EnviaBit decf PosicionEnviar,0 call Mensaje andwf FilaActual,0 subwf FilaActual,0

; Cargamos posicion en W del byte a visualizar.; Hacemos ByteActual (AND) FilaActual para ; [ByteActual(AND)FilaActual] - FilaActual, si

; Cargamos en W el byte actual a refrescar.-

determinar el bit a enviar.esto es cero el bit a enviar es 1, sino 0.bcf PORTA,BData ; Primero cargamos un 0.btfsc STATUS,Z bsf PORTA,BData ; La operacion anterior es 0? ; Si, cargamos un 1 en el bit

bsf

PORTA,BClock

; Generamos clock.-

nop ; demora bcf PORTA,BClock ;.. return ;.......................................................... Efectivizamos movlw 0xFF movwf PORTB bsf PORTA,Strobe desplazamiento.nop bcf PORTA,Strobe comf FilaActual,0 ; Complementamos FilaActual para activar Fila actual a refrescar.movwf PORTB bcf STATUS,C ; ; Rotamos Fila actual para proxima actualizacion.rlf FilaActual,1 return end ; Descactivamos todas las filas.; Efectivizamos los datos en los registros de

Y cambiar rutina de efectivizar a :

Efectivizamos clrf PORTB ; Desactivamos todas las filas.bsf PORTA,Strobe ; Efectivizamos los datos en los registros de desplazamiento.nop bcf PORTA,Strobe movfw FilaActual ;Refrescamos fila actual.movwf PORTB bcf STATUS,C ; rlf FilaActual,1 ; Rotamos Fila actual para proxima actualizacion.return

Otra Forma

Pero deben tener en cuenta que para encender un led se debe enviar al registro de desplazamiento un cero! Proyectos invitados!!! En este caso mostramos el proyecto realizado por Alex Oteiza, realmente muy buen trabajo:

También podría gustarte