3. Rutinas de aplicaciones de la capa de enlace.
4. Rutinas de lectura del ibuttom.
5. Rutinas de lectura del teclado.
1. Rutina principal ( upuerta ).
El funcionamiento del sistema de control de acceso se realiza a través
de comunicaciones mutuas entre los
diferentes módulos de control de puerta y la unidad de control central.
Este último envía comando a través de
la red a los diferentes módulos y estos responden con operaciones
de acuerdo al comando enviado.
Como ejemplo de operación, se puede suponer lo siguiente : Control
Central pide envío de condición actual
a Puerta1, esto incluye estado de la puerta, estado del pestillo, estado
del buffer de teclado yestado del buffer de
botón. Si Puerta1 ha leído un botón y se encuentra
funcionando en el modo botón dará el aviso de buffer de botón
lleno. Ante esto Control Central pedirá el envío del código,
el cual al llegar será pasado a la base de datos a fin
conocer su validez. De acuerdo a los resultados que brinde la búsqueda
del código en la base de datos, Control
Central responderá con un mensaje de código correcto o incorrecto.
En el primero de ellos se accionará el pestillo
y en el otro no.
A fin de funcionar correctamente upuerta manejará las siguientes variables:
modo : indica en que modo de funcionamiento
se encuentra el módulo. Pueden ser BOTON,
TECLADO,
BOTON + TECLADO o BLOQUEADO .
condicion : indica la condición en que
se encuentra el módulo. Se tendrá un bit para cada condición
relevante
como son estado de la puerta, estado del pestillo, hay boton?, hay teclado?.
buffer_teclado : almacena los dígitos
que están siendo ingresados por el teclado
buffer_boton : almacena el código
leído por el teclado
buffer_tx : almacenamiento de frame a transmitir a través de la capa de enlace.
Implementación como máquina de estados.
La rutina principal de manejo del sistema de control de acceso de la puerta
será implementada como una
máquina de estados, la cual está dada en la figura 1. Las
inicializaciones pertinentes ya han sido realizadas.
Figura 1 : Máquina de estados upuerta.
Transiciones de estado .
A : llegó paquete
de red
B : código de botón
leído
C : código de teclado
leído
D : modo botón
E : modo teclado
F : modo botón+teclado
G : modo bloqueado
H : código correcto
T : fin del tempo de apertura
Estados.
RED : interacción con CONTROL CENTRAL a través
de la red. Se pregunta por paquete de red.
En caso de encontrarse uno listo, se procede a determinar el comando enviado
desde la PC. De acuerdo
a este último, se harán las operaciones necesarias y se transmitirá
la respuesta. Una vez transmitida la
respuesta, se pasa al estado siguiente de acuerdo a las condiciones de
transición.
Comandos posibles a ser enviados desde la PC y respuestas ante ellos.
ENVIAR_CONDICION : se pide el envío
del byte de condición. Se arma el frame de enlace y se lo
envía a través de la red.
ENVIAR_BOTON : pedido del envío
del código de botón almacenado. Se arma el frame de enlace
con
buffer_boton y se lo envía a través de la red.
ENVIAR_TECLADO : idéntico al anterior, solo que esta vez se envía buffer_teclado.
CODIGO_INCORRECTO : código no
válido enviado. Se desplega mensaje en el LCD y se reinicializa
la máquina de estados.
ACCIONAR_PESTILLO : el código
enviado es válido; por lo tanto se acciona el pestillo inicializando
al
temporizador de tiempo de apertura y desplegando mensaje en el LCD.
Se produce un cambio de estado a PES.
BOTON_CORRECTO : primera fase correcta
en el modo botón + teclado. Se autoriza la búsqueda de
teclas y se desplega mensaje de pedido de ingreso de código por
teclado.
CAMBIAR_MODO : se cambia la variable
modo de acuerdo a la información recibida desde CONTROL
CENTRAL . Esta acción provoca la reinicialización de todas
las variables.
RE_TX : Se pide retransmitir el último
frame. Su causa es un error en la transmisión terminado el tiempo
de
espera de respuesta en.la PC. Se vuelve a transmitir el último frame
que había quedado almacenado en
buffer_tx.
B_BOT : se busca un botón
en el lector de ibuttoms, en caso de encontrarse, se lee el código
y se lo
deposita en el buffer_boton, provocando así el paso al estado de
red, del cual no se volverá hasta que
no haya logrado transmitirse el código o venga un cambio de modo.
Si no hay botón se pregunta por
mensaje de red, en caso de dar afirmativo se pasa al estado de red a atender
el mensaje, en caso contrario
se sigue con la búsqueda de botones en el lector.
Se utiliza a la función leer_boton para el efecto de búsqueda de botones.
B_TEC : utilizando a la función
buscar_teclado, se pregunta por el ingreso de un código completo
de
6 dígitos. En caso afirmativo se pasará al estado RED y se
esperará allí hasta su transmisión. En caso
de no haber código de teclado completo se pregunta por mensaje de
red, si es que hay uno cambiamos
de estado y valos a tenderlo, de otra manera se sigue esperando a un código
de teclado completo.
PES : estado de pestillo accionado.
El temporizador por interrupciones contador de múltiplos de 30 ms
se halla corriendo. Cuando este llegue a 100 ( 3 segundos ) se apagará
el pestillo y se pasará al estado
de RED. Si mientras el pestillo se encuentra accionado se recibe un mensaje
de red se cambia al estado
de RED para atenderlo.
Figura 2 : Diagrama de flujo de upuerta.
Variables tipo bandera.
BUF_BOT : indica que el buffer de botón tiene un
código leído.
BUF_TEC : indica que el buffer de teclado tiene un código
de 6 teclas.
MODO_BT : solo para el modo boton+teclado, indica cuando ya se leyó
un botón con código aceptado por
CONTROL CENTRAL.
COD : indica
que el pestillo ha sido accionado, por lo tanto se debe pasar siempre del
estado de RED
al estado PES.
Las rutinas de comunicaciones se encargan de formar una capa de enlace
de datos, la cual provee de
servicios de transmisión y recepción de frames a las capas
superiores, en este caso a la capa de aplicación en
la cual se encuentra el sistema de control de acceso de la puerta.
Esta capa de enlace de datos cumple las funciones de formación de
frame de enlace de transmisión tanto como
de recepción de acuerdo al protocolo establecido y detección
de errores en el frame recibido con el posterior
descarte del frame en caso de estar erróneo.
Al diseñar esta capa de enlace, el objetivo es dejar libre a las
rutinas de aplicación de la tarea de transmisión
de datos, cumpliendo solo con la inicialización de tal tarea.
Se contarán con máquinas de estado de transmisión
y recepción de frames que funcionarán por interrupciones,
de tal
manera que la rutina de aplicación que desea transmitir un frame
a través de la capa de enlace solo debe
inicializar esta máquina de transmisión y pasarle el buffer
de transmisión indicado donde se encuentre la trama.
2.1. Protocolo de capa de enlace.
El diseño proveerá de una red broadcast sobre un par de hilos,
al cual se conectarán todos los elementos de la
misma. El acceso al canal estará controlado por CONTROL CENTRAL,
formando una red master-slave.
CONTROL CENTRAL transmitirá a cada módulo y este le responderá
solo a él.
Los bytes enviados en forma serial tendrán el formato UART con 9°bit.
En este modo de transmisión el puerto
serial del 8051 permite una opción de interrupción por recepción
solo si el 9°bit=1; con lo cual evitaremos que
todos los bytes del frame interrumpan al procesador. El byte que
contenga la dirección destino irá con el 9°bit =1,
quedando los restantes con el 9°bit = 0; de esta forma los módulos
solo serán interrumpidos por el byte de dirección,
en el cual preguntarán si la dirección destino corresponde
con la suya, de ser así cambian a modalidad de interrupción
con cualquier valor de 9°bit, recibiendo el resto del frame. Si la
dirección del frame no es la suya, no hacen caso
al resto del frame esperando por el siguiente byte con el 9°bit de
transmisión = 1.
Formato de frame de enlace.
DIR : dirección del destino ( 9°bit = 1)
N : número de bytes de dato sin incluir el CHKSM ( 9° bit = 0)
DATO 0 a DATO N –1 : bytes de dato.( 9° bit = 0)
CHKSM : Control de errores. xor de todos los bytes anteriores. (
9° bit = 0)
Máquina de estados de trasmisión.
La máquina de estados de transmisión está implementada
usando la rutina de servicio de interrupciones del
puerto serial y se presenta
como una máquina de estados en la figura 3.
La variable que mantendrá el estado es estado_tx.
Figura 3 : Máquina de estados de transmisión.
Transiciones
A : no hay inicio
de transmisión.
B : fin de transmisión
del byte de dirección.
C : fin de transmisión
del último byte de datos.
D : fin de transmisión
del CHKSM.
Estados.
T0 : estado inactivo,
la señal de habilitación del canal se mantiene en su nivel
no activo. Una función de servicio
para aplicación saca a la máquina de tx de este estado y
lo pone en T1.
T1 : se transmite el resto
de la trama del buffer de transmisión, todos con 9°bit = 0.
Se va calculando
paulatinamente el CHKSM de transmisión en una variable chksm_tx.
T2 : se transmite el CHKSM
resultante de todos los los bytes anteriores ( 9°bit
= 0).
Máquina de estados de recepción.
La máquina de estados de recepción está implementada
usando la rutina de servicio de interrupciones del
puerto serial y se presenta
como una máquina de estados en la figura 4.
La variable que mantendrá el estado es estado_rx.
Figura 4 : Máquina de estados de recepción.
Transiciones:
A
: se recibió un byte de dirección
( 9°bit=1) y la dirección coincide con la del módulo.
B
: se recibió un byte de dirección
( 9°bit=1) y la dirección no coincide con la del módulo.
C
: se recibió el numero de bytes de datos
N.
D
: se recibió el último byte de datos.
E
: se recibió el CHKSM y coincide con el
calculado.
F
: se recibió el CHKSM y no coincide con
el calculado.
G :
se leyó el frame recibido a través de la función de_enlace.
Estados :
R0
: estado de espera por un byte de dirección que
contenga la dirección del módulo.Durante este estado
el buffer de recepción no contiene ningún frame..
R1
: permite recibir el numero de bytes de datos para que
durante el estado R2 se pueda conocer el arribo
del último dato byte de dato.
R3
: se recibe el CHECK SUM y se verifica que coincida con
el calculado en los estados anteriores. Si
coincide el estado siguiente es R4.
R4
: estado que contiene un frame válido. Se lo utiliza
en la función de_enlace para saber si ya llegó un
paquete de ted. La función de_enlace reinicializa la máquina
luego de haber leído el frame.
No se implementa ningún temporizador para descartar algún
frame, simplemente un byte de dirección reinicializa la
máquina de recepción
y descarta el frame que se estaba recibiendo.
Funciones de servicio a la capa de aplicación.
a_enlace
Recibe como parámetro el buffer de transmisión e inicializa
la máquina de estados de transmisión enviando
el byte de dirrección buffer_tx[0] con el 9°bit=1 y forzando
el estado T1, si es que otra trama no se está
transmitiendo.
Si otra trama se está transmitiendo sale de la función y
devuelve 1. Si es que pudo transmitir devuelve 0.
Figura 5 : Diagrama de flujo de a_enlace
de_enlace
Pregunta
si un frame ha sido recibido, esto lo hace revisando el estado_rx, el cual
debe ser R4.
Si se recibió un frame devuelve la dirección del buffer de
recepción y reinicializa la máquina de recepción
En caso contrario devuelve 0.
Figura 6 : Diagrama de flujo de de_enlace
3. Aplicaciones de la capa de enlace.
enviar_condicion
Se envía el byte de condición utilizando los servicios de la capa de enlace.
Figura 7 : Diagrama de flujo para enviar_condicion
enviar_teclado
Se envía el contenido del buffer de teclado utilizando los servicios de la capa de enlace.
Figura 8 : Diagrama de flujo para enviar_teclado
enviar_boton
Se envía el contenido del buffer del botón utilizando los servicios de la capa de enlace.
Figura 9 : Diagrama de flujo para enviar_boton
4. Rutinas de lectura del ibuttom.
leer_boton
Rutina principal de lectura del ibuttom. Se pregunta por la existencia
de un botóna través de la función
boton_reset. Si hay un botón, se deshabilita la red ( interrupciones
del puerto serial ), a fin de mantener
confiable la temporización de lectura. Se procede a leer los 8 bytes
contenidos en el ibuttom con la función
boton_leer_byte. Una vez finalizados los 8 bytes, se vuelve a habilitar
la red y se controlan errores en el código
recibido a través de un código de detección de errores
CRC proveído por el fabricante del botón.
El botón trasmite también el byte CRC para hacer posible
esta operación. Si no hay errores, se devuelve 1 y en caso
contrario 0.
Figura 10 : Diagrama de flujo para leer_boton.
boton_reset
Envía el pulso de reset ( línea = 0 ) de 480 us al lector
del botón. Pasado este tiempo pone la línea a 1
y se queda a muetrearla . Si en los siguientes 64 us la línea permanece
en 1 no hay botón y se devuelve 0.
Si dentro del lapso de los 64 us halla la línea baja, se queda a
esperar que el botón levante nuevamente la línea
dentro de los próximos 3360 us. Si así sucede devuelve 1
indicando la presencia del botón.
boton_leer_byte
Se produce la temporización necesaria para leer el código
del botón. Esta consiste en bajar la línea a 0
por 1 us y luego volver a levantarla a 1 quedándose a esperar por
un tiempo máximo de 64 us. Si en ese
intervalo la línea se mantiene en alto se leyó un 1, en caso
contrario de haber bajado a 0 por un tiempo
de 15 us se toma al bit como 0.
boton_crc
Se realiza la detección de errores a través de un código
de redundancia cíclica proveído por el fabricante.
Esta función devuelve siempre el nuevo valor del byte crc, recibiendo
como parámetros el antiguo valor crc
y el nuevo byte de datos leído.
5. Rutinas de lectura del teclado numérico.
leer_teclado
Rutina principal de lectura del teclado.
A través de la función leer_tecla captura las teclas,
las cuales
son codificadas por codificar_tecla para luego ser ingresadas al
buffer de teclado. Una vez que una tecla ha
sido capturada y filtrada por leer_tecla la búsqueda de la
siguiente tecla queda suspendida, esto se realiza
para evitar que una tecla presionada ingrese más de una vez. La
función prueba_tecla_presionada puede
volver a habilitar la búsqueda de teclas en caso de no encontrar
tecla presionada por un intervalo de tiempo
específico. La tecla * está designada como reinicialización
deingreso de código, por lo tanto si se la detecta
CTECLAS se hace iguala a cero comenzando todo de nuevo.
La rutina leer_teclado devuelve 1 si un código de 6 teclas ha ingresado
y 0 si todavía no ha ocurrido.
Esta función es continuamente llamada en el estado B_TEC, si todavía
no se ha detectado 6 teclas o no haya
mensaje desde la red.
Variables.
BUSCAR_TECLA : bandera de habilitación
de búsqueda de tecla.La puede habilitar prueba_tecla_presionada
y la deshabilita leer_tecla al capturar una tecla.
TECLA_VALIDA : bandera
de tecla capturada. La habilita leer_tecla al capturar una tecla.
CTECLAS
: contador del número de teclas capturadas hasta el momento.
Figura : Diagrama de flujo de leer_teclado.
prueba_
tecla_presionada
Muestrea el teclado por un determinado númerode veces buscando una
tecla presionada. Si la encuentra
no habilita el barrido ( BUSCAR_TECLA = 0). Su fucnión principal
es mo permitir el reingreso de una tecla
ya capturada.
El número de veces está fijado en 10, lo cual da un muestreo
durante 2.1 ms con 210 us de período de
muestreo. Este valor es válido para una frecuencia de 11.059 MHz
y de acuerdo al código utilizado.
El valor fue fijado basándome en pruebas con el teclado.
Figura : Diagrama de flujo de prueba_tecla_presionada.
leer_tecla
Rutina
encargada de la captura de una tecla y de asegurarse de ella es una tecla
válida sin rebotes mecánicos.
En la rutina se barren las
columnas del teclado, si no se detecta ninguna tecla se sale de la rutina.
En caso de detectarse alguna,
se la almacena en la variable local TECLA, y se sigue realizando el barrido.
A esta tecla capturada se
la considera válida solo si se da 10 veces de seguido.
Si se cumple la condición
citada se sale de la función y se levanta la bandera de tecla válida.
Figura
: Diagrama de flujo para leer_tecla
TECLA_PROC : Bandera que
indica que una tecla está en proceso.
Cx
: Contador de veces para la columna x
codificar_tecla
Se procede a la codificación
de la tecla desde el formato de muestreo a su correspondiente valor ASCII.
La tecla no codificada se recibe como parámetro y se devuelve a
la tecla codificada en ASCII.
Figura : Diagrama de flujo para codificar_tecla
lcd_enviar_instruccion
Se envía un comando al LCD, produciendo la temporización
necesaria para el efecto. La instrucción enviada es
recibida como parámetro de la función que la llame .
Figura : Diagrama de flujo para lcd_enviar_instruccion
lcd_enviar_dato
Se envía un dato a desplegar en el LCD, produciendo la temporización
necesaria para el efecto.El dato enviado
es recibido como parámetro de la función que la llame .
Figura : Diagrama de flujo para lcd_enviar_dato
lcd_espera
Se produce un estado de espera hasta que el LCD driver haya completado
la operación recomendada.
Esta demora depende de la operación, por lo tanto se la incluye
como una función, y no simplemente como
un retardo. Básicamente se produce temporización para lectura
del estado del estado del driver y se lee el
valor lógico del pin 8 del bus de datos ( P2.7 ). Si este es 0,
el driver ya ha completado la operación.
Figura : Diagrama de flujo para lcd_espera
lcd_borrar
Se envía el comando de borrar_lcd al LCD driver.
Figura : Diagrama de flujo para lcd_borrar
lcd_iniciar
Se envían los comandos de inicialización al LCD, como ancho
del bus de datos, tipo de carateres a desplegar,
dirección de desplazamiento. Recibe como parámetro el modo
de funcionamiento ( los dos primeros factores
citados), y además trasnmite el comado de encendido ( OE h) y de
desplazamiento hacia la derecha ( 06 h ).
Figura : Diagrama de flujo para lcd_iniciar
lcd_men1
Se despliega el mensaje " Codigo
correcto " o el mensaje " Código
incorrecto ", de acuerdo al parámetro
TIPO recibido. Para el primer caso TIPO = 1 y TIPO = 0 para el último.
Figura : Diagrama
de flujo para lcd_men1