Subido por Rodrigo Aldebaran Martinez Flores

MarFlo 6IM1 P2 (1)

Anuncio
Instituto Politécnico Nacional
Centro de Estudios científicos y Tecnológicos 9: “Juan de Dios Bátiz”
Microelectrónica programable
Practica 2: “MULTIPLEXADO “MANEJO DE UN TECLADO MATRICIAL DE 4X4”.
(ACTUALIZACIÓN DEL TIEMPO).
Alumno: Martinez Flores Rodrigo Aldebarán
Profesor: Jesús Alberto Olivares Vargas
Grupo: 6IM1
Objetivo: El alumno comprende el funcionamiento de un teclado matricial de 4x4,
además de aprender a manipular el mismo. También adquiere el conocimiento para
desarrollar un programa que permita manipular el tiempo de un reloj de tiempo real.
Desarrollo Teórico de la practica 2: “MULTIPLEXADO “MANEJO DE UN TECLADO
MATRICIAL DE 4X4”.(ACTUALIZACIÓN DEL TIEMPO).
Un teclado matricial es un dispositivo que agrupa varios pulsadores y permite
controlarlos empleando un número de conductores inferior al que necesitaríamos al
usarlos de forma individual. Podemos emplear estos teclados como un controlador
para un autómata o un procesador como Arduino.
Estos dispositivos agrupan los pulsadores en filas y columnas formando una matriz,
disposición que da lugar a su nombre. Es frecuente una disposición rectangular pura
de NxM columnas, aunque otras disposiciones son igualmente posibles.
Los teclados matriciales son frecuentes en electrónica e informática. De hecho, los
teclados de ordenador normales son teclados matriciales, siendo un buen ejemplo
de teclado matricial con disposición no rectangular.
Una de las desventajas de usar un teclado matricial es que pueden causar
problemas cuando se pulsa más de una tecla simultáneamente. Este es uno de los
motivos por el que los teclados de ordenador usan una disposición no rectangular,
agrupando ciertas teclas en circuitos diferentes (Ctrl, Alt, Shift...).
¿Cómo funciona un teclado matricial?
Como ya mencioné anteriormente, un teclado matricial agrupa los pulsadores en
filas y columnas formando una matriz, lo que permite emplear un número menor de
conductores para determinar las pulsación de las teclas.
La siguiente imagen muestra, a modo de ejemplo, una disposición rectangular de
4x4.
Para detectar la pulsación de una tecla actuaremos de forma similar a la lectura
simple de un pulsador. En resumen, ponemos a tierra un extremo del pulsador, y el
otro lo conectamos a una entrada digital con una resistencia de pull-up.
Para leer todas las teclas tendremos que hacer un barrido por filas. En primer lugar
ponemos todas las filas a 5V, y definimos todas las columnas como entradas con
resistencia de pull-up.
Progresivamente ponemos una fila a 0V, y leemos las entradas de la columna. Una
vez realizada la lectura volvemos a ponerla a 5V, pasamos a la siguiente fila, y
volvemos a realizar el progreso hasta recorrer todas las filas.
Para detectar NxM pulsadores necesitamos sólo N+M conductores. Por tanto ahorro
de conductores es superior cuanto más grandes sean N y M, y más parecidos entre
sí. (ej: 16 pulsadores en 2x8 necesitan 10 conductores, y en 4x4 sólo 8
conductores.)
La mayor desventaja de la disposición matricial es que pueden dar problemas al
detectar la pulsación de múltiples teclas de forma simultánea.
Interrupciones
Una interrupción es una suspensión temporal de la ejecución de un proceso, para
pasar a ejecutar una subrutina de servicio de interrupción, la cual, por lo general, no
forma parte del programa, sino que pertenece al sistema operativo o al BIOS. Una
vez finalizada dicha subrutina, se reanuda la ejecución del programa.
Las interrupciones son generadas por los dispositivos periféricos habilitando una
señal del CPU (llamada IRQ del inglés "interrupt request") para solicitar atención de
este. Por ejemplo. cuando un disco duro completa una lectura solicita atención al
igual que cada vez que se presiona una tecla o se mueve el ratón.
La primera técnica que se empleó para esto fue el polling, que consistía en que el
propio procesador se encargara de sondear los dispositivos periféricos cada cierto
tiempo para averiguar si tenía pendiente alguna comunicación para él. Este método
presentaba el inconveniente de ser muy ineficiente, ya que el procesador consumía
constantemente tiempo y recursos en realizar estas instrucciones de sondeo.
El mecanismo de interrupciones fue la solución que permitió al procesador
desentenderse de esta problemática, y delegar en el dispositivo periférico la
responsabilidad de comunicarse con él cuando lo necesitara. El procesador, en este
caso, no sondea a ningún dispositivo, sino que queda a la espera de que estos le
avisen (le "interrumpan") cuando tengan algo que comunicarle (ya sea un evento,
una transferencia de información, una condición de error, etc.).
Con lo citado anteriormente se puede aseverar que las interrupciones dentro de la
programación son software.
Las interrupciones se utilizan:
a) En la detección de eventos catastróficos para el sistema, tales como las fallas
súbitas en las fuentes de alimentación. Por medio de una interrupción el
microprocesador puede ser alertado a tiempo de preservar la información
vital y desconectar los dispositivos que puedan dañarse.
b) En dispositivos donde el microprocesador no necesita obtener información
con mucha frecuencia. Por ejemplo, en sistemas de alarma, ya que el
microprocesador no sabe cuándo va a aparecer una situación que requiera
sus servicios. El dispositivo genera una interrupción cuando llega el
momento, y mientras tanto el microprocesador puede ejecutar otras tareas.
c) En la atención a dispositivos periféricos que son mucho más lentos que el
microprocesador: teclados, pantallas, impresoras. En vez de que el
microprocesador los espere, es más eficiente que los dispositivos lo
interrumpan cuando tengan algo nuevo que enviar o estén listos para recibir.
d) En el servicio de periféricos de alta velocidad (discos) o dispositivos para los
cuales sea muy difícil mantener la información hasta el momento en que el
microprocesador la solicite.
Las interrupciones principalmente se clasifican en 2 tipos inhibibles y no inhibibles.
Cuando se activa una entrada de INTERRUPCIÓN NO INHIBIBLE, el
microprocesador siempre es interrumpido, es decir, la señal de interrupción es
aceptada bajo cualquier condición, es por esto que las interrupciones no inhibibles
son las mas apropiadas para manejar eventos catastróficos.
Por otro lado, cuando se activa una entrada de INTERRUPCION INHIBIBLE, el
microprocesador reconoce la interrupción solamente si esa entrada se encuentra
habilitada. Las entradas de interrupción inhibibles se habilitan o inhabilitan bajo el
control del programa. Si la entrada está inhabilitada, el microprocesador ignora la
interrupción.
En el caso particular del PIC 16F877A al producirse una interrupción, el PIC salta
automáticamente a la dirección (0x0004) del vector de interrupción de la memoria
de programa y ejecuta la porción de programa, correspondiente a la atención de la
interrupción, hasta encontrar la instrucción RETFIE. Al encontrar dicha instrucción,
abandona la interrupción y retorna a la posición de memoria del programa principal
desde la que salto al producirse la interrupción.
La familia PIC16F87XA tiene hasta 14 fuentes de interrupción. Posee un registro de
control, INTCON que permite la habilitación de interrupciones y el manejo de los
flags. La habilitación general se activa mediante el bit GIE (INTCON<7>), el cual es
desactivado en el Reset, por lo tanto, hay que habilitarlo por programa.
Timer 0
Los Timer o temporizadores son módulos integrados en el Pic que permite realizar
cuentas tanto de eventos internos como externos. Cuando la cuenta es interna se
habla de temporización (cuenta pulsos de reloj) y cuando la cuenta es externa se
habla de contador.
El bloque funcional Timer 0 es un contador (registro) de 8 bits, incrementado por
hardware y programable. La cuenta máxima es de 255 (el incremento es constante
e independiente).
Los registros implicados en la configuración del TIMER 0 son los siguientes:
•
•
•
OPTION_REG: Configura el “hardware” del TIMER 0 o WDT.
INTCON: Permite trabajar con la interrupción del TIMER 0.
TRISA: Habilita el pin RA4 del puerto a.
El tiempo de desbordamiento del Timer 0 se calcula según la siguiente ecuación.
Tint = (256- Carga TMR0) *P.TCM
Donde TCM es el ciclo de máquina que se puede calcular mediante la ecuación: T CM
= (1/FOSC)*4
Tiempo mínimo.
Si tmr0 = 255 y P = 2.
Tint = (256- 255) * 2 * 0.000001 = 2 micro segundos.
Tiempo máximo.
Si tmr0 = 0 y P = 256.
Tint = (256- 0) * 256 * 0.000001 = 65.5 mili segundos.
LCD de 16 Caracteres por una línea
Sigla del inglés Liquid Cristal Display, 'representación visual por cristal líquido',
sistema que utilizan determinadas pantallas electrónicas para mostrar información
visual.
Cada píxel de un LCD típicamente consiste en una capa de moléculas alineadas
entre dos electrodos transparentes, y dos filtros de polarización, los ejes de
transmisión de cada uno que están (en la mayoría de los casos) perpendiculares
entre sí. Sin cristal líquido entre el filtro polarizante, la luz que pasa por el primer
filtro sería bloqueada por el segundo (cruzando) polarizador.
La superficie de los electrodos que están en contacto con los materiales de cristal
líquido es tratada a fin de ajustar las moléculas de cristal líquido en una dirección
en particular. Este tratamiento suele ser normalmente aplicable en una fina capa
de polímero que es unidireccionalmente frotada utilizando, por ejemplo, un paño. La
dirección de la alineación de cristal líquido se define por la dirección de frotación.
Antes de la aplicación de un campo eléctrico, la orientación de las moléculas de
cristal líquido está determinada por la adaptación a las superficies. En un
dispositivo twisted nematic, TN (uno de los dispositivos más comunes entre los de
cristal líquido), las direcciones de alineación de la superficie de los dos electrodos
son perpendiculares entre sí, y así se organizan las moléculas en una
estructura helicoidal, o retorcida. Debido a que el material es de cristal líquido
birrefringente, la luz que pasa a través de un filtro polarizante se gira por la hélice
de cristal líquido que pasa a través de la capa de cristal líquido, lo que le permite
pasar por el segundo filtro polarizado. La mitad de la luz incidente es absorbida por
el primer filtro polarizante, pero por lo demás todo el montaje es transparente.
Cuando se aplica un voltaje a través de los electrodos, una fuerza de giro orienta
las moléculas de cristal líquido paralelas al campo eléctrico, que distorsiona la
estructura helicoidal (esto se puede resistir gracias a las fuerzas elásticas desde
que las moléculas están limitadas a las superficies). Esto reduce la rotación de
la polarización de la luz incidente, y el dispositivo aparece gris. Si la tensión aplicada
es lo suficientemente grande, las moléculas de cristal líquido en el centro de la capa
son casi completamente desenrolladas y la polarización de la luz incidente no es
rotada ya que pasa a través de la capa de cristal líquido. Esta luz será
principalmente polarizada perpendicular al segundo filtro, y por eso será bloqueada
y el pixel aparecerá negro. Por el control de la tensión aplicada a través de la capa
de cristal líquido en cada píxel, la luz se puede permitir pasar a través de distintas
cantidades, constituyéndose los diferentes tonos de gris.
El efecto óptico de un dispositivo twisted nematic (TN) en el estado del voltaje es
mucho menos dependiente de las variaciones de espesor del dispositivo que en el
estado del voltaje de compensación. Debido a esto, estos dispositivos suelen usarse
entre polarizadores cruzados de tal manera que parecen brillantes sin tensión (el
ojo es mucho más sensible a las variaciones en el estado oscuro que en el brillante).
Estos dispositivos también pueden funcionar en paralelo entre polarizadores, en
cuyo caso la luz y la oscuridad son estados invertidos. La tensión de compensación
en el estado oscuro de esta configuración aparece enrojecida debido a las pequeñas
variaciones de espesor en todo el dispositivo. Tanto el material del cristal líquido
como el de la capa de alineación contienen compuestos iónicos. Si un campo
eléctrico de una determinada polaridad se aplica durante un período prolongado,
este material iónico es atraído hacia la superficie y se degrada el rendimiento del
dispositivo. Esto se intenta evitar, ya sea mediante la aplicación de una corriente
alterna o por inversión de la polaridad del campo eléctrico que está dirigida al
dispositivo (la respuesta de la capa de cristal líquido es idéntica,
independientemente de la polaridad de los campos aplicados)
Es un dispositivo LCD con un solo renglón de 16 caracteres, pero electrónicamente
está dividido en dos secciones de 8 caracteres. Cada una de estas secciones se
maneja como si fuese un renglón de 8 caracteres, es decir, si se desea escribir en
la primera sección debe enviarse antes el comando es 80H y para escribir en la
segunda sección, C0H.
Descripción de los pines.
1.- GND
Señal de referencia a tierra.
2.- VCC.
Voltaje de alimentación 5 VCD.
3.- Vo.
4.- R/S.
5.- R/W.
6.- E.
7.- D0.
8.- D1.
9.- D2.
10.- D3.
11.- D4.
12.- D5.
13.- D6.
14.- D7.
15.- LED
16.- LED
Voltaje de contraste.
Modo de operación “0” lógico comandos o “1” lógico datos.
“0” lógico LCD en modo escritura, “1” lógico LCD en modo lectura.
Pin utilizado para ingresar a la LCD un comando o dato.
Bit 0 bus de datos.
Bit 1 bus de datos.
Bit 2 bus de datos.
Bit 3 bus de datos.
Bit 4 bus de datos.
Bit 5 bus de datos.
Bit 6 bus de datos.
Bit 7 bus de datos.
Para inicializar la LCD se tienen que enviar los siguientes comandos.
Colocar la LCD en modo comandos pin R/S en “0” lógico.
Primer comando
Segundo comando
Tercer comando
Cuarto comando
Quinto comando
38h.
01h.
06h.
0Ch.
80h.
Los dígitos en la memoria de la LCD se encuentran en las siguientes direcciones.
Dig 1 Dirección 80h.
Dig 2 Dirección 81h.
Dig 3 Dirección 82h.
Dig 4 Dirección 83h.
Dig 5 Dirección 84h.
Dig 6 Dirección 85h.
Dig 7 Dirección 86h.
Dig 8 Dirección 87h.
Dig 9 Dirección C0h.
Dig 10 Dirección C1h.
Dig 11 Dirección C2h.
Dig 12 Dirección C3h.
Dig 13 Dirección C4h.
Dig 14 Dirección C5h.
Dig 15 Dirección C6h.
Dig 16 Dirección C7h.
Funcionamiento del hardware
En la imagen podemos apreciar como el microcontrolador PIC16F877A está
conectado directamente a la pantalla LCD mediante el puerto C, por otro lado, el
teclado matricial también se conecta directamente al PIC mediante el puerto B.
La ventaja de usar una LCD es que en cuestión de hardware se simplifica mucho,
sin embargo, el software es más complicado.
El funcionamiento del sistema desarrollado es el siguiente, el PIC tiene conectado
conectado en su puerto C a las 8 terminales del LCD que controlarán los segmentos,
este puerto es el encargado de enviar la información al display, permitiendo saber
cuál es el mensaje que queremos mostrar, la LCD en sí ya es un circuito integrado
que posee sus propios elementos, esto nos permite simplificar el circuito.
Al display se conectan otros elementos, por ejemplo, el VCC, que da alimentación
al display, el VSS que es la tierra del display y el VEE que permite modular la
intensidad de los leds del display, motivo por el cual hay una resistencia variable
conectada a esa terminal, a mayor resistencia menor será la intensidad de luz de la
iluminación del panel, a menor resistencia la iluminación será más intensa.
El teclado matricial se conecta directamente al puerto B del PIC, de los pines RB0
a RB3 se encargan de controlar las entradas del teclado matricial, mientras que de
los pines RB4 a RB7 controlan las salidas, ahí es donde se ve rflejado el estado de
las teclas, y de esta manera podremos saber que tecla se esta presionando.
Funcionamiento del software
Como se menciono anteriormente, el hardware del sistema es muy reducido y
simple, pero en consecuencia a esto el software es mucho más complejo.
La imagen anterior muestra cómo se establece la dirección de diferentes registros
que se utilizarán, el contador 1, 2 y 3, aparte de las constantes para las unidades y
decenas en el contador, también se declaran los buffers, esto solamente es declarar
la posición en la que se encuentra el registro, mas no el valor que va a guardar.
En este paso se definen las constantes que emplearemos durante el desarrollo del
programa, entre estas destacan las teclas del teclado matricial de 4x4, eso nos
permitirá saber que tecla se está seleccionando de cada fila, los valores se repiten
para cada fila.
Posterior a esto se definen las banderas de los registros
Ahora debemos de asignar los valores en binario para definir cuales puertos del
PIC actuaran como entradas o salidas, en este caso solo utilizaremos el puerto b
como entrada y salida, es decir de RB0 a RB3 actuaran como salidas, mientras que
de RB4 a RB7 serán entradas. Del puerto C se utiliza únicamente como salida, un
pin del puerto A también será utilizado como salida.
Para el puerto A utilizaremos 2 pines, los cuales utilizaremos para controlar el RS y
E de la pantalla LCD. Vamos a utilizar los pines RA0 Y RA1, por lo que al definir el
valor en binario del puerto pondremos ‘111100’ de tal forma que los dos primeros
pines (del menos al más significativo) serán salidas, mientras que los otros 4 serán
salidas ya que no los vamos a utilizar.
Para el puerto B utilizaremos todos los pines, pero los primeros 4 los definiremos
como salidas para asignar el valor de la fila que queremos leer, mientras que los 4
últimos serán entradas, que nos permitirán leer la columna en la que se está
presionando la tecla. Podemos ver en la imagen que se define el valor del puerto
como ‘11110000’.
Podemos apreciar como el puerto C en la parte inferior tiene la instrucción de definir
las constantes PROGC como ‘00000000’, lo que quiere decir que funcionarán como
salidas.
El puerto C y D no se utilizan, por lo que sus valores del puerto se definen como
entradas, tal como se puede apreciar en la siguiente imagen.
Para el puerto A utilizaremos 2 pines, los cuales utilizaremos para controlar el RS y
E de la pantalla LCD. Vamos a utilizar los pines RA0 Y RA1, por lo que al definir el
valor en binario del puerto pondremos ‘111100’ de tal forma que los dos primeros
pines (del menos al más significativo) serán salidas, mientras que los otros 4 serán
salidas ya que no los vamos a utilizar.
Para el puerto B utilizaremos todos los pines, pero los primeros 4 los definiremos
como salidas para asignar el valor de la fila que queremos leer, mientras que los 4
últimos serán entradas, que nos permitirán leer la columna en la que se está
presionando la tecla. Podemos ver en la imagen que se define el valor del puerto
como ‘11110000’.
Podemos apreciar como el puerto C en la parte inferior tiene la instrucción de definir
las constantes PROGC como ‘00000000’, lo que quiere decir que funcionarán como
salidas.
El puerto C y D no se utilizan, por lo que sus valores del puerto se definen como
entradas, tal como se puede apreciar en la imagen anterior.
Una vez fueron definidos los puertos, se escriben las subrutinas de vector reset y
vector de interrupción.
En el vector de interrupción se definen los valores de registros que nos permitirán
llevar a cabo el conteo mediante hardware.
El vector de interrupción antes de realizar la cuenta de los registros hace un
respaldo de todos los valores encontrados en algunos registros especiales, como el
STATUS, el PCLATH, y el W.
En la segunda parte de esta subrutina se restauran los valores iniciales y se regresa
al programa principal, gracias al principio de pila que se definió en la parte teórica.
Posteriormente se escribe la subrutina de interrupciones, en esta subrutina se
incrementa el contador de milisegundos, aparte de que se comprueba que el valor
del registro se haya alcanzado, esta subrutina nos permitirá conocer el momento en
el que se completó el segundo.
Se definen valores de los prescaladores para conseguir el tiempo que queremos.
Esta subrutina se complementa con la que se definió anteriormente.
Posteriormente está la subrutina de inicio del PIC, en este se definen el valor de
algunos registros y banderas. Se cargan a los registros especiales que manejan el
comportamiento de los pines los estados de cada uno de los puertos, salidas y
entradas.
En el programa principal tenemos algunas subrutinas que es importante definir, la
primera subrutina es “prog_ini”, esta llama a la subrutina de inicio que se definió
anteriormente. La segunda subrutina es la “ini_LCD” esta permite cargar los valores
necesarios a la LCD para inicializarla y para que funcione correctamente, es
importante llevar a cabo esta subrutina para poder visualizar correctamente los
datos en la LCD.
Empieza el loop principal y tenemos varias subrutinas, la subrutina “muestra time”,
seguido de la subrutina encargada de contar el tiempo. Tenemos la subrutina nueva
de “barre teclado” y otra subrutina nueva llamada “muestra tecla.
Subrutina de muestra de tiempo, nos permite visualizar los valores en el display en
formato militar, un reloj centrado en el que tenemos formato de 24 horas,
separadas por dos puntos “:”.
Podemos ver como muestra las variables “dechor”, “unihor”, “decmin”, etc. Estas
variables hacen referencia a las decenas de horas, unidades de horas y así
sucesivamente hasta las unidades de segundo.
Tenemos la subrutina de barrido de teclado, esta nos permitirá leer que tecla fue
presionada, este valor de la tecla será guardado en el registro ‘var_tecopri’, el cual
utilizaremos para comprobar que teclas fueron presionadas en otras subrutinas.
Posteriormente tenemos la subrutina de actualización de tiempo, esta nos permite
modificar el tiempo utilizando el teclado matricial una vez que fue presionada la tecla
“A” del teclado matricial, después de esto debemos ingresar los valores al teclado y
una vez tengamos el tiempo actualizado presionamos la tecla “B” para continuar con
el conteo.
Después tenemos la subrutina que revisa la tecla, esta se encarga de comprobar
que la tecla presionada no sea la “A”, para que una vez sea presionada se inicie la
subrutina de actualización de tiempo. Después de esta subrutina sigue una
subrutina de espera de int. De 1 segundo, esta permite utilizando el TMR0 hacer la
cuenta de 1 segundo para el reloj.
Después de esta subrutina de retardo tenemos la subrutina encargada de contar en
el reloj, apoyándose de la subrutina de retardo de 1 segundo que se definió
anteriormente.
Tenemos finalmente varias subrutinas, entre las que se encuentran subrutinas de
inicio del LCD, y varias subrutinas de retardo de milisegundos.
Desarrollo practico de la practica 2: “MULTIPLEXADO “MANEJO DE UN TECLADO
MATRICIAL DE 4X4”.(ACTUALIZACIÓN DEL TIEMPO).
Mediciones realizadas con voltímetro en el bus de datos del PIC 16F877 A
Se tienen valores lógicos de 0 y 1.
Puerto A del microcontrolador
Se observa que la terminal RS toma valores lógicos de 0 y 1. Mientras que la
terminal Enable siempre presenta 5 volts, para que se pueda activar la LCD.
Puerto B del microcontrolador
Cuando recibe un 0 lógico nos refleja un valor de 0 volts, mientras que cuando recibe
un 1 arroja un valor de 5 volts.
Mediciones con osciloscopio en el bus de datos
Mediciones realizadas con el osciloscopio en el puerto A
Diagrama esquematico de la practica 2: “MULTIPLEXADO “MANEJO DE UN
TECLADO MATRICIAL DE 4X4(ACTUALIZACIÓN DEL TIEMPO).”
Diagrama de Flujo
Codigo Fuente de la practica 2: “MULTIPLEXADO “MANEJO DE UN
TECLADOMATRICIAL DE 4X4”.(ACTUALIZACIÓN DEL TIEMPO).
;INSTITUTO POLITECNICO NACIONAL.
;CECYT 9 JUAN DE DIOS BATIZ.
;
;PRACTICA 1
;TIMER 0 “MANEJO DE UNA PANTALLA LCD”
;
;GRUPO: 6IM1 .
;
;INTEGRANTE: Martinez Flores Rodrigo Aldebaran
;
;Este programa nos permite manipular un reloj de tiempo real mostrado en una LCD
de 16x1 mediante un teclado matricial de 4x4
;------------------------------------------------------------------------------------------------------------------list p=16f877A;
;#include "C:\Program Files (x86)\Microchip\MPASM Suite\P16F877A.INC";
#include "C:\Program Files (x86)\Microchip\MPASM Suite\P16F877A.INC";
;Bits de configuracion.
__config _XT_OSC & _WDT_OFF & _PWRTE_ON & _BODEN_OFF & _LVP_OFF
& _CP_OFF; ALL
;------------------------------------------------------------------------------------------------------------------;
;fosc=4 MHz.
;Ciclo de trabajo del PIC = (1/fosc)*4 = 1 µs.
;t int:= (256 - R) * (P) * ((1/3579545)*4) = 1.0012ms // Tiempo de interrupcion
; R = 249, P = 128
;Frec int = 1 / t int = 874 Hz.
;------------------------------------------------------------------------------------------------------------;Definicion de las variables del programa en RAM.
resp_w
equ 0x20;
resp_status
equ 0x21;
res_pclath
equ 0x22;
res_fsr
equ 0x23;
presc_1
equ 0x24;
.001
100
5
presc_2
equ 0x25;
t int = t intb * presc_1 *
presc_2
banderas
equ 0x26;
cont_milis
equ 0x27;
select_time
equ 0x28;
uniseg
equ 0x29;
decseg
unimin
decmin
unihor
dechor
cta_24
Var_teclado
Var_tecopri
Contador1
Contador2
Contador3
bannar
banperr
test
temporal_num
equ 0x30;
equ 0x31;
equ 0x32;
equ 0x33;
equ 0x34;
equ 0x35;
equ 0x35;
equ 0x36;
equ 0x37;
equ 0x38;
equ 0x39;
equ 0x40;
equ 0x41;
equ 0x42;
equ 0x41;
;Constantes.
M
N
L
equ
equ
equ
.3;
.255;
.255;
No_haytecla
equ
0XF0;
Tec_1
Tec_2
Tec_3
Tec_div
Tec_4
Tec_5
Tec_6
Tec_B
Tec_7
Tec_8
Tec_9
Tec_c
Tec_clear
Tec_0
Tec_igual
Tec_suma
equ
equ
equ
0XE0;
0XD0;
0XB0;
equ
equ
equ
equ
equ
equ
equ
equ
equ
equ
equ
equ
equ
0X70;
0XE0;
0XD0;
0XB0;
0X70;
0XE0;
0XD0;
0XB0;
0X70;
0XE0;
0XD0;
0XB0;
0X70;
;------------------------------------------------------------------------------------------------------------;Banderas del registro banderas
ban_int
equ .0; El valor .0 es asignado a bandera int, bandera utilizada
para comunicar la subrutina de interrupcion con el programa principal
sin_bd1
equ .1;
sin_bd2
equ .2;
sin_bd3
equ .3;
sin_bd4
equ .4;
sin_bd5
equ .5;
sin_bd6
equ .6;
sin_bd7
equ .7;
bannab
equ .7;
banperb
equ .7;
;-------------------------------------------------------------------------------------------------------------
; Asignación de los puertos de I/0.
; Puerto A.
RS_LCD
equ .0;Pin de la salida modo comandos o modo
datos de la LCD
Enable_LCD
equ .1;Pin de salida de Enable LCD
Sin_UsoRA2
equ .2;sin uso
Sin_UsoRA3
equ .3;sin uso
Sin_UsoRA4
equ .4;sin uso
Sin_UsoRA5
equ .5;sin uso
progA
;Puerto B.
Act_Ren1
Act_Ren2
Act_Ren3
Act_Ren4
Col_1
Col_2
Col_3
Col_4
progb
;Puerto C.
Bit_D0LCD
Bit_D1LCD
Bit_D2LCD
Bit_D3LCD
Bit_D4LCD
Bit_D5LCD
Bit_D6LCD
equ b'111100';Def. la config. de los bits del pto. a.
equ .0;Pin de salida para activar el renglón 1 del teclado.
equ .1;Pin de salida para activar el renglón 2 del teclado.
equ .2;Pin de salida para activar el renglón 3 del teclado.
equ .3;Pin de salida para activar el renglón 4 del teclado.
equ .4;Pin de entrada para leer el código de la tecla oprimida.
equ .5;Pin de entrada para leer el código de la tecla oprimida.
equ .6;Pin de entrada para leer el código de la tecla oprimida.
equ .7;Pin de entrada para leer el código de la tecla oprimida.
equ b'11110000'; // Programación inicial del puerto B.
equ
equ
equ
equ
equ
equ
equ
.0;Bit 0 de datos o comandos para la LCD
.1;Bit 1 de datos o comandos para la LCD
.2;Bit 2 de datos o comandos para la LCD
.3;Bit 3 de datos o comandos para la LCD
.4;Bit 4 de datos o comandos para la LCD
.5;Bit 5 de datos o comandos para la LCD
.6;Bit 6 de datos o comandos para la LCD
Bit_D7LCD
progc
;Puerto D.
Sin_UsoRD0
Sin_UsoRD1
Sin_UsoRD2
Sin_UsoRD3
Sin_UsoRD4
Sin_UsoRD5
Sin_UsoRD6
Sin_UsoRD7
progD
; Puerto E.
Sin_UsoRE0
Sin_UsoRE1
Sin_UsoRE2
progE
equ
.7;Bit 7 de datos o comandos para la LCD
equ b'00000000'; // Programación inicial del puerto C como
equ
equ
equ
equ
equ
equ
equ
equ
.0;sin uso
.1;sin uso
.2;sin uso
.3;sin uso
.4;sin uso
.5;sin uso
.6;sin uso
.7;sin uso
equ B'11111111';Programación inicial del puerto D como
equ
equ
equ
.0;sin uso
.1;sin uso
.2;sin uso
equ B'111';Programación inicial del puerto E como
;-----------------------------------------------------------------------------------------------------------------------------------------------------;====================
;== Vector Reset ==
;====================
org 0x0000;
vec_reset
clrf PCLATH; Borra el contenido del registro pclath.
goto prog_prin; Salto incondicional a la etiqueta
prog_prin
;-----------------------------------------------------------------------------------------------------------------------------------------------------;==============================
;== Vector de Interrupcion ==
;==============================
org 0x0004; Las instrucciones del código fuente que
siguen a esta directiva se ensamblan a partir de la posición indicada por 0x0004
vec_int
movwf resp_w; respalda el estado del registro w
movf status,w;
movwf resp_status; respalda banderas de la alu
clrf status;
movf pclath,w;
movwf res_pclath;
clrf pclath;
movf fsr,w;
movwf res_fsr;
btfsc intcon,tmr0if;
call rutina_int;
sal_int
movlw .131;
movwf tmr0;
movf res_fsr,w;
movwf fsr;
movf res_pclath,w;
movwf pclath;
movf resp_status,w;
movwf status;
nop;
retfie;
;------------------------------------------------------------------------------------------------------------;=====================================
;== Subrutina de Interrupciones ====
;=====================================
rutina_int
incf cont_milis,f;
incf presc_1,f;
movlw .100;
xorwf presc_1,w;
btfsc status,z;
goto sig_int;
goto sal_rutint;
sig_int
clrf presc_1;
incf presc_2,f;
movlw .10;
xorwf presc_2,w;
btfss status,z;
goto sal_rutint;
clrf presc_1;
clrf presc_2;
sal_rutext
bsf banderas,ban_int;
sal_rutint
bcf intcon,t0if;
return;
;------------------------------------------------------------------------------------------------------------;==============================================
;== Subrutina de Inicio de regreso del PIC ==
;==============================================
prog_ini
bsf status,rp0; Ponte en el banco 1 de RAM.
movlw 0x02; Asigna un prescalador de 8 al tmr0 y
deshabilita pull-up
movwf option_reg ^0x80;
movlw proga;
movwf trisa ^0x80;
movlw progb;
movwf trisb ^0x80;
movlw progc;
movwf trisc ^0x80;
movlw progd;
movwf trisd ^0x80;
movlw proge;
movwf trise ^0x80;
movlw 0x06; Configura puertos A y E como pines
digitales
movwf adcon1 ^0x80;
bcf status,rp0; Regresa al banco 0 de RAM.
movlw 0xa0; Borra las banderas y habilita las
interrupciones globales e interrupcion de tmr0 por desbordamiento
movwf intcon;
movlw .131;
movwf tmr0;
clrf banderas;
clrf portc;
movlw 0x03;
movwf porta;
movlw 0x0F;
movwf portb;
clrf resp_w; inicializa la variable a 0
clrf resp_status;
clrf res_pclath;
clrf res_fsr;
clrf presc_1;
clrf presc_2;
clrf banderas;
clrf cont_milis;
clrf uniseg;
clrf decseg;
clrf unimin;
clrf decmin;
clrf unihor;
clrf dechor;
clrf cta_24;
clrf select_time;
clrf var_Tecopri;
clrf banperr;
return;
;------------------------------------------------------------------------------------------------------------;==========================
;== Programa Principal ==
;==========================
prog_prin
call prog_ini;
call ini_lcd; llamada a la subrutina de inicializacion de la
LCD
loop_prin
call muestra_time;
call count_time1;
call barre_teclado;
call muestra_tecla;
goto loop_prin;
;------------------------------------------------------------------------------------------------
;------------------------------------------------------------------------------------------------------------;======================================
;== Subrutina de muestra de tiempo ==
;======================================
muestra_time
call esp_int;
bcf porta,RS_LCD;
movlw 0x80;
movwf portc;
call pulso_enable;
bsf porta,RS_LCD;
movlw ' ';
movwf portc;
call pulso_enable;
movlw ' ';
movwf portc;
call pulso_enable;
movlw ' ';
movwf portc;
call pulso_enable;
movlw ' ';
movwf portc;
call pulso_enable;
movlw 0x30;
addwf dechor,w;
movwf portc;
call pulso_enable;
movlw 0x30;
addwf unihor,w;
movwf portc;
call pulso_enable;
movlw ':';
movwf portc;
call pulso_enable;
movlw 0x30;
addwf decmin,w;
movwf portc;
call pulso_enable;
movlw 0x30;
addwf unimin,w;
movwf portc;
call pulso_enable;
movlw ':';
movwf portc;
call pulso_enable;
movlw 0x30;
addwf decseg,w;
movwf portc;
call pulso_enable;
movlw 0x30;
addwf uniseg,w;
movwf portc;
call pulso_enable;
movlw ' ';
movwf portc;
call pulso_enable;
movlw ' ';
movwf portc;
call pulso_enable;
movlw ' ';
movwf portc;
call pulso_enable;
movlw ' ';
movwf portc;
call pulso_enable;
return;
;------------------------------------------------------------------------------------------------
;--------------------------------------------------------------------------------------------------
;======================================
;== Subrutina de barrido de teclado ==
;======================================
barre_teclado
bcf bannar,bannab;
bsf portb,Act_Ren4;
nop;
bcf portb,Act_Ren1;
movf portb,w;
movwf Var_teclado;
movlw 0xF0;
andwf Var_teclado,f;
movlw No_haytecla;
subwf Var_teclado,w;
btfsc status,Z;
goto sig_Ran2;
movlw Tec_7;
subwf Var_teclado,w;
btfsc status,Z;
goto Fue_Tec7
movlw Tec_8;
subwf Var_teclado,w;
btfsc status,Z;
goto Fue_Tec8;
movlw Tec_9;
subwf Var_teclado,w;
btfsc status,Z;
goto Fue_Tec9;
movlw Tec_div;
subwf Var_teclado,w;
btfsc status,Z;
goto Fue_Tecdiv;
sig_Ran2
bsf portb,Act_Ren1;
nop;
bcf portb,Act_Ren2;
movf portb,w;
movwf Var_teclado;
movlw 0xF0;
andwf Var_teclado,f;
movlw No_haytecla;
subwf Var_teclado,w;
btfsc status,Z;
goto sig_Ran3;
movlw Tec_4;
subwf Var_teclado,w;
btfsc status,Z;
goto Fue_Tec4;
movlw Tec_5;
subwf Var_teclado,w;
btfsc status,Z;
goto Fue_Tec5;
movlw Tec_6;
subwf Var_teclado,w;
btfsc status,Z;
goto Fue_Tec6;
movlw Tec_B;
subwf Var_teclado,w;
btfsc status,Z;
goto Fue_TecB;
sig_Ran3
bsf portb,Act_Ren2;
nop;
bcf portb,Act_Ren3;
movf portb,w;
movwf Var_teclado;
movlw 0xF0;
andwf Var_teclado,f;
movlw No_haytecla;
subwf Var_teclado,w;
btfsc status,Z;
goto sig_Ran4;
movlw Tec_1;
subwf Var_teclado,w;
btfsc status,Z;
goto Fue_Tec1;
movlw Tec_2;
subwf Var_teclado,w;
btfsc status,Z;
goto Fue_Tec2;
movlw Tec_3;
subwf Var_teclado,w;
btfsc status,Z;
goto Fue_Tec3;
movlw Tec_C;
subwf Var_teclado,w;
btfsc status,Z;
goto Fue_TecC;
sig_Ran4
bsf portb,Act_Ren3;
nop;
bcf portb,Act_Ren4;
movf portb,w;
movwf Var_teclado;
movlw 0xF0;
andwf Var_teclado,f;
movlw No_haytecla;
xorwf Var_teclado,w;
btfsc status,Z;
goto Fue_Tecnada;
movlw Tec_clear;
xorwf Var_teclado,w;
btfsc status,Z;
goto Fue_TecClear;
movlw Tec_0;
xorwf Var_teclado,w;
btfsc status,Z;
goto Fue_Tec0;
movlw Tec_igual;
xorwf Var_teclado,w;
btfsc status,Z;
goto Fue_Tecigual;
movlw Tec_suma;
xorwf Var_teclado,w;
btfsc status,Z;
goto Fue_Tecsuma;
Fue_Tecnada
movlw ' ';
movwf Var_tecopri;
bsf bannar,bannab;
goto sal_barretec;
Fue_Tec0
movlw .0;
movwf Var_tecopri;
goto sal_barretec;
Fue_Tec1
movlw .1;
movwf Var_tecopri;
goto sal_barretec;
Fue_Tec2
movlw .2;
movwf Var_tecopri;
goto sal_barretec;
Fue_Tec3
movlw .3;
movwf Var_tecopri;
goto sal_barretec;
Fue_Tec4
movlw .4;
movwf Var_tecopri;
goto sal_barretec;
Fue_Tec5
movlw .5;
movwf Var_tecopri;
goto sal_barretec;
Fue_Tec6
movlw .6;
movwf Var_tecopri;
goto sal_barretec;
Fue_Tec7
movlw .7;
movwf Var_tecopri;
goto sal_barretec;
Fue_Tec8
movlw .8;
movwf Var_tecopri;
goto sal_barretec;
Fue_Tec9
movlw .9;
movwf Var_tecopri;
goto sal_barretec;
Fue_Tecdiv
movlw 'A';
movwf Var_tecopri;
goto sal_barretec;
Fue_TecB
movlw 'B';
movwf Var_tecopri;
goto sal_barretec;
Fue_TecC
movlw 'C';
movwf Var_tecopri;
goto sal_barretec;
Fue_Tecsuma
movlw '+';
movwf Var_tecopri;
goto sal_barretec;
Fue_TecClear
movlw '*';
movwf Var_tecopri;
goto sal_barretec;
Fue_Tecigual
movlw '=';
movwf Var_tecopri;
sal_barretec
return;
;-------------------------------------------------------------------------------------------------;============================================
;== Subrutina para actualizar el tiempo ==
;============================================
actualizar
nop;
call ret_255ms
call ret_255ms
call ret_255ms
repetir
call barre_teclado;
btfsc bannar,bannab;
goto repetir;
bcf banperr,banperb;
call compvr0;
call compvr1;
call compvr2;
btfss banperr,banperb;
goto repetir;
bcf banperr,banperb;
movf Var_tecopri,w;
movwf dechor;
call muestra_time;
call ret_40ms
call ret_40ms
repetir1
call barre_teclado;
btfsc bannar,bannab;
goto repetir1;
bcf banperr,banperb;
movlw .2;
xorwf dechor,test;
btfss status,z;
goto todas;
goto ceroatres;
todas
call compvr0;
call compvr1;
call compvr2;
call compvr3;
call compvr4;
call compvr5;
call compvr6;
call compvr7;
call compvr8;
call compvr9;
goto salir2;
ceroatres
call compvr0;
call compvr1;
call compvr2;
call compvr3;
goto salir2;
salir2
btfss banperr,banperb;
goto repetir;
bcf banperr,banperb;
movf Var_tecopri,w;
movwf unihor;
call muestra_time;
call ret_40ms
call ret_40ms
repetir2
call barre_teclado;
btfsc bannar,bannab;
goto repetir2;
bcf banperr,banperb;
call compvr0;
call compvr1;
call compvr2;
call compvr3;
call compvr4;
call compvr5;
btfss banperr,banperb;
goto repetir2;
bcf banperr,banperb;
movf Var_tecopri,w;
movwf decmin;
call muestra_time;
call ret_40ms
call ret_40ms
repetir3
call barre_teclado;
btfsc bannar,bannab;
goto repetir3;
bcf banperr,banperb;
call compvr0;
call compvr1;
call compvr2;
call compvr3;
call compvr4;
call compvr5;
call compvr6;
call compvr7;
call compvr8;
call compvr9;
btfss banperr,banperb;
goto repetir3;
bcf banperr,banperb;
movf Var_tecopri,w;
movwf unimin;
call muestra_time;
call ret_40ms
call ret_40ms
repetir4
call barre_teclado;
btfsc bannar,bannab;
goto repetir4;
bcf banperr,banperb;
call compvr0;
call compvr1;
call compvr2;
call compvr3;
call compvr4;
call compvr5;
btfss banperr,banperb;
goto repetir4;
bcf banperr,banperb;
movf Var_tecopri,w;
movwf decseg;
call muestra_time;
call ret_40ms
call ret_40ms
repetir5
call barre_teclado;
btfsc bannar,bannab;
goto repetir5;
bcf banperr,banperb;
call compvr0;
call compvr1;
call compvr2;
call compvr3;
call compvr4;
call compvr5;
call compvr6;
call compvr7;
call compvr8;
call compvr9;
btfss banperr,banperb;
goto repetir5;
bcf banperr,banperb;
movf Var_tecopri,w;
movwf uniseg;
call muestra_time;
call ret_40ms
call ret_40ms
actualizar1
call barre_teclado;
movlw 'B';
xorwf Var_tecopri,w;
btfsc status,Z;
goto salir;
goto actualizar1;
salir
return;
;-------------------------------------------------------------------------------------------------;-------------------------------------------------------------------------------------------------;======================================
;== Subrutina que comprueba validez ==
;======================================
compvr0
;bsf banperr,banperb;
movlw .0;
xorwf Var_tecopri,test;
btfsc status,Z;
goto activar;
goto salir1;
compvr1
;bsf banperr,banperb;
movlw .1;
xorwf Var_tecopri,test;
btfsc status,Z;
goto activar;
goto salir1;
compvr2
;bsf banperr,banperb;
movlw .2;
xorwf Var_tecopri,test;
btfsc status,Z;
goto activar;
goto salir1;
compvr3
;bsf banperr,banperb;
movlw .3;
xorwf Var_tecopri,test;
btfsc status,Z;
goto activar;
goto salir1;
compvr4
;bsf banperr,banperb;
movlw .4;
xorwf Var_tecopri,test;
btfsc status,Z;
goto activar;
goto salir1;
compvr5
;bsf banperr,banperb;
movlw .5;
xorwf Var_tecopri,test;
btfsc status,Z;
goto activar;
goto salir1;
compvr6
;bsf banperr,banperb;
movlw .6;
xorwf Var_tecopri,test;
btfsc status,Z;
goto activar;
goto salir1;
compvr7
;bsf banperr,banperb;
movlw .7;
xorwf Var_tecopri,test;
btfsc status,Z;
goto activar;
goto salir1;
compvr8
;bsf banperr,banperb;
movlw .8;
xorwf Var_tecopri,test;
btfsc status,Z;
goto activar;
goto salir1;
compvr9
;bsf banperr,banperb;
movlw .9;
xorwf Var_tecopri,test;
btfsc status,Z;
goto activar;
goto salir1;
activar
bsf banperr,banperb;
salir1
bcf status,z;
return;
;-------------------------------------------------------------------------------------------------;-------------------------------------------------------------------------------------------------;====================================
;== Subrutina que revisa la tecla ==
;====================================
muestra_tecla
movlw 'A';
xorwf Var_tecopri,w;
btfsc status,Z;
goto actualizar;
;bcf porta,RS_LCD; A este no se le quita
el comentario***
;movlw 0x01;
;movwf portc;
;call pulso_Enable;
;bsf porta,RS_LCD;
;goto sal_muestec;
sal_muestec
return;
;--------------------------------------------------------------------------------------------------
esp_int
;===============================================
;== Subrutina de espera de int. de 1 segundo ==
;===============================================
nop;
btfss banderas,ban_int;
goto esp_int;
bcf banderas,ban_int;
return;
;-----------------------------------------------------------------------------------------------;=========================================================
=================
;=========
Subrutina que cuenta el tiempo
========
;=========================================================
=================
count_time1
incf uniseg,f; Incrementa en 1 la cuenta de las unidades de
segundo.
movlw .10;
subwf uniseg,w;
btfss status,Z; Compara si es que ya se llego al numero
maximo de las uni. de seg. que es 9.
goto exit_count1; Regresa al programa principal si es que
aun no se llega a 9.
clrf uniseg; Si se paso a XX-XX-X9 reinicia la cuenta
desde 0.
incf decseg,f;
movlw .6;
subwf decseg,w;
btfss status,Z; Compara si es que ya se llego al numero
maximo de las dec. de seg. que es 5.
goto exit_count1; Regresa al programa principal si es que
aun no se llega a 5.
clrf uniseg;
clrf decseg; Si se paso a XX-XX-59 reinicia la cuenta
desde 0.
incf unimin,f; Incrementa en 1 la cuenta de las unidades
de minuto.
movlw .10;
subwf unimin,w;
btfss status,Z; Compara si es que ya se llego al numero
maximo de las uni. de min. que es 9.
goto exit_count1; Regresa al programa principal si es que
aun no se llega a 9.
clrf uniseg;
clrf decseg;
clrf unimin; Si se paso a XX-X9-59 reinicia la cuenta
desde 0.
incf decmin,f;
movlw .6;
subwf decmin,w;
btfss status,Z; Compara si es que ya se llego al numero
maximo de las dec. de min. que es 5.
goto exit_count1; Regresa al programa principal si es que
aun no se llega a 5.
clrf uniseg;
clrf decseg;
clrf unimin;
clrf decmin; Si se paso a XX-59-59 reinicia la cuenta
desde 0.
incf cta_24;
movlw .24;
subwf cta_24,w;
btfss status,z;
goto exit_count1;
incf unihor,f;
movlw .10;
subwf unihor,w;
btfss status,Z; Compara si es que ya se llego al numero
maximo de las uni. de hor. que es 9.
goto exit_count1; Regresa al programa principal si es que
aun no se llega a 9.
clrf uniseg;
clrf decseg;
clrf unimin;
clrf unihor; Si se paso a X9-59-59 reinicia la cuenta desde
0.
incf dechor,f;
movlw .3;
subwf dechor,w;
btfss status,Z; Compara si es que ya se llego al numero
maximo de las dec. de hor.
goto exit_count1; Regresa al programa principal si es que
aun no se pasa a 1.
clrf uniseg;
clrf decseg;
clrf unimin;
clrf decmin;
clrf unihor; .
exit_count1
return;
;-----------------------------------------------------------------------------------------------;================================================
;== Subrutina de inicialización de la LCD ====
ini_lcd
;================================================
bcf porta,RS_LCD; coloca la lcd en formato comandos
movlw 0x38; Carga con 38 el registro w
movwf portc; Mueve el 38 al bus de datos que está en el
puerto c
call pulso_enable; Genera pulso eneable para que
capture y ejecute el dato
movlw 0x01;
movwf portc;
call pulso_enable;
movlw 0x06; Borra todos los caracteres de la LCD y
posiciona el cursor en el digito 1
movwf portc;
call pulso_enable;
movlw 0x0c;
movwf portc;
call pulso_enable;
movlw 0x80; Direccion del digito 1 en la LCD
movwf portc;
call pulso_enable;
bsf porta,RS_LCD; coloca el LCD en modo datos
return;
;----------------------------------------------------------------------------------------;================================================
;== Subrutina de Retardo de medio segundo ====
;================================================
pulso_enable
bcf porta,Enable_LCD;
call retardo_1ms;
bsf porta,Enable_LCD;
call ret_40ms;
return;
;----------------------------------------------------------------------------------------;================================================
;== Subrutina de Retardo de 10 milisegundos ====
;================================================
retardo_1ms
clrf cont_milis;
esp_int1ms
movlw .10;
subwf cont_milis,w;
btfss status,Z;
goto esp_int1ms;
return;
;----------------------------------------------------------------------------------------;================================================
;== Subrutina de Retardo de 40 milisegundos ====
;================================================
ret_40ms
clrf cont_milis;
esp_int40ms
movlw .40;
subwf cont_milis,w;
btfss status,Z;
goto esp_int40ms;
return;
;-------------------------------------------------------------------------------------------------------------
;----------------------------------------------------------------------------------------;================================================
;== Subrutina de Retardo de 255 milisegundos ====
;================================================
ret_255ms
clrf cont_milis;
esp_int255ms
movlw .255;
subwf cont_milis,w;
btfss status,Z;
goto esp_int255ms;
return;
;------------------------------------------------------------------------------------------------------------End
Conclusión
Esta practica introdujo un nuevo dispositivo electrónico muy importante, estoy
hablando del teclado matricial, la importancia de este dispositivo radica en que nos
permite interactuar de manera directa con el sistema, en el caso particular de
nuestra práctica, nos permite manipular y editar la hora del reloj de tiempo real.
El hecho de incluir este nuevo sistema implica a nivel de software realizar los
ajustes necesarios para el correcto funcionamiento de este, estos ajustes
principalmente se ven reflejados en la subrutina de barrido de teclado, esta
subrutina nos permite realizar un sondeo para saber con exactitud que tecla fue la
que se pulso, además da validez al dato ingresado en el teclado.
Una vez más, esta práctica nos mostró que entre más se simplifique el hardware
más complejo será el desarrollo a nivel de software.
Descargar