VI-a) DESCRIPCIÓN DE "METEO"
METEO es un sistema de estación meteorológica controlada por PC y basada en el microcontrolador ST62E15 de SGS-THONSOM. METEO es capaz de llevar un control de temperaturas, presiones y dirección del viento además de poder llevar un registro exhaustivo (mediante spoiler de datos a un fichero ASCII) de todas las temperaturas.
Se puede dividir a METEO en dos partes, el programa de control del PC y la placa de adquisición de datos y registro de los mismos.
El PC por tener una mayor capacidad de
calculo se encarga de la visualización de datos en sus
escalas correctas y del registro en fichero, además de
ir ordenando a la placa de adquisición de datos el envió
de los mismos. La presentación de los datos la realiza
sobre una pantalla de presentación en la que además
se pueden elegir todas las opciones disponibles. La pantalla la
podemos observar en la FIG 6.1. Este programa ha sido realizado
en Qbasic de Microsoft
Dentro de ella podemos distinguir varias partes.
La parte central dedicada a la veleta, en ella se muestra el estado actual de la veleta mediante un flecha.
La esquina superior izquierda esta dedicada a la temperatura, en ella se muestra la temperatura actual, las temperaturas máximas y mínimas registradas por el microcontrolador, y la temperatura media determinada por la suma de los valores de temperatura actual entre en nº de muestreos realizados desde la ultima conexión del programa de visualización. Los datos presentados están en grados centígrados.
La esquina inferior izquierda esta dedicada
a las presiones, funcionando de manera similar al termómetro
exceptuando que no presenta la presión media. Las unidades
utilizadas son los Bares.
En la ultima línea del lado izquierdo se visualiza el nombre del programa así como su versión.
La esquina superior derecha esta dedicada a la gráfica de temperatura, esta gráfica se compone mediante los datos leídos de temperatura actual.
La parte central de la columna derecha muestra la hora y la fecha actual tomados directamente del reloj del sistema del PC.
La parte inferior derecha muestra el
menú de opciones seleccionables mediante las teclas de
función del teclado, las opciones disponibles son las siguientes:
F1: ACERCA DE .. :
Muestra la versión del programa así como el nombre
de los programadores (FIG 6.2), se vuelve a la pantalla de control
mediante la pulsación de cualquier tecla.
F2: CONFIGURAR: Con esta opción primero se seleccionara el puerto de trabajo, una vez seleccionado se mostraran las direcciones del puerto, a continuación se configurara el tipo de ordenador pudiendo elegir entre un 8086, un 80386 y un 80486, después se elegirá el intervalo con el cual se realizara el traspaso de datos de temperatura entre 1 segundo a 24h introduciendo el tiempo en segundos, después se reiniciará el programa.
F3: SALIR AL DOS: Con esta opción se vuelve al símbolo del sistema.
Descripción de ficheros que deben existir en el directorio de trabajo.
METEO.EXE Es el fichero del programa
METEO.CFG Es el fichero de configuración
METEO.DAT Es le fichero en el que
se guardan los datos del spoiler de temperaturas.
La placa de adquisición de datos y por lo tanto el ST6, se encarga de tomar los datos de los sensores de temperatura y presión que son valores analógicos y de convertirlos en valores digitales, después de esta conversión se encarga de determinar si estos datos son mínimos o máximos y en caso de cumplir una de esas dos condiciones los almacena en sus registros correspondientes, así mismo adquiere la posición de la veleta. EL ST6 a su vez se encarga de mandar los datos a medida que el PC los requiere.
La placa del ST6 es capaz de trabajar independientemente del PC llevando un control de la tempereraturas y presiones máximas y mínimas además de las actuales. El programa para el PC es incapaz de funcionar sin la estación meterologica conectada.
VI-b) Esquemas y explicación del circuitoVI-b) Esquemas y explicación del circuito
El esquema de la estación metereologica se puede dividir en varias partes diferentes:
- Fuente de alimentación
- Adaptadores de tensión de los sensores
- Zona de transferencia de datos
- Microcontrolador.
La fuente de alimentación tiene como función el estabilizar y limitar la tensión que puede recibir el ST6, esta etapa debe de alimentarse con tensión continua de por lo menos 8 V por que es la tensión mínima para que funcione correctamente el 7805.
Los adaptadores para los sensores tienen como función la de dividir entre dos la tensión entregada por estos, esto debe realizarse por que los sensores entregan tensión entre 0 y 10V y el ST6 solo puede convertir hasta 5V.
La zona de transferencia de datos esta constituida por los buffers 74LS245, estos buffers tienen como función la de proteger al ST6 y al puerto Paralelo del ordenador frente de posibles averías, la conexión al PC se realiza mediante un conector de 25 patillas.
El microcontrolador se encarga de la conversión y adquisición de datos así como de llevar el control de temperaturas y presiones máximas y mínimas, así como las comunicaciones con el PC. El microcontrolador lleva un circuito de Reset que se activa la aplicar la alimentación, así como su correspondiente circuito oscilador a 8 Mhz.
Los faston nombrados como PA7 y PA6 tienen como función adquirir los datos analógicos, los PC4, PC5 y PC6 tienen como función la adquisición de los datos de la veleta.
El esquema completo y los fotolitos de
circuito impreso se encuentran en las páginas siguientes.
VI-c) SISTEMA DE COMUNICACIONESVI-c) SISTEMA DE COMUNICACIONES
VI-c,I) PROBLEMAS Y SOLUCIONES VI-c,I) PROBLEMAS Y SOLUCIONES :
La estación metereológica se comunica a través del puerto paralelo CENTRONICS del PC. Se plantea entonces el problema de que el puerto paralelo es unidireccional (salida del PC). El puerto paralelo consta de 3 registros uno de datos, uno de control y otro de estado. El registro de datos tiene asociadas 8 líneas que son las de salida de datos. El de estado tiene asociadas 6 líneas una de salida y 5 de entrada. El de control nosotros no lo utilizaremos. Las 8 líneas de salida de datos son unidireccionales por lo tanto se plantea el problema de hacer que el PC pueda recibir datos. La única manera de conseguirlo sería enviarle los datos a través de las líneas de estado, esto nos lleva a un nuevo problema, que sólo existen 5 líneas de estado, tendremos entonces que enviar los datos de 4 en 4 bits y la línea que sobra la utilizaremos para indicar "dato listo" al PC, los bits del registro de estado donde se encontraran los datos enviados por la estación son los 4 de mayor peso, y el que indica dato listo es el bit 3. Existe el problema también de que el PC lee del registro el bit 6 invertido de su valor lógico por lo tanto había que invertirlo, de esto se encarga el programa ensamblador del ST6. El PC enviará datos a la estación sólo con los 4 bits de menor peso de las líneas de datos, no se utilizan las otras 4 ya que no son necesarias debido al protocolo de comunicaciones establecido. Para indicar el PC a la estación su requerimiento de datos se utiliza la línea STROBE que se controla mediante un bit del registro de estado del puerto paralelo.
VI-c,II) DESCRIPCION DEL SISTEMA DE PROTOCOLO VI-c,II) DESCRIPCION DEL SISTEMA DE PROTOCOLO :
Nada mas conectarse la alimentación a la estación metereológica el ST6 entra en un bucle de 5 segundos para conseguir que las sondas de temperatura y presión estén ya estabilizadas para cuando se vaya a iniciar la conversión. Después de ese ciclo de 5 segundos el MCU entra en un bucle cerrado de espera de interrupción, mientras en ese bucle el MCU está realizando las conversiones oportunas y llevándolas a posiciones de memoria, también está determinando las temperaturas y presiones máximas y mínimas. El PC entonces será capaz de interrumpir al ST6 para pedir la información que necesite. El programa del PC sólo interrumpirá al MCU si este le indica que está permitido y para indicarlo lo que hace es enviar un 5h a la entrada del PC. El programa del PC comprueba que ese 5h existe y si existe saca por su bus de datos el código correspondiente a la información que quiere, Después interrumpe al ST6 mediante la línea STROBE. Una vez que el ST6 ha sido interrumpido saca un 0 a la salida para que el PC sepa que no puede volver a interrumpirle. El PC espera entonces a que la línea de "dato listo" se active para saber que los 4 bits de mayor peso están en la entrada, cuando esta línea es activada por el ST6 el PC recoge los datos de la entrada y saca un 08h al bus de datos para indicar que ha recogido el dato. Cuando el ST6 detecta ese 08h desactiva la línea de "dato listo" y saca los 4 bits de menor peso y vuelve a activar "dato listo", el PC estaba esperando de nuevo esta señal y una vez detectada recoge el dato.
Una vez que se ha recogido el dato el PC saca a la salida un 09h para indicar al ST6 que se ha recibido el dato de parte baja. El ST6 cuando detecta el 09h retorna de la interrupción al programa principal y saca de nuevo a la salida un 05h para indicar que esta listo para ser interrumpido nuevamente. En el caso de la veleta se manda el estado de la veleta en un sólo nibble ya que ese dato es de tan sólo 3 bits.
Tabla de códigos de comunicaciones :
PC ----> ST6
CÓdigo | DESCRIPCION DE CODIGO |
01h | Temperatura Actual |
02h | Presión Actual |
03h | Veleta |
04h | Temperatura mínima |
05h | Temperatura máxima |
06h | Presión mínima |
07h | Presión máxima |
08h | Dato recibido (parte alta) |
09h | Dato recibido (parte baja) |
ST6 ----> PC
Código | DESCRIPCION DEL CODIGO |
05h | ST6 puede ser interrumpido |
00h | ST6 no puede se interrumpido |
VI-d,I) PROGRAMA BASIC PARA "METEO"
VI-d,I) PROGRAMA BASIC PARA METEO :
LISTADO DEL PROGRAMA . . .
REM ************************************************************************
REM ************* *************
REM ************* PROYECTO DE PRACTICAS PARA ST6 5.C. 1994 *************
REM ************* *************
REM ************************************************************************
REM ****** ********
REM ****** José Ignacio Díaz Beamud & Jesús Antonio Alquezar Sierra ********
REM ****** ********
REM ****** Estación meteorológica por ST6 controlada por PC ********
REM ****** ********
REM ************************************************************************
REM **************************************** INICIO PROGRAMA ****************
ON ERROR GOTO er: REM **** Activa la detección de error por si no hay conf.
KEY(2) STOP: REM **** Desactiva momentaneamente
la F2
temmed = 0: REM **** Temperatura media = 0
media = 1: REM **** Datos de temperatura cogida = 1
ero = 0
REM **************** Borra fichero METEO.DAT
y lo crea nuevo ****************
propri:
OPEN "METEO.DAT" FOR OUTPUT AS #3
PRINT #3, ""
CLOSE #3
REM *********************************
Crea fichero temperaturas *************
OPEN "METEO.DAT" FOR OUTPUT AS #3
PRINT #3, ""
PRINT #3, "Control de Datos de Temperatura **** METEO.EXE V5.00 **** "
PRINT #3, ""
PRINT #3, "Temp. Actual Hora Máxima Mínima Media"
PRINT #3, " "
PRINT #3, ""
REM **********************************
Lee fichero de configuración *********
OPEN "METEO.CFG" FOR INPUT AS #2
INPUT #2, dato%: REM **** Lee dirección de puerto de LPT (datos)
INPUT #2, esta%: REM **** Lee dirección de estado
INPUT #2, ctrl%: REM **** Lee dirección de control
INPUT #2, equi: : REM **** Lee tipo de equipo
INPUT #2, tifi%: : REM **** Lee tiempo de escritura en fichero
CLOSE #2: REM **** Cierra fichero
OUT (dato%), 0
comin:
GOSUB pontem: REM **** Va a determinar
las variables de temporizador
CLS
SCREEN 2
PRINT "METEO.EXE V5.00 23MAYO1994"
LOCATE 10, 1
PRINT " Estacion meteorologica por ST6 controlada por PC"
PRINT : PRINT
PRINT " por Jose Ignacio
Diaz Beamud & Jesus Antonio Alquezar Sierra"
REM ***************************************
Hace efecto pantalla inicial ****
FOR x = 25 TO 620
LINE (25, 107)(x, 107)
FOR temporiza = 1 TO linei: NEXT temporiza
NEXT x
FOR x = 620 TO 25 STEP 1
LINE (620, 109)(x, 109)
FOR temporiza = 1 TO linei: NEXT temporiza
NEXT x
FOR t = 1 TO 10
FOR r = 1 TO 15
CIRCLE (620, 107), r
FOR temporiza = 1 TO circi: NEXT temporiza
NEXT r
FOR r = 1 TO 15
CIRCLE (620, 107), r, 0
FOR temporiza = 1 TO circi: NEXT temporiza
NEXT r
NEXT t
REM ***************************************
Fin de efecto *******************
CLS
SCREEN 2
LOCATE 25, 66: PRINT "PROYECTO ST6"
LOCATE 25, 2: PRINT "METEO.EXE V5.00"
LINE (150, 3)(490, 195), , B: REM
** CREA EL RECUADRO DE VELETA ***
REM *********************************
DIBUJA LA N DE NORTE ***********
LINE (300, 50)(300, 40)
LINE (300, 40)(340, 50)
LINE (340, 50)(340, 40)
REM ***************************************************************
REM ****************************** DIBUJA
LA S DE SUR *************
LINE (340, 160)(300, 160)
LINE (340, 160)(340, 155)
LINE (340, 155)(300, 155)
LINE (300, 155)(300, 150)
LINE (300, 150)(340, 150)
REM ***************************************************************
REM ****************************** DIBUJA
LA E DE ESTE ************
LINE (440, 95)(440, 105)
LINE (440, 95)(480, 95)
LINE (440, 105)(480, 105)
LINE (440, 100)(480, 100)
REM ***************************************************************
REM ****************************** DIBUJA
LA O DE OESTE ***********
LINE (200, 95)(200, 105)
LINE (200, 105)(160, 105)
LINE (160, 105)(160, 95)
LINE (160, 95)(200, 95)
REM ***************************************************************
REM ***********************************
RECUADRO DE TEMPERATURA ***
LINE (1, 3)(140, 100), , B
LOCATE 1, 4: PRINT " Termometro "
LOCATE 4, 2: PRINT " Temp : 00.0C"
LOCATE 6, 2: PRINT " Max : 00.0C"
LOCATE 8, 2: PRINT " Min : 00.0C"
LOCATE 10, 2: PRINT " Med : 00.0C"
REM ***************************************************************
REM ***********************************
RECUADRO DE PRESION ******
LINE (1, 108)(140, 190), , B
LOCATE 14, 4: PRINT " Manometro "
LOCATE 17, 2: PRINT "Pres : 00 B."
LOCATE 19, 2: PRINT "Max : 00 B."
LOCATE 21, 2: PRINT "Min : 00 B."
REM ***************************************************************
REM ***********************************
RECUADRO GRAFICA TEMP. ****
xgraf = 516
LINE (500, 3)(639, 50), , B
LOCATE 1, 65: PRINT " Grafica Temp. "
LOCATE 2, 64: PRINT "C"
LINE (515, 10)(515, 45)
LINE (515, 45)(630, 45)
REM ***************************************************************
REM ***********************************
RECUADRO DE RELOJ *********
LINE (500, 60)(639, 110), , B
LOCATE 8, 68: PRINT " Reloj "
LOCATE 10, 65: PRINT "Hora : 00:00:00"
LOCATE 12, 65: PRINT "Dia: 00000000"
REM ******************************************
Menu ***************
LINE (500, 123)(639, 190), , B
LOCATE 16, 69: PRINT " Menu "
LOCATE 18, 65: PRINT "F1 ACERCA DE.."
LOCATE 19, 65: PRINT "F2 CONFIGURAR "
LOCATE 20, 65: PRINT "F3 SALIR A DOS"
LOCATE 22, 66: PRINT "por J.I.DIAZ"
LOCATE 23, 65: PRINT "y J.A.ALQUEZAR"
REM **************************** DIBUJA EL CONTORNO DE LA VELETA **
LOCATE 1, 24: PRINT " Veleta de Estacion Meteorologica "
FOR N = 1 TO 100
CIRCLE (320, 100), N
FOR temporiza = 1 TO circv: NEXT temporiza
NEXT N
FOR N = 1 TO 90
CIRCLE (320, 100), N, 0
FOR temporiza = 1 TO circv: NEXT temporiza
NEXT N
REM ************************ Abilita
interrupciones de teclas de funcion ***
KEY(3) ON
ON KEY(3) GOSUB f3
KEY(1) ON
ON KEY(1) GOSUB f1
KEY(2) ON
ON KEY(2) GOSUB f2
REM ***********************************
Pido a ST6 temperatura máxima *******
tam:
l6 = INP(esta%)
listost6 = l6 AND 8
IF listost6 <> 8 THEN GOTO tam
dst6 = l6 AND 240
IF dst6 = 80 THEN GOTO sitam
GOTO tam
REM ***********************************
Parte alta de temperatura max. ****
sitam:
OUT (dato%), 5: REM **** Pido código Temperatura Máxima
GOSUB STROBE: REM **** Interrumpo a ST6
GOSUB datemp
esptam:
l6 = INP(esta%): REM **** Entra datos de ST6
listost6 = l6 AND 8: REM **** Determina si el dato de ST6 está listo
IF listost6 <> 8 THEN GOTO esptam: REM **** Si no esta espera
dtac = INP(esta%)
dtacalta = (dtac AND 240): REM **** Parte alta de Temperatura Máxima
OUT (dato%), 8: REM **** Indico
que ya he recibido el dato
REM ******************************** Parte Baja de Temperatua Máxima ********
GOSUB datemp
pe3:
l6 = INP(esta%): REM **** Entra datos de ST6
listost6 = l6 AND 8: REM **** Determina si el dato de ST6 está listo
IF listost6 <> 8 THEN GOTO pe3: REM **** Si no esta espera
dtac = INP(esta%)
dtacbaja = (dtac AND 240) / 16: REM **** Parte Baja de Temperatura
OUT (dato%), 9: REM **** Indico
que ya he recibido el dato
temmax = ((dtacalta + dtacbaja) * .01953) * 20: REM **** Calcula
LOCATE 6, 9: PRINT USING "###.##"; temmax: REM ** Limita present.
LOCATE 6, 16: PRINT "C
"
REM ***********************************
Pido a ST6 temperatura mínima *******
tam2:
l6 = INP(esta%)
listost6 = l6 AND 8
IF listost6 <> 8 THEN GOTO tam2
dst6 = l6 AND 240
IF dst6 = 80 THEN GOTO sitam2
GOTO tam2
REM ***********************************
Parte alta de temperatura min. ****
sitam2:
OUT (dato%), 4: REM **** Pido código Temperatura Mínima
GOSUB STROBE: REM **** Interrumpo a ST6
GOSUB datemp
esptam2:
l6 = INP(esta%): REM **** Entra datos de ST6
listost6 = l6 AND 8: REM **** Determina si el dato de ST6 está listo
IF listost6 <> 8 THEN GOTO esptam2: REM **** Si no esta espera
dtac = INP(esta%)
dtacalta = (dtac AND 240): REM **** Parte alta de Temperatura Mínima
OUT (dato%), 8: REM **** Indico que ya he recibido el dato
REM ******************************** Parte Baja de Temperatua Mínima ********
GOSUB datemp
pe32:
l6 = INP(esta%): REM **** Entra datos de ST6
listost6 = l6 AND 8: REM **** Determina si el dato de ST6 está listo
IF listost6 <> 8 THEN GOTO pe32: REM **** Si no esta espera
dtac = INP(esta%)
dtacbaja = (dtac AND 240) / 16: REM **** Parte Baja de Temperatura
OUT (dato%), 9: REM **** Indico
que ya he recibido el dato
temmin = ((dtacalta + dtacbaja) * .01953) * 20: REM **** Calcula
LOCATE 8, 9: PRINT USING "###.##"; temmin: REM ** Limita present.
LOCATE 8, 16: PRINT "C
"
REM *********************************************
Pide de Presión Máxima ****
pa2:
l6 = INP(esta%)
listost6 = l6 AND 8
IF listost6 <> 8 THEN GOTO pa2
dst6 = l6 AND 240
IF dst6 = 80 THEN GOTO siesta31
GOTO pa2
REM ***************************************
Parte alta de Presión Máxima ****
siesta31:
OUT (dato%), 7: REM **** Pido código Presión Máxima
GOSUB STROBE: REM **** Interrumpo a ST6
GOSUB datemp
espe41:
l6 = INP(esta%): REM **** Entra datos de ST6
listost6 = l6 AND 8: REM **** Determina si el dato de ST6 está listo
IF listost6 <> 8 THEN GOTO espe41: REM **** Si no esta espera
pac = INP(esta%)
pacalta = (pac AND 240): REM **** Parte alta de Presión Máxima
OUT (dato%), 8: REM **** Indico que ya he recibido el dato
REM *********************************** Parte Baja de Presión Máxima ********
GOSUB datemp
espe51:
l6 = INP(esta%): REM **** Entra datos de ST6
listost6 = l6 AND 8: REM **** Determina si el dato de ST6 está listo
IF listost6 <> 8 THEN GOTO espe51: REM **** Si no esta espera
pac = INP(esta%)
pacbaja = (pac AND 240) / 16: REM **** Parte Baja de Presión Máxima
OUT (dato%), 9: REM **** Indico
que ya he recibido el dato
premax = (((pacalta + pacbaja) * .019) * 2) / 5: REM **** Calcula
LOCATE 19, 9: PRINT USING "#.###"; premax: REM *** Limita presenta.
LOCATE 19, 15: PRINT "B. "
REM *********************************************
Pide de Presión Mínima ****
pa3:
l6 = INP(esta%)
listost6 = l6 AND 8
IF listost6 <> 8 THEN GOTO pa3
dst6 = l6 AND 240
IF dst6 = 80 THEN GOTO siesta32
GOTO pa3
REM ***************************************
Parte alta de Presión Mínima ****
siesta32:
OUT (dato%), 6: REM **** Pido código Presión Mínima
GOSUB STROBE: REM **** Interrumpo a ST6
GOSUB datemp
espe42:
l6 = INP(esta%): REM **** Entra datos de ST6
listost6 = l6 AND 8: REM **** Determina si el dato de ST6 está listo
IF listost6 <> 8 THEN GOTO espe42: REM **** Si no esta espera
pac = INP(esta%)
pacalta = (pac AND 240): REM **** Parte alta de Presión Mínima
OUT (dato%), 8: REM **** Indico que ya he recibido el dato
REM *********************************** Parte Baja de Presión Mínima ********
GOSUB datemp
espe52:
l6 = INP(esta%): REM **** Entra datos de ST6
listost6 = l6 AND 8: REM **** Determina si el dato de ST6 está listo
IF listost6 <> 8 THEN GOTO espe52: REM **** Si no esta espera
pac = INP(esta%)
pacbaja = (pac AND 240) / 16: REM **** Parte Baja de Presión Actual
OUT (dato%), 9: REM **** Indico
que ya he recibido el dato
premin = (((pacalta + pacbaja) * .019) * 2) / 5: REM **** Calcula
LOCATE 21, 9: PRINT USING "#.###"; premin: REM *** Limita presenta.
LOCATE 21, 15: PRINT "B. "
REM *************************************
Activa el timer para fichero *****
TIMER ON
ON TIMER(tifi%) GOSUB fiche
REM ************************************************************************
REM **************** ********************
REM **************** Programa de salida de datos (HORA) ********************
REM **************** ********************
REM ************************************************************************
rep:
t$ = TIME$
d$ = DATE$
LOCATE 10, 72: PRINT t$
LOCATE 12, 70: PRINT d$
GOSUB lisinter
GOTO rep
REM *************************************************************************
REM ********************** Subrutina de COMUNICACIONES **********************
REM *************************************************************************
lisinter:
l6 = INP(esta%)
listost6 = l6 AND 8
IF listost6 <> 8 THEN RETURN: REM **** Testea bit de listo
dst6 = l6 AND 240
IF dst6 = 80 THEN GOTO siesta:
RETURN: REM **** Comprueba
que se puede interrumpir a ST6
REM *********************************************
Pido dato de veleta ******
siesta:
OUT (dato%), 3: REM **** Pido código veleta
GOSUB STROBE: REM **** Interrumpo a ST6
GOSUB datemp
espe1:
l6 = INP(esta%): REM **** Entra datos de ST6
listost6 = l6 AND 8: REM **** Determina si el dato de ST6 está listo
IF listost6 <> 8 THEN GOTO espe1: REM **** Si no esta espera
dv = INP(esta%)
datovel = (dv AND 240) / 16
OUT (dato%), 8
GOSUB dibujavel
REM *****************************************
Pide de Temperatura Actual ****
ta:
l6 = INP(esta%)
listost6 = l6 AND 8
IF listost6 <> 8 THEN GOTO ta
dst6 = l6 AND 240
IF dst6 = 80 THEN GOTO siesta2
GOTO ta
REM ***********************************
Parte alta de temperatura Actual ****
siesta2:
OUT (dato%), 1: REM **** Pido código Temperatura Actual
GOSUB STROBE: REM **** Interrumpo a ST6
GOSUB datemp
espe2:
l6 = INP(esta%): REM **** Entra datos de ST6
listost6 = l6 AND 8: REM **** Determina si el dato de ST6 está listo
IF listost6 <> 8 THEN GOTO espe2: REM **** Si no esta espera
dtac = INP(esta%)
dtacalta = (dtac AND 240): REM **** Parte alta de Temperatura Actual
OUT (dato%), 8: REM **** Indico que ya he recibido el dato
REM ******************************** Parte Baja de Temperatua Actual ********
GOSUB datemp
espe3:
l6 = INP(esta%): REM **** Entra datos de ST6
listost6 = l6 AND 8: REM **** Determina si el dato de ST6 está listo
IF listost6 <> 8 THEN GOTO espe3: REM **** Si no esta espera
dtac = INP(esta%)
dtacbaja = (dtac AND 240) / 16: REM **** Parte Baja de Temperatura
OUT (dato%), 9: REM **** Indico
que ya he recibido el dato
temact = ((dtacalta + dtacbaja) * .01953) * 20: REM **** Calcula
LOCATE 4, 9: PRINT USING "###.##"; temact: REM ** Limita present.
LOCATE 4, 16: PRINT "C "
temmd = (temact + temmd)
temmed = temmd / media: REM *** Suma media para calcular
media = media + 1
LOCATE 10, 9: PRINT USING "###.##"; temmed: REM ** Limita present.
LOCATE 10, 16: PRINT "C "
IF temact > temmax THEN GOSUB temmax: REM *** Determina si es máx.
IF temact < temmin THEN GOSUB temmin: REM *** Determina si es mín.
REM ********************************************
Dibuja Gráfica *************
xgraf = xgraf + 1
IF xgraf = 629 THEN GOSUB borra
ygraf = ABS(INT(temact 45))
IF ygraf < 10 THEN GOTO pa:
PSET (xgraf, ygraf)
REM ************************************************
PIDE DATO DE VELETA ****
l6 = INP(esta%)
listost6 = l6 AND 8
IF listost6 <> 8 THEN RETURN: REM **** Testea bit de listo
dst6 = l6 AND 240
IF dst6 = 80 THEN GOTO siesta4:
RETURN: REM **** Comprueba
que se puede interrumpir a ST6
REM *********************************************
Pido dato de veleta ******
siesta4:
OUT (dato%), 3: REM **** Pido código veleta
GOSUB STROBE: REM **** Interrumpo a ST6
GOSUB datemp
espe14:
l6 = INP(esta%): REM **** Entra datos de ST6
listost6 = l6 AND 8: REM **** Determina si el dato de ST6 está listo
IF listost6 <> 8 THEN GOTO espe14: REM **** Si no esta espera
dv = INP(esta%)
datovel = (dv AND 240) / 16
OUT (dato%), 8
GOSUB dibujavel
REM *********************************************
Pide de Presión Actual ****
pa:
l6 = INP(esta%)
listost6 = l6 AND 8
IF listost6 <> 8 THEN GOTO pa
dst6 = l6 AND 240
IF dst6 = 80 THEN GOTO siesta3
GOTO pa
REM ***************************************
Parte alta de Presión Actual ****
siesta3:
OUT (dato%), 2: REM **** Pido código Presión Actual
GOSUB STROBE: REM **** Interrumpo a ST6
GOSUB datemp
espe4:
l6 = INP(esta%): REM **** Entra datos de ST6
listost6 = l6 AND 8: REM **** Determina si el dato de ST6 está listo
IF listost6 <> 8 THEN GOTO espe4: REM **** Si no esta espera
pac = INP(esta%)
pacalta = (pac AND 240): REM **** Parte alta de Presión Actual
OUT (dato%), 8: REM **** Indico que ya he recibido el dato
REM *********************************** Parte Baja de Presión Actual ********
GOSUB datemp
espe5:
l6 = INP(esta%): REM **** Entra datos de ST6
listost6 = l6 AND 8: REM **** Determina si el dato de ST6 está listo
IF listost6 <> 8 THEN GOTO espe5: REM **** Si no esta espera
pac = INP(esta%)
pacbaja = (pac AND 240) / 16: REM **** Parte Baja de Presión Actual
OUT (dato%), 9: REM **** Indico
que ya he recibido el dato
preact = (((pacalta + pacbaja) * .019) * 2) / 5: REM **** Calcula
LOCATE 17, 9: PRINT USING "#.###"; preact: REM *** Limita presenta.
LOCATE 17, 15: PRINT "B. "
IF preact > premax THEN GOSUB premaxi: REM **** Determina máxima
IF preact < premin THEN
GOSUB premini: REM **** Determina mínima
RETURN
REM ************************************************
PIDE DATO DE VELETA ****
l6 = INP(esta%)
listost6 = l6 AND 8
IF listost6 <> 8 THEN RETURN: REM **** Testea bit de listo
dst6 = l6 AND 240
IF dst6 = 80 THEN GOTO siesta41:
RETURN: REM **** Comprueba
que se puede interrumpir a ST6
REM *********************************************
Pido dato de veleta ******
siesta41:
OUT (dato%), 3: REM **** Pido código veleta
GOSUB STROBE: REM **** Interrumpo a ST6
GOSUB datemp
espe141:
l6 = INP(esta%): REM **** Entra datos de ST6
listost6 = l6 AND 8: REM **** Determina si el dato de ST6 está listo
IF listost6 <> 8 THEN GOTO espe141: REM **** Si no esta espera
dv = INP(esta%)
datovel = (dv AND 240) / 16
OUT (dato%), 8
GOSUB dibujavel
REM **************************************
Subrutina de STROBE***************
STROBE:
FOR temporiza = 1 TO stb: NEXT temporiza
OUT (ctrl%), 0: REM **** Pongo a nivel alto a STROBE
FOR temporiza = 1 TO stb: NEXT temporiza
OUT (ctrl%), 1: REM **** Pongo
a nivel bajo a STROBE
RETURN
REM ****************************************** Datos de Veleta **************
dibujavel:
IF datovel = 4 THEN GOTO aba
IF datovel = 0 THEN GOTO arri
IF datovel = 6 THEN GOTO der
IF datovel = 2 THEN GOTO izda
IF datovel = 1 THEN GOTO no
IF datovel = 7 THEN GOTO ne
IF datovel = 3 THEN GOTO so
IF datovel = 5 THEN GOTO se
RETURN
arri:
vi = ac
ac = 8
GOSUB vel
RETURN
aba:
vi = ac
ac = 2
GOSUB vel
RETURN
der:
vi = ac
ac = 6
GOSUB vel
RETURN
izda:
vi = ac
ac = 4
GOSUB vel
RETURN
no:
vi = ac
ac = 7
GOSUB vel
RETURN
ne:
vi = ac
ac = 9
GOSUB vel
RETURN
so:
vi = ac
ac = 1
GOSUB vel
RETURN
se:
vi = ac
ac = 3
GOSUB vel
RETURN
vel:
SELECT CASE vi
CASE IS = 0
GOTO aca
CASE IS = 2
LINE (320, 130)(320, 70), 0
LINE (320, 130)(330, 120), 0
LINE (320, 130)(310,
120), 0
CASE IS = 8
LINE (320, 130)(320, 70), 0
LINE (320, 70)(330, 80), 0
LINE (320, 70)(310, 80),
0
CASE IS = 6
LINE (250, 100)(390, 100), 0
LINE (390, 100)(375, 95), 0
LINE (390, 100)(375,
105), 0
CASE IS = 4
LINE (250, 100)(390, 100), 0
LINE (250, 100)(265, 95), 0
LINE (250, 100)(265,
105), 0
CASE IS = 9
LINE (280, 120)(360, 80), 0
LINE (360, 80)(355, 90), 0
LINE (360, 80)(338, 83),
0
CASE IS = 1
LINE (280, 120)(360, 80), 0
LINE (280, 120)(285, 110), 0
LINE (280, 120)(302,
117), 0
CASE IS = 7
LINE (280, 80)(360, 120), 0
LINE (280, 80)(285, 90), 0
LINE (280, 80)(302, 83),
0
CASE IS = 3
LINE (280, 80)(360, 120), 0
LINE (360, 120)(355, 110), 0
LINE (360, 120)(338,
117), 0
END SELECT
SELECT CASE ac
CASE IS = 0
GOTO aca
CASE IS = 2
LINE (320, 130)(320, 70)
LINE (320, 130)(330, 120)
LINE (320, 130)(310,
120)
CASE IS = 8
LINE (320, 130)(320, 70)
LINE (320, 70)(330, 80)
LINE (320, 70)(310, 80)
CASE IS = 6
LINE (250, 100)(390, 100)
LINE (390, 100)(375, 95)
LINE (390, 100)(375,
105)
CASE IS = 4
LINE (250, 100)(390, 100)
LINE (250, 100)(265, 95)
LINE (250, 100)(265,
105)
CASE IS = 9
LINE (280, 120)(360, 80)
LINE (360, 80)(355, 90)
LINE (360, 80)(338, 83)
CASE IS = 1
LINE (280, 120)(360, 80)
LINE (280, 120)(285, 110)
LINE (280, 120)(302,
117)
CASE IS = 7
LINE (280, 80)(360, 120)
LINE (280, 80)(285, 90)
LINE (280, 80)(302, 83)
CASE IS = 3
LINE (280, 80)(360, 120)
LINE (360, 120)(355, 110)
LINE (360, 120)(338,
117)
aca:
END SELECT
RETURN
REM ************************************
Opción F3 salir al DOS *************
f3:
TIMER OFF
SCREEN 0
CLS
OUT (dato%), 0
PRINT #3, ""
PRINT #3, "Proyecto METEO ***********************************************"
PRINT #3, ""
PRINT #3, "** Jesús Antonio
Alquezar Sierra & José Ignacio Díaz Beamud **"
CLOSE #3
PRINT "Software Estación Meteorológica V5.00 23 de MAYO de 1994 "
PRINT : PRINT
PRINT "Por Jesús Antonio Alquezar Sierra & José Ignacio Díaz Beamud"
PRINT "____________________________________________________________"
END
REM ************************************
Subrutina de borrado de Gráfica ****
borra:
LINE (516, 10)(629, 44), 0, BF
xgraf = 516
RETURN
REM ******************************************
Subrutina de AYUDA ***********
f1:
TIMER STOP
FOR yayu = 10 TO 185
LINE (159, 10)(yayu * 1.75 + 155, yayu), 1, B
FOR temporiza = 1 TO ayu: NEXT temporiza
LINE (159, 10)((xayu * 1.75 + 155) 1, yayu 1), 0, B
NEXT
LOCATE 3, 23: PRINT " "
LOCATE 4, 23: PRINT " ACERCA ESTACION : "
LOCATE 5, 23: PRINT " "
LOCATE 7, 29: PRINT " Programa Producido por : "
LOCATE 8, 29: PRINT " "
LOCATE 9, 29: PRINT " J.I.D.B. & J.A.A.S. "
LOCATE 11, 29: PRINT " HARDWARE & SOFTWARE "
LOCATE 12, 29: PRINT " 23 de MAYO de 1994. "
LOCATE 15, 29: PRINT " METEO.EXE V5.00 "
LOCATE 20, 33: PRINT " PROYECTO ST6 "
LOCATE 22, 32: PRINT " pulse una tecla "
PLAY "MBo3L8ED+ED+Eo2Bo3DCL2o2A"
tea:
IF INKEY$ = "" THEN GOTO tea
LINE (159, 10)(478.75,
185), 0, BF
REM *********************************
DIBUJA LA N DE NORTE ***********
LINE (300, 50)(300, 40)
LINE (300, 40)(340, 50)
LINE (340, 50)(340, 40)
REM ***************************************************************
REM ****************************** DIBUJA
LA S DE SUR *************
LINE (340, 160)(300, 160)
LINE (340, 160)(340, 155)
LINE (340, 155)(300, 155)
LINE (300, 155)(300, 150)
LINE (300, 150)(340, 150)
REM ***************************************************************
REM ****************************** DIBUJA
LA E DE ESTE ************
LINE (440, 95)(440, 105)
LINE (440, 95)(480, 95)
LINE (440, 105)(480, 105)
LINE (440, 100)(480, 100)
REM ***************************************************************
REM ****************************** DIBUJA
LA O DE OESTE ***********
LINE (200, 95)(200, 105)
LINE (200, 105)(160, 105)
LINE (160, 105)(160, 95)
LINE (160, 95)(200, 95)
FOR N = 90 TO 100
CIRCLE (320, 100), N
NEXT N
TIMER ON
RETURN
REM **************************** Subrutina de F2 que es configuracion *******
f2:
CLOSE #3
TIMER OFF
CLS
pri:
SCREEN 0
CLS
PRINT "******** Detección de puerto CENTRONICS (paralelo) para IBMPC ********"
PRINT "********
********"
PRINT "******** José Ignacio
Diaz Beamud & Jesús Antonio Alquezar Sierra ********"
REM **** Determina la base del puerto
base *********************************
LOCATE 10, 12
INPUT "En que puerto LPT está conectada la ESTACION (1,2,3)"; p
IF p = 1 THEN BB = 8: ba = 9: GOTO in
IF p = 2 THEN BB = 10: ba = 11: GOTO in
IF p = 3 THEN BB = 12: ba = 13: GOTO in
GOTO pri
in:
LOCATE 10, 12: PRINT "
"
DEF SEG = 64: REM **** Pone la memoria en el segmento 64
datosb% = PEEK(BB): REM **** Saca el primer byte (bajo)
datosa% = PEEK(ba): REM **** Saca el segundo byte (alto)
REM **** La suma determina la posicion de LPT **** posicion 0040:0008
dato% = (256 * datosa%) + (datosb%)
IF dato% = 0 THEN GOTO nohay
esta% = dato% + 1
ctrl% = dato% + 2
LOCATE 10, 22
COLOR 25
PRINT "El puerto paralelo es correcto LPT"; p
PRINT ""
COLOR 5
PRINT " Dirección BASE = "; HEX$(dato%)
PRINT " Dirección ESTADO = "; HEX$(esta%)
PRINT " Dirección CONTROL = "; HEX$(ctrl%)
OUT (dato%), 0
OUT (ctrl%), 0
COLOR 15
LOCATE 23, 1: PRINT "Pulse una tecla . . ."
GOTO inicio
nohay:
LOCATE 10, 13
COLOR 12
PRINT "No detecto puerto LPT"; p; "consulte con su manual de usuario."
COLOR 10
PRINT " ¡¡¡¡ PROCESO DETENIDO !!!!"
END
inicio:
k:
IF INKEY$ = "" THEN GOTO k
kk3:
CLS
PRINT " ¿Que tipo de ordenador es en el que tiene instalado este programa.?"
PRINT " Si su equipo no esta en la lista escoja el que más se adecua a la"
PRINT " velocidad de su equipo
. . ."
PRINT : PRINT
PRINT " 1 PCXT (8086)"
PRINT " 2 PCi386SX 25 Mhz"
PRINT " 3 PCi486DX 33 Mhz"
PRINT : PRINT
INPUT "Eliga OPCION "; equi
IF equi > 3 OR equi < 1 THEN GOTO
kk3
PRINT : PRINT
CLS
PRINT "Introduce el número de intervalos que quieres para que sea guardada"
PRINT "la temperatura en el fichero METEO.DAT, en segundos . . ."
PRINT "Nota : Se pierde el antiguo fichero METEO.DAT"
INPUT "Tiempo "; tifi%
REM *************************************
Escribe fichero de Configuración **
OPEN "METEO.CFG" FOR OUTPUT AS #1
PRINT #1, dato%
PRINT #1, esta%
PRINT #1, ctrl%
PRINT #1, equi
PRINT #1, tifi%
CLOSE #1
IF ero = 1 THEN GOTO fin2
GOTO propri
fin2:
CLS
PRINT "Vuelva a ejecutar el programa . . . . (GRACIAS)"
END
REM **********************************************
Subrutina de Error *******
er:
ero = 1
CLS
SCREEN 0
PRINT "Este programa no se ha configurado todavia ahora tendra que acerlo"
PRINT "antes de poder ejecutarlo, la configuración se guardará en el archivo"
PRINT "METEO.CFG que será copiado en el directorio desde donde se haya"
PRINT "ejecutado este programa y será de formato ASCII . . ."
PRINT : PRINT : PRINT
PRINT "Pulse un tecla para configurar
. . ."
kk2:
IF INKEY$ = "" THEN GOTO kk2
GOTO f2
REM *************************************
Subrutina de Selección de equipo **
pontem:
SELECT CASE equi
REM ********************** Configuración XT (8086) ******************
CASE IS = 1
linei = 1: circi = 1: circv =
1: stb = 1: ayu = 1: est6 = 10
REM ********************** Configuración 286 ************************
CASE IS = 2
linei = 1: circi = 1: circv =
1: stb = 1: ayu = 1: est6 = 10
REM ********************** Configuración 486DX 33Mhz ****************
CASE IS = 3
linei = 50: circi = 105: circv = 500
stb = 100: ayu = 200: est6 =
50
END SELECT
RETURN
REM ********************* Subrutina de
tiempo para que el ST6 trate dato ****
datemp:
FOR temporiza = 1 TO est6: NEXT temporiza
RETURN
REM *********************************** Subrutina de temp max **************
temmax:
temmax = temact
LOCATE 6, 9: PRINT USING "###.##"; temmax: REM ** Limita present.
LOCATE 6, 16: PRINT "C
"
RETURN
REM *********************************** Subrutina de temp min **************
temmin:
temmin = temact
LOCATE 8, 9: PRINT USING "###.##"; temmin: REM ** Limita present.
LOCATE 8, 16: PRINT "C
"
RETURN
REM ************************************************************************
REM ***********************************
Subrutina de Presión Máxima ********
premaxi:
premax = preact
LOCATE 19, 9: PRINT USING "#.###"; premax: REM *** Limita presenta.
LOCATE 19, 15: PRINT "B. "
RETURN
REM ************************************************************************
REM ***********************************
Subrutina de Presión Máxima ********
premini:
premin = preact
LOCATE 21, 9: PRINT USING "#.###"; premin: REM *** Limita presenta.
LOCATE 21, 15: PRINT "B. "
RETURN
REM ***************************************
Impresión Tempe en fichero *****
fiche:
PRINT #3, USING "###.##"; temact; : PRINT #3, " > ";
PRINT #3, TIME$; : PRINT #3, " "; USING "###.##"; temmax;
PRINT #3, " "; USING "###.##"; temmin;
PRINT #3, " "; USING
"###.##"; temmed
RETURN
REM ************************************************************************
END
BREVE EXPLICACION AL PROGRAMA METEO.BAS
:
Este programa está escrito y compilado en QUICKBASIC de Microsoft. Es un programa que se comunica con la estación metereológica a través del protocolo ya establecido. El programa
nada más inicializarse comprueba
que existe el archivo de configuración (METEO.CFG). Si
este no existe salta a la subrutina de configuración. También
cada vez que se ejecuta el programa borra los datos anteriores
de METEO.DAT de control de temperatura y crea uno nuevo. El programa
una vez realizada la pantalla de METEO trata de comunicarse con
la estación, entra en un bucle hasta que la entrada de
el registro de estado (por el cual la estación envía
datos al PC) hay un 05h (mirar capitulo de protocolo). En ese
momento el programa saca el código de la información
que necesita y produce un pulso en STROBE para interrumpir al
ST6. Cuando detecta dato listo recoge el dato, lo introduce en
una variable y saca al puerto de datos un 08h en espera de la
parte baja que cuando es recibida se coloca en otra variable,
con esta variable se realiza una operación, ya que como
la información se recoge de los 4 bits de mayor peso del
registro de estado habrá que pasarlo a parte baja para
sumarlo con la parte alta. Ahora habrá que determinar cual
es el dato completo, para ello se utiliza una tercera variable.
Los cálculos son :
para la parte alta :
dato_alto = inp(esta%)
parte_alta = (dato_alto AND 240)
para la parte baja :
dato_bajo = inp(esta%)
parte_baja = (dato_bajo AND 240) /
16
y el resultado de la unión
es :
dato_total = parte_alta + parte_baja
Con esto dato_total es el valor del registro
ADR del ST6, que es lo que nos manda el PC por lo tanto ahora
podremos operar con el para conseguir el valor deseado.
NOTA : Se recuerda que como el ST6
está alimentado a 5V la resolución del convertidor
es de 19,5mV.
Para hallar el valor de la temperatura
a partir de dato_total sería :
tempe = (dato_total * .01953) * 2
* 10
dato_total se multiplica por 0.0195V
para saber el valor en voltios del ADR, después este resultado
se multiplica por 2, ya que la entrada del A/D esta dividida entre
dos por medio de un divisor de tensión y posteriormente
se multiplica por 10 que es el valor por el cual hay que multiplicar
en resultado en VOLTIOS para saber la temperatura, ya que la sonda
entrega de 0-10V en un rango de temperaturas de 0-100ºC,
osea 100/10=10.
Para determinar el valor de la presión
a partir de dato_total sería :
presion = ((dato_total * .01953) *
2) / 5
dato_total se multiplica por 0.0195V
para saber el valor en voltios del ADR, después este resultado
se multiplica por 2, por que la tensión de entrada del
A/D esta divida entre 2, y para saber a que presión equivale
esa tensión el resultado se multiplica por 5.
Para la veleta no hay que realizar ningún
tipo de calculo ya que el valor de los 4 bits de mayor peso del
registro de estado determinan en que posición se encuentra.
El programa METEO.BAS pide los datos
de temperatura y presión de máximas y mínimas
sólo cuando al se ejecuta al programa, después es
el mismo programa BASIC el que lleva ese control, así se
consigue mayor fluidez datos para refrescar a la veleta.
Los datos de temperatura se registran
en el fichero METEO.DAT y los de la configuración en METEO.CFG.
VI-d,II) PROGRAMA DEL ST6VI-d,II) PROGRAMA DEL ST6
Ante la dificultad para poder realizar
el organigrama mediante alguno de los programas existentes, se
opta por explicar los bloques.
Hay que advertir para la comprensión
del programa que cada vez que se va a sacar un dato a un puerto
se realiza la complementacion del bit 3, es debido a una característica
del puerto paralelo del PC y se realiza en el ST6 por ser mas
fácilmente realizable que en el PC.
Programa principal:
Este programa comienza con la definición de los símbolos y de las posiciones de memoria que se van a utilizar en el desarrollo del programa, a continuación se determina si el sistema estaba funcionando anteriormente (Como mas adelante se explicara esta previsto que el PC pueda desconectarse en cualquier momento y se ha dotado al sistema de una rutina "anticuelge" en el único momento que podría ocurrir, esta rutina provoca el RESET mediante el WDR), en caso de haber estado funcionando salta una rutina de inicialización, en caso contrario salta a la rutina de inicialización, si estaba o no estaba funcionando anteriormente se determina por medio de un posición de memoria puesta a tal efecto.
La rutina de inicialización, lo que realiza es cargar el dato 00h en los registros destinados a guardar las temperaturas y presiones máximas, y guardar FFH en los registros destinados a los mínimos, a continuación llama a un temporizador de 5 Sg y después pone a 1 el registro de control de funcionamiento con lo que termina la rutina de inicialización y vuelve al flujo principal.
A continuación viene una rutina de programación de puertos que a programa a los puertos según la función que van a realizar, después habilita las interrupciones.
A continuación comienza la rutina que se repite ciclicamente, comienza mediante la indicación al PC de que esta listo para ser interrumpido, comienza la conversión de temperatura para ello reprograma los puertos, una vez acabada la conversión se determina si la temperatura es máxima o mínima y si es así la guarda en el registro correspondiente además de en el de temperatura actual, después realiza la conversión de la presión con lo que vuelve a reprogramar los puertos, una vez acabada la conversión determina si es máxima o mínima y la guarda en el lugar correspondiente además de en el registro de presión actual. después de esto salta al comienzo de la rutina repetitiva.
Hay que decir que el ST6 puede ser interrumpido
en cualquier momento por el PC con lo cual se salta a la rutina
de interrupción.
RUTINA DE INTERRUPCIÓN:
A esta rutina se accede desde el programa
principal mediante la interrupción del PC, una vez en esta
rutina se carga el valor de nolisto en el puerto que comunica
en dirección al PC, con lo cual se dehabilita el permiso
al PC para que interrumpa, después se carga el código
que manda el PC en el registro reservado a tal efecto, a continuación
se determina a que código pertenece saltando a la rutina
correspondiente, en caso de ser un código o valido se vuelve
al programa principal.
Las rutinas son todas prácticamente iguales exceptuando la de la veleta que se describirá mas adelante.
Todas las rutinas de envió de datos (exceptuando la de la veleta) funcionan igual todas ellas cogen dato solicitado y lo transmiten de nible en nible mandando primero la parte alta y después la parte baja, antes de mandar el siguiente dato o de volver a la subrutina anterior comprueba si el PC lo ha recibido, esto los hace mediante dos códigos un para la parte alta y otro para la parte baja.
La rutina de la veleta lo que hace es
leer los datos de la veleta y a continuación lo manda al
PC, en este caso solo manda un nible por que el dato de la veleta
es solo de 3 bit.
En las rutinas de envió de datos
es en el único momento en el que se puede colgar el sistema
esto se soluciona limitando en nº de veces que se puede repetir
el bucle de comprobación de dato recibido, en caso de agotarse
ese tiempo (nº de veces que se puede repetir el bucle) salta
a una rutina para hacer funcionar el wachtdog esto lo hace entrando
en un bucle cerrado que no carga el WDR. Hay que advertir que
durante todo el programa se recarga el WDR para evitar el RESET.
A continuacion se encuetra el fichero
fuente
.DISPLAY " METEO21.ASM "
.DISPLAY " "
.DISPLAY "**************************************************************** "
.DISPLAY "****** Programa para ST6215 por J.I.D.B. & J.A.A.S. ****** "
.DISPLAY "****** ****** "
.DISPLAY "****** ESTACION METEREOLOGICA ****** "
.DISPLAY "****** V 2.01 ****** "
.DISPLAY "**************************************************************** "
.DISPLAY " "
.DISPLAY " PROGRAMA TERMINADO EL DIA "
.DISPLAY "
24 DE MAYO DE 1994 "
;****************************************************************************
;**************************** DEFINE REGISTROS ******************************
;****************************************************************************
x .def 80h
y .def 81h
v .def 82h
w .def 83h
a .def 0ffh,m
drpa .def 0c0h
drpb .def 0c1h
drpc .def 0c2h
ddrpa .def 0c4h
ddrpb .def 0c5h
ddrpc .def 0c6h
ior .def 0c8h
rdw .def 0c9h
orpa .def 0cch
orpb .def 0cdh
orpc .def 0ceh
adr .def 0d0h,m
adcr .def 0d1h
psc .def 0d2h
tcr .def 0d3h
tscr .def 0d4h
wdr .def 0d8h
;****************************************************************************
;*************** DEFINICION POSICIONES MEMORIA ******************************
;****************************************************************************
temact .def 84h,0ffh,0ffh,m ; DEFINE POSIONES DE MEMORIA
preact .def 85h,0ffh,0ffh,m ; A UTILIZAR PARA LA PROGRMACION
veleta .def 0c2h,m ; VELETA (PC)
temmin .def 86h,0ffh,0ffh,m ; TEMPERATURA MINIMA
temmax .def 87h,0ffh,0ffh,m ; TEMPERATURA MAXIMA
premin .def 88h,0ffh,0ffh,m ; PRESION MINIMA
premax .def 89h,0ffh,0ffh,m ; PRESION MAXIMA
partal .def 8Ah,0ffh,0ffh,m ; PARTE ALTA A TRANSMITIR
partba .def 8bh,0ffh,0ffh ; PARTE BAJA A TRANSMITIR
comu .def 8ch,0ffh,0ffh ; REGISTRO DE TRANSMISIONES
control .def 8dh,0ffh,0ffh,m ; Registro de control de funcionamiento
salva .def 8eh,0ffh,0ffh ; Posición
Salva Acumulador para sobrutina
alta .equ 11110000b ; Define palabras para control rapido
baja .equ 00001111b
tempe .equ 01h ; CODIGO
DE LA TEMPERATURA ACTUAL
presi .equ 02h ; CODIGO
DE LA PRESION ACTUAL
velet .equ 03h ; CODIGO
DE LA VELETA
tempm .equ 04h ; CODIGO DE LA TEMPERATURA MINIMA
tempx .equ 05h ; CODIGO
DE LA TEMPERATURA MAXIMA
presm .equ 06h ; CODIGO DE LA PRESION MINIMA
presx .equ 07h ; CODIGO
DE LA PRESION MAXIMA
repc .equ 08h ; Codigo de dato recibido ( PC > ST6)
rep2 .equ 09h ; Codigo
dato recibido 2
listo .equ 11110101b ; CODIGO
DE LISTO PARA RECIBIR INTERRUCCION
nolisto .equ 0 ; CODIGO
DE ANULACION DE LISTO
ddrte .equ 00h ;\
ortem .equ 50h ; | ACTIVA EL ADC DE LA PATILLA Nº6
drtem .equ 0e0h ;/
ddrpr .equ 00h ;\
orpre .equ 90h ; | ACTIVA EL ADC DE LA PATILLA Nº7
drpre .equ 0e0h ;/
ddrve .equ 00h ;\
orvel .equ 10h ; | DESACTIVA LOS CONVERTIDORES
drvel .equ 0e0h ;/
;****************************************************************************
;************************ PROGRAMACION INICIAL DE PUERTOS *******************
;****************************************************************************
.org 0800h
reset reti ; Retorna a modo normal desues del reset
ldi wdr,0feh ; Recarga el WDR
ldi a,0aah ; Carga en el acumlador ffh
cp a,control ; Compara el acumulador con control
jrz comi1 ; Si ya estaba funcionando salta
jp reco
comi1 jp comi
reco ldi temmax,0 ;\ Realiza los ajustes para el correcto
ldi premax,0 ; | funcionamiento del sistema
ldi temmin,0ffh ; |
ldi premin,0ffh ;/
ldi a,05h ; Bloquea el sistema Durante 5 Sg
call temp ;
ldi control,0aah ; Pone
el registro de control en fucionamiento
comi ldi ddrpb,00011111b ;\
ldi orpb,00011111b ; | Programa el puerto B como salida
ldi drpb,11100000b ;/ (PB0PB4)
resto alta impedancia
ldi wdr,0feh ; Recarga el WDR
ldi ddrpc,00h ;\
ldi orpc,00h ; | Programa como entrada el puerto c
ldi drpc,80h ;/
(Veleta) ( PC 7 en alta impedancia)
ldi wdr,0feh ; Recarga el WDR
ldi ddrpa,ddrve ;\
ldi orpa,orvel ; | Programa puerto A como entrada
ldi drpa,drvel ;/
ldi wdr,0feh ; Recarga el WDR
ldi ior,00010000b ; Habilita las interrupciones de PA a
; flanco
descendente
;****************************************************************************
;**************** FINAL PROGRAMACION DE PUERTOS *****************************
;****************************************************************************
;****************************************************************************
;***************** COMIENZO PROGRAMA PRINCIPAL ******************************
;****************************************************************************
prin ldi a,listo ; Carga en A listo
call comple ; Llama a subrutina de complementación bit 4
ld drpb,a ; Indica al PC Que el ST6 esta listo
ldi ddrpa,ddrte ; Programa el puerto a para poder medir
ldi orpa,ortem ; la temperatura
ldi drpa,drtem
ldi adcr,00010000b ; Conecta el ADC
nop ; Espera a que se conecte
ldi adcr,00110000b ; Da
comienzo a la conversion
lazo1 ldi wdr,0feh ; Recarga el WDR
jrr 6,adcr,lazo1 ; Comprueba si la conversion ha finalizado
; y si es asi continua
ld a,adr ; coge el dato resultado de la conversion
ldi adcr,00h ; apaga el ADC
ld temact,a ; Guarda la temperatura en su posicion
ldi wdr,0feh ; recarga el WDR
ld a,temmin ; Comienza la determinacion de temperatura
cp a,temact ; minima
jrnc gutmi ; Si no se ha producido carry salta
jp ftmi ; salta al final de la rutina
gutmi jrnz gutmin ; si no se ha producido flag de 0 salta
ldi wdr,0feh ; recarga el WDR
jp ftmi ; salta al final de la rutina
gutmin ld a,temact ; guarda la temperatura actual como minima
ldi wdr,0feh ; recarga el WDR
ld temmin,a ;
jp presion ; si la temperatura era minima salta al final
; de
las temperaturas
ftmi ld a,temmax ; Comienza la determinacion de temperatura
ldi wdr,0feh ; recarga el WDR
cp a,temact ; maxima
jrc gutma ; Si se ha producido carry salta
jp presion ; salta al final de la rutina
gutma jrnz gutmax ; si no se ha producido flag de 0 salta
ldi wdr,0feh ; recarga el WDR
jp presion ; salta al final de la rutina
gutmax ld a,temact ; guarda la temperatura actual como maxima
ldi wdr,0feh ; recarga el WDR
ld temmax,a ;
presion ldi wdr,0feh ; recarga el WDR
ldi ddrpa,ddrpr ; Programa el puerto a para poder medir
ldi orpa,orpre ; la presion
ldi drpa,drpre
ldi adcr,00010000b ; Conecta el ADC
nop ; Espera a que se conecte
ldi adcr,00110000b ; Da
comienzo a la conversion
lazo2 ldi wdr,0feh ; Recarga el WDR
jrr 6,adcr,lazo2 ; Comprueba si la conversion ha finalizado
; y si es asi continua
ld a,adr ; coge el dato resultado de la conversion
ldi adcr,00h ; apaga el ADC
ld preact,a ; Guarda la presion en su posicion
ld a,premin ; Comienza la determinacion de de presion
ldi wdr,0feh ; recarga el WDR
cp a,preact ; minima
jrnc gupmi ; Si no se ha producido carry salta
jp fpmi ; salta al final de la rutina
gupmi jrnz gupmin ; si no se ha producido flag de 0 salta
ldi wdr,0feh ; recarga el WDR
jp fpmi ; salta al final de la rutina
gupmin ld a,preact ; guarda la presion actual como minima
ld premin,a ;
jp prin ; si la presion era minima salta al final
; de
las presiones (comienzo programa)
fpmi ldi wdr,0feh ; recarga el WDR
ld a,premax ; Comienza la determinacion de presion
cp a,preact ; maxima
jrc gupma ; Si se ha producido carry salta
jp prin ; salta al final de la rutina
gupma jrnz gupmax ; si no se ha producido flag de 0 salta
ldi wdr,0feh ; recarga el WDR
jp prin ; salta al final de la rutina
gupmax ld a,preact ; guarda la presion actual como maxima
ldi wdr,0feh ; recarga el WDR
ld premax,a ;
jp prin ; Salta
la principio de rutina
;****************************************************************************
;******************* FINAL RUTINA PRINCIPAL *******************************
;****************************************************************************
;****************************************************************************
;******************* COMIENZO INTERRUPCION COMUNICACIONES ******************
;****************************************************************************
comunica
ld salva,a ; Guarda en Salva el ACUMULADOR
ldi a,nolisto ; Carga en A nolisto ( desabilia permiso in)
call comple ; Llama a subrutina de complementación bit 4
ld drpb,a ; Indica al PC Que el ST6 no esta listo
ldi drpb,0e0h ; Indica al PC que esta atendiendo interrup
ldi wdr,0feh ; Recarga WDR
ld a,drpa ; Entra dato del PC
andi a,baja ; Pongo a 0 el las lineas que no son de comu
cpi a,tempe ; Comprueba codigos de operacion
ldi wdr,0feh ; Recarga WDR
jrnz pr
call comtem ; Llama a la rutina de com de tempe actual
jp fin
pr cpi a,presi ; Comprueba si corresponde a presion
ldi wdr,0feh ; Recarga WDR
jrnz vel
call compre
jp fin
vel cpi a,velet ; Comprueba si corresponde a veleta
ldi wdr,0feh ; Recarga WDR
jrnz tmin
call comvel
jp fin
tmin cpi a,tempm ; Comprueba si corresponde a T min
ldi wdr,0feh ; Recarga WDR
jrnz tmax
call comtmin
jp fin
tmax cpi a,tempx ; Comprueba si corresponde a T max
ldi wdr,0feh ; Recarga WDR
jrnz pmin
call comtmax
jp fin
pmin cpi a,presm ; Comprueba si corresponde a P min
ldi wdr,0feh ; Recarga WDR
jrnz pmax
call compmin
jp fin
pmax cpi a,presx ; Comprueba si corresponde a P max
ldi wdr,0feh ; Recarga WDR
jrnz fin
call compmax
fin ld a,salva ; Recupera el valor del acumulador
ldi wdr,0feh ; Recarga WDR
reti ; retorna
al programa principal
;****************************************************************************
;******************* FIN RUTINA DETERMINACION INTERRUPCION *****************
;****************************************************************************
;****************************************************************************
;******************* COMIENZO RUTINAS DE COMUNICACIONES *********************
;****************************************************************************
;****************************************************************************
;******************** TEMPERATURA ACTUAL ************************************
;****************************************************************************
comtem ld a,temact
ld comu,a ; Carga la temperatura actual
ldi wdr,0feh ; Recarga el WDR
ld a,comu ; Comienza la transmision de parte alta
andi a,alta ;\
rlc a ; | Rota parte alta a la baja
rlc a ; |
rlc a ; |
rlc a ; |
rlc a ;/
andi a,baja ; Elimina posible Carry
set 5,a
set 6,a ; Mantiene el estado de alta
set 7,a ; Impedancia
ldi wdr,0feh ; Recarga el WDR
call comple ; Llama a subrrutina de complementacion
ld drpb,a ; Saca parte alta
set 4,drpb ; Indica dato listo
call reci ; Llama a comprobacion recep
ld a,comu ; Comienza transmision parte baja
andi a,baja
set 5,a
set 6,a
set 7,a
ldi wdr,0feh ; Recarga el WDR
call comple ; Llama a subrrutina de complementacion
ld drpb,a ; Saca parte baja
set 4,drpb ; Indica dato listo
call reci2 ; Llama a comprobacion recep
reti ; Fin
trasmision
;****************************************************************************
;***************** FIN TEMPERATURA ACTUAL **********************************
;****************************************************************************
;****************************************************************************
;************************ PRESION ACTUAL ************************************
;****************************************************************************
compre ld a,preact
ld comu,a ; Carga la presion actual
ldi wdr,0feh ; Recarga el WDR
ld a,comu ; Comienza la transmision de parte alta
andi a,alta ;\
rlc a ; | Rota parte alta a la baja
rlc a ; |
rlc a ; |
rlc a ; |
rlc a ;/
andi a,baja ; Elimina posible Carry
set 5,a
set 6,a ; Mantiene el estado de alta
set 7,a ; Impedancia
ldi wdr,0feh ; Recarga el WDR
call comple ; Llama a subrrutina de complementacion
ld drpb,a ; Saca parte alta
set 4,drpb ; Indica dato listo
call reci ; Llama a comprobacion recep
ld a,comu ; Comienza transmision parte baja
andi a,baja
set 5,a
set 6,a
set 7,a
ldi wdr,0feh ; Recarga el WDR
call comple ; Llama a subrrutina de complementacion
ld drpb,a ; Saca parte baja
set 4,drpb ; Indica dato listo
call reci2 ; Llama a comprobacion recep
reti ; Fin
trasmision
;****************************************************************************
;******************** FIN PRESION ACTUAL ************************************
;****************************************************************************
;****************************************************************************
;******************** TEMPERATURA MAXIMA ************************************
;****************************************************************************
comtmax ld a,temmax
ld comu,a ; Carga la temperatura maxima
ldi wdr,0feh ; Recarga el WDR
ld a,comu ; Comienza la transmision de parte alta
andi a,alta ;\
rlc a ; | Rota parte alta a la baja
rlc a ; |
rlc a ; |
rlc a ; |
rlc a ;/
andi a,baja ; Elimina posible Carry
set 5,a
set 6,a ; Mantiene el estado de alta
set 7,a ; Impedancia
ldi wdr,0feh ; Recarga el WDR
call comple ; Llama a subrrutina de complementacion
ld drpb,a ; Saca parte alta
set 4,drpb ; Indica dato listo
call reci ; Llama a comprobacion recep
ld a,comu ; Comienza transmision parte baja
andi a,baja
set 5,a
set 6,a
set 7,a
ldi wdr,0feh ; Recarga el WDR
call comple ; Llama a subrrutina de complementacion
ld drpb,a ; Saca parte baja
set 4,drpb ; Indica dato listo
call reci2 ; Llama a comprobacion recep
reti ; Fin
trasmision
;****************************************************************************
;***************** FIN TEMPERATURA MAXIMA **********************************
;****************************************************************************
;****************************************************************************
;******************** TEMPERATURA MINIMA ************************************
;****************************************************************************
comtmin ld a,temmin
ld comu,a ; Carga la temperatura minima
ldi wdr,0feh ; Recarga el WDR
ld a,comu ; Comienza la transmision de parte alta
andi a,alta ;\
rlc a ; | Rota parte alta a la baja
rlc a ; |
rlc a ; |
rlc a ; |
rlc a ;/
andi a,baja ; Elimina posible Carry
set 5,a
set 6,a ; Mantiene el estado de alta
set 7,a ; Impedancia
ldi wdr,0feh ; Recarga el WDR
call comple ; Llama a subrrutina de complementacion
ld drpb,a ; Saca parte alta
set 4,drpb ; Indica dato listo
call reci ; Llama a comprobacion recep
ld a,comu ; Comienza transmision parte baja
andi a,baja
set 5,a
set 6,a
set 7,a
ldi wdr,0feh ; Recarga el WDR
call comple ; Llama a subrrutina de complementacion
ld drpb,a ; Saca parte baja
set 4,drpb ; Indica dato listo
call reci2 ; Llama a comprobacion recep
reti ; Fin
trasmision
;****************************************************************************
;***************** FIN TEMPERATURA MINIMA **********************************
;****************************************************************************
;****************************************************************************
;********************** PRESION MAXIMA ************************************
;****************************************************************************
compmax ld a,premax
ld comu,a ; Carga la presion maxima
ldi wdr,0feh ; Recarga el WDR
ld a,comu ; Comienza la transmision de parte alta
andi a,alta ;\
rlc a ; | Rota parte alta a la baja
rlc a ; |
rlc a ; |
rlc a ; |
rlc a ;/
andi a,baja ; Elimina posible Carry
set 5,a
set 6,a ; Mantiene el estado de alta
set 7,a ; Impedancia
ldi wdr,0feh ; Recarga el WDR
call comple ; Llama a subrrutina de complementacion
ld drpb,a ; Saca parte alta
set 4,drpb ; Indica dato listo
call reci ; Llama a comprobacion recep
ld a,comu ; Comienza transmision parte baja
andi a,baja
set 5,a
set 6,a
set 7,a
ldi wdr,0feh ; Recarga el WDR
call comple ; Llama a subrrutina de complementacion
ld drpb,a ; Saca parte baja
set 4,drpb ; Indica dato listo
call reci2 ; Llama a comprobacion recep
reti ; Fin
trasmision
;****************************************************************************
;******************** FIN PRESION MAXIMA **********************************
;****************************************************************************
;****************************************************************************
;********************** PRESION MINIMA ************************************
;****************************************************************************
compmin ld a,premin
ld comu,a ; Carga la presion minima
ldi wdr,0feh ; Recarga el WDR
ld a,comu ; Comienza la transmision de parte alta
andi a,alta ;\
rlc a ; | Rota parte alta a la baja
rlc a ; |
rlc a ; |
rlc a ; |
rlc a ;/
andi a,baja ; Elimina posible Carry
set 5,a
set 6,a ; Mantiene el estado de alta
set 7,a ; Impedancia
ldi wdr,0feh ; Recarga el WDR
call comple ; Llama a subrrutina de complementacion
ld drpb,a ; Saca parte alta
set 4,drpb ; Indica dato listo
call reci ; Llama a comprobacion recep
ld a,comu ; Comienza transmision parte baja
andi a,baja
set 5,a
set 6,a
set 7,a
ldi wdr,0feh ; Recarga el WDR
call comple ; Llama a subrrutina de complementacion
ld drpb,a ; Saca parte baja
set 4,drpb ; Indica dato listo
call reci2 ; Llama a comprobacion recep
reti ; Fin
trasmision
;****************************************************************************
;******************* FIN PRESION MINIMA **********************************
;****************************************************************************
;****************************************************************************
;************************** VELETA ******************************************
;****************************************************************************
comvel ld a,veleta
ld comu,a ; Carga la VELETA
ldi wdr,0feh ; Recarga el WDR
ld a,comu ; Comienza la transmision de parte alta
andi a,alta ;\
rlc a ; | Rota parte alta a la baja
rlc a ; |
rlc a ; |
rlc a ; |
rlc a ;/
res 3,a ; Elimina posible bit de error
andi a,baja ; Elimina posible Carry
set 5,a
set 6,a ; Mantiene el estado de alta
set 7,a ; Impedancia
ldi wdr,0feh ; Recarga el WDR
call comple ; Llama a subrrutina de complementacion
ld drpb,a ; Saca estado de la veleta
set 4,drpb ; Indica dato listo
call reci ; Llama a comprobacion recep
reti ; Fin
trasmision
;****************************************************************************
;******************* FIN VELETA *****************************************
;****************************************************************************
;****************************************************************************
;******************* COMPROBACION DE DATO RECIBIDO PARTE ALTA ***************
;****************************************************************************
reci ldi w,0ffh ; Carga nº max de veces del bucle
reci0 ldi v,0ffh ; Carga nº max de veces
reci1 ldi wdr,0feh ; Recarga el WDR
ld a,drpa ; Carga en el acumulador el puerto del PC
andi a,baja ; Elimina parte alta
cpi a,8 ; Comprueba si coincide con " Dato Recibido"
jrnz rec0 ; Vuelve a comprobarlo
jp firec ; Salta al final de subrutina
rec0 dec v ; Decrementa el nº de veces que quedan
jrz rec1 ; Si se ha ejecutado el bucle 256 veces decre
; el registro w
jp reci1 ; Salta al principio de rutina
rec1 dec w ;
jrz cuelge ; Si se, ha terminado el bucle cuelga el sistema
jp reci0 ;
cuelge jp reini ; cuelga el sistema
firec res 4,drpb ; Deja de indicar dato listo
ldi wdr,0feh ; Recarga el WDR
ret ; Vuelve
a rutina anterior
reini nop ; Entra en bucle cerrado para que se produzca
jp reini ; el
reset del sistema provocado por wdr
;*******************************************************************
;************** FIN COMPROBACION DATO RECIBIDO PARTE ALTA **********
;*******************************************************************
;*******************************************************************
;************** COMPROBACION DATO RECIBIDO PARTE BAJA **************
;*******************************************************************
reci2 ldi w,0ffh ; Carga nº max de veces del bucle
reci02 ldi v,0ffh ; Carga nº max de veces
reci12 ldi wdr,0feh ; Recarga el WDR
ld a,drpa ; Carga en el acumulador el puerto del PC
andi a,baja ; Elimina parte alta
cpi a,09H ; Comprueba si coincide con " Dato Recibido"
jrnz rec3 ; Vuelve a comprobarlo
jp firec2 ; Salta al final de subrutina
rec3 dec v ; Decrementa el nº de veces que quedan
jrz rec12 ; Si se ha ejecutado el bucle 256 veces decre
; el registro w
jp reci12 ; Salta al principio de rutina
rec12 dec w ;
jrz cuelge2 ; Si se, ha terminado el bucle cuelga el sistema
jp reci02 ;
cuelge2 jp reini ; cuelga el sistema
firec2 res 4,drpb ; Deja de indicar dato listo
ldi wdr,0feh ; Recarga el WDR
ret ; Vuelve
a rutina anterior
;****************************************************************************
;**************** FIN COMPROBACION DE DATO RECIBIDO PARTE BAJA **************
;****************************************************************************
;****************************************************************************
;**************** SUBRRUTINA DE COMPLEMENTACION DE DATOS ********************
;****************************************************************************
comple jrs 3,a,stb ; Comprueba el estado del bit 3 del
set 3,a ; acumulador y lo complementa, esto es
ret ; necesario para la correcta comunicacion
stb res 3,a ; con el PC
ret ;
;****************************************************************************
;************* FINAL SUBRRUTINA DE COMPLEMETANCION DE DATOS *****************
;****************************************************************************
;***********************************************************************
;*********************** TEMPORIZADOR PROGRAMABLE PARA EL INICIO *******
;***********************************************************************
temp jrnz inic
jp fin1
inic ldi v,0ach
sal2 ldi w,0ffh
sal1 ldi wdr,0feh ;Recarga el WATCHDOG para que no llege a ser 0
nop ;y se produzca un reset
nop
dec w
jrnz sal1
dec v
jp saltito
fin1 jp fin2
saltito jrnz sal2
dec a
ldi wdr,0feh
jrz fin2
jp temp
fin2 ldi wdr,0feh
ldi control,0aah
ret
;***************************************************************************
;********************** FINAL TEMPORIZADOR PROGRAMABLE *********************
;***************************************************************************
;****************************************************************************
;*********************** FINAL DE SUBRRUTINAS *******************************
;****************************************************************************
;****************************************************************************
;*************************** VECTORES DEL ST6 *******************************
;****************************************************************************
.org 0ff0h
adc nop ;Vector conv. A/D
reti
timer nop ;Vector del timer
reti
int2 nop ;Vector de PB y PC
reti
int1 jp comunica ;Vector
de PA
.org 0ffch
nmi nop ;Vector de NMI
reti
res jp reset ;Vector de RESET
.end