Para ayudar a varios compatriotas en mi Universidad me he dispuesto a crear esta entrada.. bla bla bla
A lo bueno.
NOTA: Se seguirá usando para programar el microcontrolador el debugger ICSP tan usado en anteriores entradas (BDM).
Descripción del Proyecto.
Crear una cuenta de 0 a 99, la cual se incrementará en una unidad cada segundo, esta cuenta será en sistema decimal y los resultados de la misma serán mostrados en dos display de 7 segmentos, uno por digito.
Se usaran dos transistores 2N3906 como conmutadores para activar cada uno de los display de 7 conectando el común de estos al transistor los cuales por medio de un pulso en su Base activaran o desactivaran el display a conveniencia.
Se usan también dos Buffers de corriente CD4050 para que la corriente demandada por cada display se cargue sobre estos y no sobre los microcontroladores y que este ultimo solo tenga la acción de mandar pulsos lógicos de voltaje.
Contador digital
Un contador
digital es básicamente un circuito electrónico que muestra un cambio cada
cierto periodo de tiempo establecido, este periodo de tiempo es común que sea
ajustable.
Estos cambios se pueden manifestar de diferentes maneras de acuerdo
a lo que se desee lograr, como por ejemplo, mostrar una cuenta de números en
cualquier tipo interfaz visual, o activar cierto relé que a su vez crear más
cambios.
También son usados como una manera sencilla de realizar acciones
cada cierto tiempo.
En nuestro caso, nuestro contador mostrara una cuenta de números
decimales del 0 al 99 mostrado en dos display de 7 segmentos, esta cuenta se
incrementara en intervalos de una unidad cada segundo que pase.
Display
de 7 segmentos
Los Display de 7 segmentos son básicamente un arreglo de leds
ordenados de tal forma que encendiendo unos cuantos de estos puedes formar
números y algunas letras, en otros símbolos.
Hay dos distintos, ya sea cátodo común o ánodo común, esto debido a
que los leds dentro de los mismo tienen todos interconectados a un mismo punto
el cátodo o el ánodo.
Por tanto conectando este punto común a una fuente de voltaje (para
el caso del ánodo común) se puede encender cada led interno mandando un estado
lógico bajo o a tierra (para el caso del cátodo común) y mandándole un pulso
lógico alto.
Transistor
PNP 2N3906
El transistor es un dispositivo semiconductor que cumple varias
funciones, entre ellas están las de amplificador, oscilador, conmutador o
rectificador. En este caso lo usaremos de conmutador para crear la acción de
barrido en los display de 7 segmentos.
Esquematicos
Descarga: pdf
CODIGO
;******************************************************************* ;* This stationery serves as the framework for a user application. * ;* For a more comprehensive program that demonstrates the more * ;* advanced functionality of this processor, please see the * ;* demonstration applications, located in the examples * ;* subdirectory of the "Freescale CodeWarrior for HC08" program * ;* directory. * ;******************************************************************* ; Include derivative-specific definitions INCLUDE 'derivative.inc' ; ; export symbols ; XDEF _Startup ABSENTRY _Startup ; ; variable/data section ; ORG RAMStart ; Insert your data definition here ExampleVar: DS.B 1 contador: equ $90 unidades: equ $92 unidadesA: equ $93 decenas: equ $94 decenasA: equ $95 tope: equ $96 ; ; code section ; ORG ROMStart _Startup: LDHX #RAMEnd+1 ; initialize the stack pointer TXS CLI ; enable interrupts PROG_PORTS: MOV #$FF,PTBDD ;puerto B salida MOV #$FF,PTCDD ;declaramos puerto C como salida MOV #$64,RTCMOD ;declaramos timer a un segundo, con tope el 100=$64 MOV #%1111,RTCSC MOV #$00,contador ;iniciamos el contador con cero MOV #$00,unidades ;inicializamos unidades y decenas MOV #$00,decenas ;cargamos el valor de ajuste a disp 7 segm en las memorias MOV #111111,$80 ;ajuste del 0 MOV #000110,$81 ;ajuste del 1 MOV #%01011011,$82 MOV #%01001111,$83 MOV #%01100110,$84 MOV #%01101101,$85 MOV #%01111101,$86 MOV #000111,$87 MOV #%01111111,$88 MOV #%01100111,$89 ;ajuste del 9 main: feed_watchdog BSR checa_cuenta ;vamos a la subrutina que lleva la cuenta en unidades y decenas BSR ajusta_unidades ;subrutina que ajusta el valor de unidades y decenas para desplegarlo en el disp 7 segm BSR ajusta_decenas LDA unidadesA ;cargamos unidades y decenas ajustadas y las mostramos en el display STA PTBD MOV #%10,PTCD BSR retardo LDA decenasA STA PTBD MOV #%01,PTCD BSR retardo LDA contador ;checamos si se paso del 99 CBEQA #$64,hacercero BRA main ;subrutina que regresa a cero todo ;------------------- hacercero: MOV #$00,unidades MOV #$00,unidadesA MOV #$00,decenas MOV #$00,decenasA MOV #$00,contador BRA main ;-------------------------------- ;--------------Rutina checa cuenta checa_cuenta: LDA RTCCNT CMP contador BNE incrementa_cuenta ;si no es el mismo numero, es decir, ya cambio (ya paso el tiempo programado) RTS ;si es el mismo, regresamos incrementa_cuenta: LDA RTCCNT ;como no son iguales, los hacemos iguales STA contador INC unidades ;si las unidades completa una decena LDA unidades ;regresamos a cero unidades y decenas +1 CMP #$A BEQ una_decena_mas RTS una_decena_mas: MOV #$00,unidades INC decenas RTS ;--------------termian rutina checa cuenta ;---------------------*******Subrutina de retardo retardo: LDHX #$0000 RET1: feed_watchdog AIX #$01 CPHX #$FF ;Se incrementa este valor para hacer un retardo mas largo BNE RET1 RTS ;-----------------------****Termian el retardo ;.---------------------------Subrutinas de ajuste ajusta_unidades: LDHX #$80 ;apuntamos a la memoria $80, que es donde empiezan los valores de ajuste MOV #$80,tope ;colocamos $80 en la memoria que servira de tope LDA unidades ADD tope ;cargamos las unidades y las sumamos a tope obteniendo asi ($80+unidades) la direccion del numero para ajustar STA tope ciclo_unidades: feed_watchdog ;recorremos desde la memoria $80 hasta que llegemos a la memoria tope($80+unidades) CPX tope BEQ salir_unidades INCX BRA ciclo_unidades salir_unidades: LDA ,X STA unidadesA ;el valor de la memoria tope la guardamos en unidadesA el cual sera el valor ajustado de la unidad RTS ajusta_decenas: LDHX #$80 ;misma explicacion que para unidades pero con decenas MOV #$80,tope LDA decenas ADD tope STA tope ciclo_decenas: feed_watchdog CPX tope BEQ salir_decenas INCX BRA ciclo_decenas salir_decenas: LDA ,X STA decenasA RTS ;--------------Terminan las subrutinas de ajuste ;************************************************************** ;* spurious - Spurious Interrupt Service Routine. * ;* (unwanted interrupt) * ;************************************************************** spurious: ; placed here so that security value NOP ; does not change all the time. RTI ;************************************************************** ;* Interrupt Vectors * ;************************************************************** ORG $FFFA DC.W spurious ; DC.W spurious ; SWI DC.W _Startup ; Reset
Descarga .asm: aqui
Descarga el proyecto para CodeWarrior: aqui
REVISION
Este codigo que coloco fue desarrollado hace mucho tiempo por mí, así que por el momento no recuerdo del todo sí es 100% funcional o si falta ajustar algo (tengo varias versiones del mismo proyecto y coloqué aquí la mas reciente).
Pido a cualquier persona que se atreva a probarlo a comentar su funcionalidad.
tchao
Sabes cómo podría hacer un retardo de 100mseg??
ResponderEliminarTienes que crear un ciclo que se repita N veces y calcular el tiempo de ejecucion por ciclo de tal forma que N * (tiempo_por_ciclo) = 100ms.
ResponderEliminarNo es facil, ocuparias ver el set de instrucciones y ver cuanto se tarda por instruccion y a partir de alli comenzar a calcular.
Normalmente lo que se hace es incrementar y/o decrementar una variable en el cuerpo del ciclo.
Vaya! Es basicamente tener ocupado al micro a lo idiota :)
BTW nada recomendable.
Que programa utilizas para hacer la simulación? muchas gracias!!!
ResponderEliminar