documentation

Anuncio
Diseño con Microcontroladores
Diseño de un Cronómetro
Santiago González Tortosa (990285)
Ana Esperanza Raposo Abreu (990287)
9 de febrero de 2005
ÍNDICE
Índice
1
1
2
INTRODUCCIÓN
1.
Introducción
Se trata de construir un cronómetro, utilizando un microcontrolador. Las funciones que tendrá que
cumplir dicho cronómetro son las siguientes:
Tendrá dos contadores independientes de tiempos.
Podrá recibir órdenes desde un PC a través del puerto serie o bien desde un teclado.
Mostrará los tiempos por un LCD o por el ordenador a través del puerto serie.
Podrá almacenar hasta tres tiempos parciales de cada contador.
Tendrá un Reset para poner a cero el contador con el que se está trabajando.
Para construir el cronómetro vamos a utilizar el microcontrolador 8052 (de la familia de los
Intel), que nos proporciona tres contadores y suficientes puertos para realizar la E/S de una manera
sencilla.
2.
Esquema General del Cronómetro
El esquema general del cronómetro es el siguiente:
Fuente de
Alimentacion
8052
Clock
LCD
Teclado
Figura 1: Esquema del cronómetro
2.1.
Conexión con el puerto serie
Para realizar la conexión con el puerto serie, se ha utilizado el controlador Max232. El diagrama
de conexión es el que se muestra en la figura 2.
2.2.
Teclado
Para simplificar lo más posible esta práctica, hemos utilizado un simple teclado a base de interruptores1 . Además, generamos la señal de interrupción con una puerta AND y la conectamos a
INT0.
Ası́ pues, el esquema es el que muestra la figura 3.
1 Este esquema no contiene las modificaciones necesarios para evitar problemas de repetir interrupciones debido
al tiempo de pulsado de una tecla
2
3
ESQUEMA GENERAL DEL CRONÓMETRO
1 microF
VCC
16
1
GND
15
2
Dout1 14DS14C2323
Rin1
13
4
Rout1
12
5
Din1
6
11
MAX232 7
10
9
8
8052
p3.0
p3.1
VCC
C1+
V+
C1C2+
C2V-
1 microF
1 microF
1 microF
Figura 2: Puerto Serie
VCC
8052
p3.2
INT0
Teclado
p0.0
p0.1
p0.2
p0.3
p0.4
p0.5
p0.6
p0.7
GND
Figura 3: Teclado
2.3.
LCD
Utilizamos todo el puerto P1 como señales de datos y parte del P2 como señales de control de
LCD. El esquema está detallado en la figura 4.
2
4
ESQUEMA GENERAL DEL CRONÓMETRO
8052
DATOS [0..7]
p1.0
p1.1
p1.2
p1.3
p1.4
p1.5
p1.6
p1.7
p2.5
p2.6
p2.7
LCD
RW
RS
EN
Figura 4: LCD
2.4.
Reloj, Reset y Fuente de Alimentación
Utlizando los esquemas dados en clase, y el cristal que nos recomiendan para el 8052, quedan
ası́ las conexiones:
Xin
Xout
Cristal
33pF
33pF
Figura 5: Reloj
Para resetear el microcontrolador utilizamos el siguiente esquema:
VCC
10microF
8,2KOhmios
VCC
8052
RST
VSS
Figura 6: Reset
Para la fuente usamos el esquema que aprendimos en clase:
3
5
CUENTAS Y CONTADORES
LM7805
100nF
VCC
100nF
GND
Figura 7: Fuente de Alimentación
3.
Cuentas y Contadores
El cronómetro poseerá dos cuentas. Los tiempos los contareoms con dos contadores diferentes,
el contador 0 y el 1 del microcontrolador.
Utilizamos los contadores para que vayan marcando las centésimas de segundo, que es el valor
más pequeño que debemos manejar. Por cada interrupción del contador, iremos sumando uno a la
cuenta de centésimas de la cuenta que esté activa (pueden estar ambas activas).
3.1.
Configuración de los contadores
Debemos tener cuidado con la elección del modo del temporizador, ya que nos interesa que el
contador sea exacto. La forma que hemos encontrado mas exacta es la siguiente:
Para que los contadores cuenten una centésima de segundo, tendremos que configurarlo de la
siguiente manera:
Elegimos el modo 2 del contador (8 bits con autorrecarga).
Teniendo un cristal de 11,0592 MHz y sabiendo que el número de ciclos que se tarda en
realizar un incremento de temporizador es 12, tenemos que el numero de incrementos por
segundo son: 11,059,200 / 12 = 921,600.
Ahora bien, sabemos que son 921600 incrementos por segundo, es decir, 9216 incrementos
por centesima de segundo.
Por tanto tendremos 921600 / 256 = 36 interrupciones por centesima de segundo.
Por tanto para hallar 1 centesima de segundo exacta, debemos esperar 36 interrupciones del
temporizador.
3.2.
Cuentas
Para almacenar los tiempos de cada cuenta, utilizamos la memoria del microcontrolador. Renombramos las direcciones para hacerlo más sencillo, y por cada cuenta almacenamos:
El tiempo principal de la cuenta
Los tres tiempos parciales que tengamos almacenados
3
CUENTAS Y CONTADORES
6
;contador de interrupciones
TICKS EQU 3Fh
; Tiempo del crono 0
Horas0 EQU 40h
Minut0 EQU 41h
Segus0 EQU 42h
Cente0 EQU 43h
; 3 Tiempos parciales del crono 0
Horas0_1 EQU 44h
Minut0_1 EQU 45h
Segus0_1 EQU 46h
Cente0_1 EQU 47h
Horas0_2 EQU 48h
Minut0_2 EQU 49h
Segus0_2 EQU 4Ah
Cente0_2 EQU 4Bh
Horas0_3 EQU 4Ch
Minut0_3 EQU 4Dh
Segus0_3 EQU 4Eh
Cente0_3 EQU 4Fh
; Tiempo del crono 1
Horas1 EQU 50h
Minut1 EQU 51h
Segus1 EQU 52h
Cente1 EQU 53h
; 3 Tiempos parciales del crono 1
Horas1_1 EQU 54h
Minut1_1 EQU 55h
Segus1_1 EQU 56h
Cente1_1 EQU 57h
Horas1_2 EQU 58h
Minut1_2 EQU 59h
Segus1_2 EQU 5Ah
Cente1_2 EQU 5Bh
Horas1_3 EQU 5Ch
Minut1_3 EQU 5Dh
Segus1_3 EQU 5Eh
Cente1_3 EQU 5Fh
De esta manera, por cada 36 interrupciónes del contador correspondiente incrementaremos las
centésimas y, si es necesario (al llegar a 100) las pondremos a cero e incrementaremos los segundos.
Cuando los segundos lleguen a 60 los pondremos a cero e incrementaremos los minutos, y ası́ sucesivamente.
Para que el cronómetro muestre las horas en dos dı́gitos, hemos establecido como lı́mite para
las horas el valor 99.
Para saber con qué cuenta estamos trabajando en cada momento, simplemente utilizamos un
registro del microcontrolador, que valdrá 0 si estamos trabajando con la primera cuenta y 1 si
estamos trabajando con la segunda.
4
COMUNICACIÓN CON PC, LCD Y TECLADO
4.
7
Comunicación con Pc, LCD y Teclado
4.1.
Comunicación con el Pc por puerto serie
La idea es enviar y recibir información utilizando un buffer interno del 8052. Para ello necesitamos activar las interupciones externas del puerto serie y utilizar el modo con UART. La UART
utiliza el temporizador 2 en modo 2. El valor con el que contamos en el temporizador se halla de
la siguiente forma:
TH1 = 256 - ((Hz Crystal / 384) / Baud)
Teniendo un cristal de 11.059 MHz y queriendo una conexion de 19.200 Baudios, tenemos que
el valor inicial del temporizador es 253.
Tenemos las señales TI y RI pertenecientes al registro de Control Serie del Micro. Cuando
recibimos una interrupción del puerto serie y vemos que se recibe información (RI), atendemos lo
que nos envı́an. Cuando enviamos algo por el puerto serie, se nos comunicará que se ha recibido
con una interrupción e indicado en el registro TI.
La forma de comunicarse el ordenador con el 8052 en nuestra práctica es la siguiente:
Caracter ’S’: Start / Stop
Caracter ’P’: Parada
Caracter ’C’: Cambio
Caracter ’R’: Reset
Caracter ’L’: Mostrar Tiempo Principal
Caracter ’1’: Mostrar Tiempo Parcial 1
Caracter ’2’: Mostrar Tiempo Parcial 2
Caracter ’3’: Mostrar Tiempo Parcial 3
4.2.
Montaje del LCD
En esta práctica vamos a utilizar el LCD HD44780U de Hitachi.
Existen tres señales de control: EN, RS y RW.
EN es la señal “Enable”. Esta señal indica al LCD que se están enviando datos. Para enviar
datos al LCD, primero ponemos la señal EN a 1. Seguidamente realizamos el envı́o (y modificamos
otras señales). Cuando se ha realizado la transferencia (el bit 76 de ACC está activo) debemos
poner la señal a 0.
RS es la señal “Register Select”. Cuando la señal está a 0, el dato que se está enviando es una
instrucción especial (como por ejemplo posicionar el cursos del LCD o limpiar la pantalla). Cuando
la señal está a 1, los datos que se están enviando son datos que se van a escribir por el Display.
RW es la señal “Read/Write”. Cuando RW está a 0, los datos se escribirán en el LCD. Sólo se
utiliza RW = 1 cuando se quiere saber el estado del LCD (ocupado o libre).
Una vez explicados estos tres conceptos, contaremos los pasos realizados para la comunicación
con el LCD:
5
MANEJO DEL CRONÓMETRO
8
Necesitamos declarar las siguientes variables:
;Datos para el LCD
DB0 EQU P1.0
DB1 EQU P1.1
DB2 EQU P1.2
DB3 EQU P1.3
DB4 EQU P1.4
DB5 EQU P1.5
DB6 EQU P1.6
DB7 EQU P1.7
EN EQU P2.7
RS EQU P2.6
RW EQU P2.5
DATA EQU P1
Para cualquier operación con el LCD, debemos esperar hasta que el estado del mismo sea
libre. Para ello utilizamos la rutina WAIT LCD.
Iniciación del LCD: Debemos indicarle al LCD el modo de funcionamiento del mismo. Utilizando la documentación, sabemos los datos que debemos enviarle al LCD. La rutina de inicio
es INIT LCD.
Siempre que se quiera escribir en el LCD, se tendrá que limpiar antes la pantalla del Display.
Para ello utilizamos la rutina CLEAR LCD.
Para escribir en el LCD, utilizamos el registro de Acarreo (ACC). Insertamos en él el caracter
a escribir y utilizamos la rutina WRITE LCD para escr¡bir por pantalla.
4.3.
Montaje del teclado
Para simplificar la práctica hemos decidido utilizar un conjunto de interruptores como teclado
del cronómetro. La forma de tratar el teclado es una interrupción externa al micro (INT0).
Debemos tener en cuenta que se pueden producir rebotes en el teclado, por tanto, si se produce
una interrupcion externa (INT0 activada) debemos realizar un bucle escaneando los puertos y ni
salir de ahi hasta que uno de ellos sea el que ha realizado la interrupción.
5.
Manejo del Cronómetro
Tanto si se maneja con el PC como con el teclado, el cronómetro debe obedecer a las siguientes
interrupciones:
Start / Stop
Parada
Cambio
Reset
Tiempo Principal
Tiempo Parcial 1
Tiempo Parcial 2
5
MANEJO DEL CRONÓMETRO
9
Tiempo Parcial 3
El programa consiste en: poner todos los registros que se utilizarán a cero y preparar los contadores, y esperar a que se produzcan las interrupciones.
5.1.
Interrupción de Start / Stop
Es la que activa y desactiva el contador de la cuenta con la que se está trabajando.
Si estaba activada, el contador se detiene y se muestra por LCD o por PC el valor en el que se ha
detenido la cuenta (horas:minutos:segundos:centésimas). Si estaba parada, se activa y se muestra
la cuenta por LCD o PC.
Esta interrupción no hace que se modifiquen los tiempos parciales de la cuenta.
5.2.
Interrupción de Parada Parcial y Almacenamiento
Detiene el tiempo que se irá mostrando y lo almacena en los tiempos parciales, pero no detiene
el contador. Esto quiere decir que podemos retener un tiempo parcial en la pantalla sin afectar a
la cuenta total del cronómetro.
5.3.
Interrupción de Cambio de Cuenta
Cambia la cuenta activa y pasa a mostrar su tiemp principal en la pantalla del PC o en el LCD.
5.4.
Interrupción de Reset
Pone a cero el tiempo principal de la cuenta con la que estamos trabajando, pero no modifica
sus tiempos parciales.
También debe reiniciar el contador a D8F0 para empezar a contar bien. Si la cuenta estaba
funcionando, es decir, contando, seguira haciendolo, pero si estaba parada, permanecerá a cero
hasta que se pulse el Start.
5.5.
Interrupción de Tiempo Principal y Tiempos Parciales
Se pide que se muestre el tiempo principal de la cuenta con la que se está trabajando o que se
muestre alguno de los tres tiempos parciales de la cuenta.
En el caso de tener que mostrar el tiempo principal, si el cronómetro estaba activo, es decir,
contando, habrá que realizar dos muestreos del tiempo por si entre medias se cambia de centésima
(lo que puede acarrear un cambio de segundo, minuto y hora).
Por tanto, lo primero que miraremos serán las centésimas, despues los segundos, minutos y
horas, y por último volveremos a mirar las centésimas. Si no han cambiado, ya tenemos el valor
correcto. Si han cambiado, se volverán a tomar todos los tiempos, operacion que lleva menos
tiempo que la cuenta de otra centésima, con lo que esta vez estaremos seguros de que los tiempos
son correctos.
5.6.
Interrupción del Contador
Cuando el contador alcance una centésima, se producirá una interrupción y debemos incrementar las centésimas de la cuenta correspondiente, Si ya hay 100, deberemos ponerlas a cero e
6
COMENTARIOS PERSONALES
10
incrementar los segundos. A su vez, si hay 60 segundos, los pondremos a cero e incrementaremos
los minutos, y ası́ sucesivamente. Como ya hemos dicho, contaremos hasta 99 horas y luego los
pondremos a cero.
6.
Comentarios Personales
Esta práctica se ha realizado con serias dificultades debido al escaso nivel para realizarla tanto
en lo teórico, como en los circuitos fı́sicos que tenemos.
Sin embargo, utilizando todos los medios disponibles, hemos conseguido suficiente documentación para hacer la práctica. No obstante seguimos pensando que el nivel que tenemos es bajo.
Pensamos que se deberı́an mejorar algunos aspectos referidos, tanto a la asignatura, como a la
práctica:
Se deberı́a entregar un guion de práctica para tener claro los requisitos que se piden en ella.
Se deberı́an realizar más ejercicios sobre microcontroladores.
Convendrı́a explicar todo lo referido a los microcontroladores. No sólo a nivel fı́sico, sino
también a nivel de programación.
Se propone facilitar al alumno la documentación dada en clase, ejemplos y material de estudio
(ejercicios, exámenes, etc. . . )
Nada más, sólo agradecer la respuesta a todas nuestras dudas por mail tan rápida y eficazmente.
7.
Bibliografı́a
La información que hemos utilizado para realizar la práctica ha sido la siguiente:
Página Web www.8052.com
Página Web www.National.com (National Semiconductors)
Página Web www.ti.com (Texas Instruments)
Curso de Microcontroladores (Dr. Alejandro Vega Salinas)
Introducción al Microcontrolador 8051 (Facultad de Granada)
Apuntes de Diseño con Microcontroladores (Facultad Politécnica de Madrid)
8
8.
CÓDIGO DEL PROGRAMA
Código del Programa
EL código del programa es el siguiente:
; Contador de interrupciones
TICKS0 EQU 3Eh
TICKS1 EQU 3Fh
; Tiempo del crono 0
Horas0 EQU 40h
Minut0 EQU 41h
Segus0 EQU 42h
Cente0 EQU 43h
; 3 Tiempos parciales del crono 0
Horas0_1 EQU 44h
Minut0_1 EQU 45h
Segus0_1 EQU 46h
Cente0_1 EQU 47h
Horas0_2 EQU 48h
Minut0_2 EQU 49h
Segus0_2 EQU 4Ah
Cente0_2 EQU 4Bh
Horas0_3 EQU 4Ch
Minut0_3 EQU 4Dh
Segus0_3 EQU 4Eh
Cente0_3 EQU 4Fh
; Tiempo del crono 1
Horas1 EQU 50h
Minut1 EQU 51h
Segus1 EQU 52h
Cente1 EQU 53h
; 3 Tiempos parciales del crono 1
Horas1_1 EQU 54h
Minut1_1 EQU 55h
Segus1_1 EQU 56h
Cente1_1 EQU 57h
Horas1_2 EQU 58h
Minut1_2 EQU 59h
Segus1_2 EQU 5Ah
Cente1_2 EQU 5Bh
Horas1_3 EQU 5Ch
Minut1_3 EQU 5Dh
Segus1_3 EQU 5Eh
Cente1_3 EQU 5Fh
;****TIEMPO GENERAL PARA EL ENVIO****
Horas EQU 60h
Minut EQU 61h
Segus EQU 62h
Cente EQU 63h
;************************************
;Datos para el LCD
DB0 EQU P1.0
DB1 EQU P1.1
DB2 EQU P1.2
11
8
CÓDIGO DEL PROGRAMA
DB3 EQU P1.3
DB4 EQU P1.4
DB5 EQU P1.5
DB6 EQU P1.6
DB7 EQU P1.7
EN EQU P2.7
RS EQU P2.6
RW EQU P2.5
DATA EQU P1
ORG 0000h
LJMP Inicio
;
;
;
;
;
;
;
;
;
Registros utilizados
r0 -> Indica si el contador 0 esta activo
r1 -> Indica si el contador 1 esta activo
r2 -> Indica que contador se esta utilizando
r3 -> Indica si hay que ir actualizando el display
r4 -> Indica si trabajamos con PC (1) o con teclado (0)
r5 -> Indica cual de los 8 tpos anteriores hay que mostrar
r6 y r7 registros temporales
r8 y r9 -> para enviar numeros al LCD
; Vectores de interrupcion
ORG 0003h
LJMP ITeclado
ORG 000Bh
LJMP ITemp0
ORG 0013h
LJMP ISerie
ORG 001Bh
LJMP ITemp1
;INT0
;T0
;INT1
;T1
Inicio:
CLR r0
; ponemos a cero los registros que utilizaremos
CLR r1
CLR r2
CLR r3
CLR r4
CLR r5
CLR r6
CLR r7
CLR r8
CLR r9
SETB EA
; activamos las interrupciones
SETB EX0
; y los temporizadores
SETB EX1
SETB ET0
SETB ET1
MOV TICKS0,#0
;Ponemos a 0 los TICKS
MOV TICKS1,#0
;Ponemos a 0 los TICKS
12
8
CÓDIGO DEL PROGRAMA
13
MOV TMOD,#22h
; Ponemos los contadores en modo 2
MOV TL0,#000h
; Ponemos en TIMER0 1 centesima de Sec
MOV TL1,#000h
; Ponemos en TIMER1 1 centesima de Sec
SETB ES ; Activamos la interrupcion del puerto Serie
; Aqui inicializamos las conexiones con el Puerto Serie y el LCD
; RUTINA DE INICIALIZACION DEL LCD**************************
INIT_LCD:
SETB EN
CLR RS
MOV DATA,#38h
CLR EN
LCALL WAIT_LCD
SETB EN
CLR RS
MOV DATA,#0Eh
CLR EN
LCALL WAIT_LCD
SETB EN
CLR RS
MOV DATA,#06h
CLR EN
LCALL WAIT_LCD
;RUTINA DE INICIALIZACION DEL PUERTO SERIE**********************
INIT_PS:
CLR SM0
;Pongo puerto Serie en Modo 1
SETB SM1
SETB T2MOD.2
; Ponemos modo 2 al contador
MOV TH2,#253
; TH1 = 256 - ((Crystal / 384) / Baud))
; siendo un cristal de 11.059MHz y queriendo una conexion de 19.200 Baudios
SETB SMOD
;activamos el modo PCON.7
SETB TR2
; EJECUTAMOS EL TIMER2!
;***********************PRINCIPAL***********************************
Ppral:
;Esperamos hasta que se produzca una interrupcion
;Las interrupciones se pueden producir por:
; el teclado
; los cronos
; el puerto serie
;Ya tenemos hecho la de los cronos y la del teclado.
;En el caso de interrupcion por los cronos:
;tenemos que mirar si el crono ha pedido congelacion o no
;en caso negativo tenemos que mirar que quieren que envie al LCD
; r3 -> Indica si hay que ir actualizando el display
; r4 -> Indica si trabajamos con PC (1) o con teclado (0)
; r5 -> Indica cual de los 8 tpos anteriores hay que mostrar
JMP PPral
; el bucle principal es solo una espera
8
CÓDIGO DEL PROGRAMA
ITemp0: ; Interrupcion del contador 0
INC TICKS0
CJNE TICKS0,#36,Sum10
RETI
Sum10:
MOV TICKS0,#0
;Ponemos a 0 los ticks
; Sumo 1 a las centesimas (esta activo, si no no habria interrupcion)
MOV r6,Cente0
INC r6
MOV Cente0,r6
CJNE r6,#100,ITemp0M
; Tengo que incrementar los segundos
MOV r6,#00h
; nuevo valor de las centesimas = 0
MOV Cente0,r6
MOV r6,Segus0
; incremento los segundos
INC r6
MOV Segus0,r6
CJNE r6,#60,ITemp0M
MOV r6,#00h
; nuevo valor de los segundos = 0
MOV Segus0,r6
MOV r6,Minut0
; incremento los minutos
INC r6
MOV Minut0,r6
CJNE r6,#60,ITemp0M
MOV r6,#00h
; nuevo valor de los minutos = 0
MOV Minut0,r6
MOV r6,Horas0
; incremento las horas
INC r6
MOV Horas0,r6
CJNE r6,#100,ITemp0M
; Cuento hasta 100 horas
MOV r6,#00h
MOV Horas0,r6
ITemp0M:; Veo si tengo que mostrar
CJNE r2,#00h,ITemp0F
; si no estamos usando este contador, acabar
CJNE r5,#00h,ITemp0F
; si no estamos mostrando el tiempo principal del contador, acabar
CJNE r3,#01h,ITemp0F
; si no hay que ir actualizando, acabar
LJMP MOSTRAR0
ITemp0F:RETI
ITemp1:
; Interrupcion del contador 1
INC TICKS1
CJNE TICKS1,#36,Sum11
RETI
Sum11:
MOV TICKS1,#0
14
8
CÓDIGO DEL PROGRAMA
; Sumo 1 a las centesimas (esta activo, si no no habria interrupcion)
MOV r6,Cente1
INC r6
MOV Cente1,r6
CJNE r6,#100,ITemp1M
; Tengo que incrementar los segundos
MOV r6,#00h
; nuevo valor de las centesimas = 0
MOV Cente1,r6
MOV r6,Segus1
; incremento los segundos
INC r6
MOV Segus1,r6
CJNE r6,#60,ITemp1M
MOV r6,#00h
; nuevo valor de los segundos = 0
MOV Segus1,r6
MOV r6,Minut1
; incremento los minutos
INC r6
MOV Minut1,r6
CJNE r6,#60,ITemp1M
MOV r6,#00h
; nuevo valor de los minutos = 0
MOV Minut1,r6
MOV r6,Horas1
; incremento las horas
INC r6
MOV Horas1,r6
CJNE r6,#100,ITemp1M
; Cuento hasta 100 horas
MOV r6,#00h
MOV Horas1,r6
ITemp1M:; Veo si tengo que mostrar
CJNE r2,#01h,ITemp1F
; si no estamos usando este contador, acabar
CJNE r5,#04h,ITemp1F
; si no estamos mostrando el tiempo principal del contador, acabar
CJNE r3,#01h,ITemp1F
; si no hay que ir actualizando, acabar
LJMP MOSTRAR4
ITemp1F:RETI
ITeclado:
CLR r4
; Trabajamos con teclado
JNB P0.0, StSt
; Esta pulsado Start/Stop
JNB P0.1, Parada
; Dejar de actualizar display cronometro
JNB P0.2, Cambio
; Cambio de contador
JNB P0.3, Reset
; Pulsado Reset
JNB P0.4, TPral
; Pulsado Tiempo Principal (Visualizar)
JNB P0.5, Parcial1
; Pulsado Tiempo Parcial 1 (Visualizar)
JNB P0.6, Parcial2
; Pulsado Tiempo Parcial 2 (Visualizar)
JNB P0.7, Parcial3
; Pulsado Tiempo Parcial 3 (Visualizar)
; Para los rebotes volvemos al inicio
LJMP ITeclado
MOSTRAR0:
MOV
MOV
MOV
; hay que hacer dos muestreos por si ha cambiado la se~
nal
Cente, Cente0
Segus, Segus0
Minut, Minut0
15
8
CÓDIGO DEL PROGRAMA
16
MOV Horas, Horas0
;Segundo muestreo: solo necesario si cambian las centesimas
MOV r6, Cente
MOV r7, Cente0
CJNE r6,r7,SMuest0
LJMP MOSTRAR
SMuest0:
; hay que volver a tomar los valores del contador 0 y ya seran definitivos
MOV Cente, Cente0
MOV Segus, Segus0
MOV Minut, Minut0
MOV Horas, Horas0
LJMP MOSTRAR
MOSTRAR1:
MOV Cente, Cente0_1
MOV Segus, Segus0_1
MOV Minut, Minut0_1
MOV Horas, Horas0_1
LJMP MOSTRAR
MOSTRAR2:
MOV Cente, Cente0_2
MOV Segus, Segus0_2
MOV Minut, Minut0_2
MOV Horas, Horas0_2
LJMP MOSTRAR
MOSTRAR3:
MOV Cente, Cente0_3
MOV Segus, Segus0_3
MOV Minut, Minut0_3
MOV Horas, Horas0_3
LJMP MOSTRAR
MOSTRAR4:
; hay que hacer dos muestreos por si ha cambiado la se~
nal
MOV Cente, Cente1
MOV Segus, Segus1
MOV Minut, Minut1
MOV Horas, Horas1
;Segundo muestreo: solo necesario si cambian las centesimas
MOV r6, Cente
MOV r7, Cente1
CJNE r6,r7,SMuest1
LJMP MOSTRAR
SMuest1:
; hay que volver a tomar los valores del contador 1 y ya seran definitivos
MOV Cente, Cente1
MOV Segus, Segus1
MOV Minut, Minut1
MOV Horas, Horas1
LJMP MOSTRAR
MOSTRAR5:
MOV Cente, Cente1_1
MOV Segus, Segus1_1
MOV Minut, Minut1_1
MOV Horas, Horas1_1
LJMP MOSTRAR
MOSTRAR6:
8
CÓDIGO DEL PROGRAMA
MOV Cente, Cente1_2
MOV Segus, Segus1_2
MOV Minut, Minut1_2
MOV Horas, Horas1_2
LJMP MOSTRAR
MOSTRAR7:
MOV Cente, Cente1_3
MOV Segus, Segus1_3
MOV Minut, Minut1_3
MOV Horas, Horas1_3
LJMP MOSTRAR
MOSTRAR:
; lo muestra por LCD o por Serie
JNB r4, LCD_TECL
LJMP X_SERIE
; Interrupcion de Start/Stop (no almacena)
StSt:
JNB r2.0 StSt0
LJMP StSt1
StSt0:
; estoy usando el contador 0
JNB TR0 Timer0a1
CLR TR0
; Desactivamos el Timer 0
LJMP StSt0a
Timer0a1:
SETB TR0
; Activamos el Timer 0
StSt0a: XRL r0, #01h
; Cambiamos su estado
XRL r3, #01h
; Hay/no hay que ir mostrando tiempos
MOV r5, #00h
; voy al contador principal del contador 0
LJMP MOSTRAR0
StSt1:
; estoy usando el contador 1
JNB TR1 Timer1a1
CLR TR1
; Desactivamos el Timer 1
LJMP StSt1a
Timer1a1:
SETB TR1
; Activamos el Timer 1
StSt1a: XRL r1, #01h
; Cambiamos su estado
XRL r3, #01h
; Hay/no hay que ir mostrando tiempos
MOV r5, #04h
; voy al contador principal del contador 0
LJMP MOSTRAR4
; Interrupcion de Parada parcial y almacenaje
; No deja de contar, solo de actualizar lo que muestra
Parada: CLR r3
; Dejo de actualizar la cuenta en pantalla
JNB r2.0, Parad0
LJMP Parad1
Parad0: ; Desplazo las cuentas parciales:
MOV Cente0_3, Cente0_2
MOV Segus0_3, Segus0_2
MOV Minut0_3, Minut0_2
17
8
18
CÓDIGO DEL PROGRAMA
SToma0:
SigoP0:
Parad1:
SToma1:
SigoP1:
MOV Horas0_3, Horas0_2
MOV Cente0_2, Cente0_1
MOV Segus0_2, Segus0_1
MOV Minut0_2, Minut0_1
MOV Horas0_2, Horas0_1
MOV Cente0_1, Cente0
MOV Segus0_1, Segus0
MOV Minut0_1, Minut0
MOV Horas0_1, Horas0
;Segundo muestreo: solo necesario si cambian las centesimas
MOV r6, Cente0
MOV r7, Cente0_1
CJNE r6,r7,SToma0
LJMP SigoP0
; hay que volver a tomar los valores del contador 0 y ya seran definitivos
MOV Cente0_1, Cente0
MOV Segus0_1, Segus0
MOV Minut0_1, Minut0
MOV Horas0_1, Horas0
MOV r5, #01h
; hay que mostrar el tiempo parcial 1 del contador 0
LJMP MOSTRAR1
; Desplazo las cuentas parciales:
MOV Cente1_3, Cente1_2
MOV Segus1_3, Segus1_2
MOV Minut1_3, Minut1_2
MOV Horas1_3, Horas1_2
MOV Cente1_2, Cente1_1
MOV Segus1_2, Segus1_1
MOV Minut1_2, Minut1_1
MOV Horas1_2, Horas1_1
MOV Cente1_1, Cente1
MOV Segus1_1, Segus1
MOV Minut1_1, Minut1
MOV Horas1_1, Horas1
;Segundo muestreo: solo necesario si cambian las centesimas
MOV r6, Cente1
MOV r7, Cente1_1
CJNE r6,r7,SToma1
LJMP SigoP1
; hay que volver a tomar los valores del contador 1 y ya seran definitivos
MOV Cente1_1, Cente1
MOV Segus1_1, Segus1
MOV Minut1_1, Minut1
MOV Horas1_1, Horas1
MOV r5, #05h
; hay que mostrar el tiempo parcial 1 del contador 1
LJMP MOSTRAR5
; Interrupcion de Cambio de Contador
Cambio:
XRL r2, #01h
; Cambiamos el contador activo
8
19
CÓDIGO DEL PROGRAMA
JNB r2.0, Cambio0
LJMP Cambio1
Cambio0:; esta activo el 0
MOV r3, r0
MOV r5, #00h
LJMP MOSTRAR0
Cambio1:; esta activo el 1
MOV r3, r1
MOV r5, #04h
LJMP MOSTRAR4
; Solo debe ir actualizandose si esta activo
; Trabajamos con el tiempo principal del contador 0
; Solo debe ir actualizandose si esta activo
; Trabajamos con el tiempo principal del contador 1
Reset:
; Miramos que cuenta esta activa
CJNE r2,#0,Reset1
Reset0:
MOV TL0,#0F0h
MOV TH0,#0D8h
CLR Horas0
CLR Minut0
CLR Segus0
CLR Cente0
MOV r3,r0
MOV r5,#00h
LJMP MOSTRAR0
; Ponemos en TIMER0 1 centesima de Sec
; Ponemos en TIMER0 1 centesima de Sec
MOV TL1,#0F0h
MOV TH1,#0D8h
CLR Horas1
CLR Minut1
CLR Segus1
CLR Cente1
MOV r3,r1
MOV r5,#04h
LJMP MOSTRAR4
; Ponemos en TIMER0 1 centesima de Sec
; Ponemos en TIMER0 1 centesima de Sec
; Actualizare si estaba activo
; Mostraremos el tiempo principal
Reset1:
TPral:
; Actualizare si estaba activo
; Mostraremos el tiempo principal
; Se ha solicitado mostrar el tiempo principal del contador
JNB r2.0, TPral0
LJMP TPral1
TPral0: ; Hay que mostrar el del contador 0
MOV r3,r0
; Hay que ir actualizando si esta activo
MOV r5,#00h
; Mostraremos el principal del contador 0
LJMP MOSTRAR0
TPral1: ; Hay que mostrar el del contador 1
MOV r3,r1
; Hay que ir actualizando si esta activo
MOV r5,#04h
; Mostraremos el principal del contador 1
LJMP MOSTRAR4
8
CÓDIGO DEL PROGRAMA
Parcial1:
; Se ha solicitado mostrar el tiempo parcial 1 del contador
JNB r2.0, TP1_0
LJMP TP1_1
TP1_0: ; Hay que mostrar el del contador 0
MOV r3,#00h
; No hay que actualizar
MOV r5,#01h
; Mostraremos el parcial 1 del contador 0
LJMP MOSTRAR1
TP1_1: ; Hay que mostrar el del contador 1
MOV r3,#00h
; No hay que actualizar
MOV r5,#05h
; Mostraremos el parcial 1 del contador 1
LJMP MOSTRAR5
Parcial2:
; Se ha solicitado mostrar el tiempo parcial 2 del contador
JNB r2.0, TP2_0
LJMP TP2_1
TP2_0: ; Hay que mostrar el del contador 0
MOV r3,#00h
; No hay que actualizar
MOV r5,#02h
; Mostraremos el parcial 2 del contador 0
LJMP MOSTRAR2
TP2_1: ; Hay que mostrar el del contador 1
MOV r3,#00h
; No hay que actualizar
MOV r5,#06h
; Mostraremos el parcial 2 del contador 1
LJMP MOSTRAR6
Parcial3:
; Se ha solicitado mostrar el tiempo parcial 3 del contador
JNB r2.0, TP3_0
LJMP TP3_1
TP3_0: ; Hay que mostrar el del contador 0
MOV r3,#00h
; No hay que actualizar
MOV r5,#03h
; Mostraremos el parcial 3 del contador 0
LJMP MOSTRAR3
TP3_1: ; Hay que mostrar el del contador 1
MOV r3,#00h
; No hay que actualizar
MOV r5,#03h
; Mostraremos el parcial 3 del contador 1
LJMP MOSTRAR7
;************************* RUTINAS DE LCD*************************
WAIT_LCD:
SETB EN
CLR RS
SETB RW
MOV DATA,#0FFh
MOV A,DATA
JB ACC.7,WAIT_LCD
20
8
CÓDIGO DEL PROGRAMA
CLR EN
CLR RW
RET
CLEAR_LCD:
SETB EN
CLR RS
MOV DATA,#01h
CLR EN
LCALL WAIT_LCD
RET
WRITE_TEXT:
SETB EN
SETB RS
MOV DATA,A
CLR EN
LCALL WAIT_LCD
RET
;*************************RUTINA GENERAL DE LCD*****************************
LCD_TECL: ;Ahora debo mirar que registro tengo que enviar al LCD
LCALL CLEAR_LCD
MOV r8,Horas
MOV r9,10
DIV r8 r9
; lo pasamos a base decimal: cociente queda en r8 y resto en r9
MOV A, r8
LCALL WRITE_TEXT
MOV A, r9
LCALL WRITE_TEXT
MOV A,#:
LCALL WRITE_TEXT
MOV r8,Minut
MOV r9,10
DIV r8 r9
; lo pasamos a base decimal: cociente queda en r8 y resto en r9
MOV A, r8
LCALL WRITE_TEXT
MOV A, r9
LCALL WRITE_TEXT
MOV A,#:
LCALL WRITE_TEXT
MOV r8,Segus
MOV r9,10
DIV r8 r9
; lo pasamos a base decimal: cociente queda en r8 y resto en r9
MOV A, r8
LCALL WRITE_TEXT
MOV A, r9
LCALL WRITE_TEXT
MOV A,#:
LCALL WRITE_TEXT
MOV r8,Cente
21
8
CÓDIGO DEL PROGRAMA
MOV r9,10
DIV r8 r9
; lo pasamos a base decimal: cociente queda en r8 y resto en r9
MOV A, r8
LCALL WRITE_TEXT
MOV A, r9
LCALL WRITE_TEXT
MOV A,#:
LCALL WRITE_TEXT
;***********************RUTINA GENERAL DE SERIE************************
X_SERIE:
;Aqui tengo que enviarlo por el puerto serie!
CLR
MOV
JNB
CLR
MOV
JNB
CLR
MOV
JNB
CLR
MOV
JNB
CLR
MOV
JNB
CLR
MOV
JNB
CLR
MOV
JNB
TI ;Limpiamos la transmision de interrupciones
SBUF,Horas ;Enviamos Horas por el puerto serie
TI,$ ;Esperamos hasta que se active la interrupcion.
TI
SBUF,#:
TI,$
TI ;Limpiamos la transmision de interrupciones
SBUF,Minut ;Enviamos Minutos por el puerto serie
TI,$ ;Esperamos hasta que se active la interrupcion.
TI
SBUF,#:
TI,$
TI ;Limpiamos la transmision de interrupciones
SBUF,Segus ;Enviamos Segundos por el puerto serie
TI,$ ;Esperamos hasta que se active la interrupcion.
TI
SBUF,#:
TI,$
TI ;Limpiamos la transmision de interrupciones
SBUF,Cente ;Enviamos Centesimas por el puerto serie
TI,$ ;Esperamos hasta que se active la interrupcion.
;*************************INTERRUPCION SERIE*****************************
; Ahora tenemos que tratar la interrupcion debido al puerto serie
ISerie:
JNB TI,INT_RI
;Si TI esta a 0 entonces RI esta a 1
;En el caso en que TI = 1
RETI
INT_RI: ; Realizamos la recepcion de Serie
MOV A,SBUF ;Leemos el caracter
CLR RI ; Ponemos a 0 la RI
;LOS CARACTERES QUE PUEDEN ENTRAR SON:***********
; S -> Start/Stop
; P -> Parada
; C -> Cambio
; R -> Reset
22
8
CÓDIGO DEL PROGRAMA
; L -> Principal
; 1 -> Parcial 1
; 2 -> Parcial 2
; 3 -> Parcial 3
;************************************************
CJNE A,#’S’,Mir_P ; Si no es S miramos el siguiente (que es P)
;Si es S tenemos que activar la vuelta X_SERIE y llamar a Start_Stop
SETB r4 ; Vamos por PC
LJMP StSt; Saltamos a Start_Stop
Mir_P:
CJNE A,#’P’,Mir_C ; Si no es P miramos el siguiente (que es C)
;Si es P tenemos que activar la vuelta X_SERIE y llamar a Pausa
SETB r4 ; Vamos por PC
LJMP Parada; Saltamos a Parada
Mir_C:
CJNE A,#’C’,Mir_R ; Si no es C miramos el siguiente (que es R)
;Si es C tenemos que activar la vuelta X_SERIE y llamar a Cambio
SETB r4 ; Vamos por PC
LJMP Cambio; Saltamos a Cambio
Mir_R:
CJNE A,#’R’,Mir_L ; Si no es R miramos el siguiente (que es L)
;Si es R tenemos que activar la vuelta X_SERIE y llamar a Reset
SETB r4 ; Vamos por PC
LJMP Reset; Saltamos a Reset
Mir_L:
CJNE A,#’L’,Mir_1; Si no es L nos vamos
;Si es L tenemos que activar la vuelta X_SERIE y llamar a Principal
SETB r4 ; Vamos por PC
LJMP TPral; Saltamos a mostrar el tiempo principal
Mir_1:
CJNE A,#’1’,Mir_2 ; Si no es 1 nos vamos
SETB r4 ; Vamos por PC
LJMP Parcial1; Saltamos a mostrar el parcial 1
Mir_2:
CJNE A,#’2’,Mir_3 ; Si no es 2 nos vamos
SETB r4 ; Vamos por PC
LJMP Parcial2; Saltamos a mostrar el tiempo principal
Mir_3:
CJNE A,#’3’,No_Hay ; Si no es 3 nos vamos
SETB r4 ; Vamos por PC
LJMP Parcial3; Saltamos a mostrar el tiempo principal
No_Hay:
RETI
23
Descargar