PROYECTO

Post on 15-Dec-2015

11 views 2 download

description

PROYECTO

transcript

http://www.avr-asm-tutorial.net/avr_en/

http://www.avr-asm-tutorial.net/avr_en/APPS.html

La conexión de un teclado para un AVREsta página muestra cómo conectar un 12-key-teclado común a un AVR y la leyó por el software ensamblador. Los capítulos son:

1. ¿Cómo funciona un teclado 2. AVR: I / O-conexión de la matriz 3. AVR: Conexión a un ADC con una red de resistencias

1. Cómo funciona un teclado

Los teclados son interruptores, que están conectados a filas y columnas. Si la tecla "1" es presionado, la columna 1 está conectado eléctricamente a la fila 1, si la tecla "2" se pulsa la columna 2 con la fila 1, y así sucesivamente ... Para saber si se presiona uno cualquiera de las 12 teclas , sólo sería necesario atar las tres líneas de la columna a tierra, conecte las cuatro líneas de fila y, a través de una resistencia de 10 kW, tirar de ellos a la red eléctrica. Si se pulsa ninguna tecla, las líneas de fila están en ventaja. Cualquier tecla pulsada tira

hacia abajo las líneas de fila a cero voltios. Para detectar, que se pulsa una de las 12 teclas, tirar hacia abajo las líneas de tres columnas una a una a tierra (las otras dos líneas de columna a más) y leer los cuatro fila resultante -lines. Si una de las cuatro filas de líneas es baja, detener la lectura e identificar el código de la llave de la columna y la fila de información. Como eso:

Columna Fila Llave

Col1 Col2 Col3 ROW1 Row2 Row3 Row4 Personaje Código binario

0 0 0 1 1 1 1 (Ninguno) 1111

0 1 1 0 1 1 1 1 0001

1 0 1 0 1 1 1 2 0010

1 1 0 0 1 1 1 3 0011

0 1 1 1 0 1 1 4 0100

1 0 1 1 0 1 1 5 0101

1 1 0 1 0 1 1 6 0110

0 1 1 1 1 0 1 7 0111

1 0 1 1 1 0 1 8 1000

1 1 0 1 1 0 1 9 1001

0 1 1 1 1 1 0 * 1010

1 0 1 1 1 1 0 0 0000

1 1 0 1 1 1 0 # 1011

Lectura de un teclado como el uso de componentes de lógica digital, necesita al menos:

un oscilador, un registro de desplazamiento y una puerta de arranque / parada para generar las señales de columna,

detección de si una de las cuatro señales de fila es cero, un Recoder para la conversión de las siete señales al código clave.

O una completa haciendo todo lo que IC (probablemente no obtendrá tal IC en su distribuidor local de partes electrónicas). ¿O es mejor utilizar un micro. Para la parte superior de la página

2. AVR: I / O-conexión de la matriz

Una matriz de teclado se puede conectar directamente a un puerto de E / S de un AVR, sin componentes adicionales. El ejemplo muestra una conexión con los menores de siete pines I / O del puerto B. Otros puertos se pueden utilizar similiarly. El PB4 pines del puerto ..PB6 se definen como salidas, que proporcionan las señales de columna. Los pines del puerto PB0..PB3 se utilizan para leer en los resultados de fila.Resistencias de pull-up en estas entradas están habilitadas por software, resistencias externas no son necesarios. El ejemplo de software siguiente se muestra primero la inicialización de los puertos. Esta parte del software tiene que ser excecuted sola vez al inicio del programa del

AVR.

Init-rutina

;; Init teclado-I / O;

.def Rmp = R16; definir un registro de usos múltiples; definir puertos.equ PKeyOut = PORTB; Salida y Pull-Up-Port.equ PKeyInp = PINB; leer entrada de teclado.equ PKeyDdr = DDRB; dirección de los datos de registro del puerto; Init-rutinaInitKey:

rmp LDI, 0b01110000; dirección de registro de salida de líneas de la columna de datos

cabo pKeyDdr, rmp; Configurar sentido registrormp LDI, 0b00001111; Pull-Up-Resistencias para bajar cuatro

pines del puertocabo pKeyOut, rmp; al puerto de salida

Compruebe si hay cualquier tecla pulsada

La siguiente rutina detecta si se presiona uno cualquiera de las 12 teclas. Esta rutina se llama en intervalos de, por ejemplo, en un bucle de retardo o mediante el uso de un temporizador.

;; Compruebe cualquier tecla pulsada;Cualquier llave:

rmp LDI, 0b00001111; PB4..PB6 = Null, pull-up-resistencias a las líneas de entrada

cabo pKeyOut, rmp; de pines del puerto PB0..PB3en rmp, pKeyInp; leer los resultados clavermp ori, 0b11110000; enmascarar todos los bits superiores con

un unormp cpi, 0b11111111; todos los bits = Uno?BREQ NOKEY; sí, se pulsa ninguna tecla

Identificar la tecla pulsada

Ahora el teclado se lee. Uno tras otro puerto Bits PB6, PB5 y PB4 se fijan a la baja, y PB0..PB3 es inspeccionado por ceros. El par de registro Z (ZH: ZL) apunta a una tabla con los códigos clave. Cuando salen de la rutina, este par apunta al código de tecla de la tecla pulsada. Mediante el uso de la instrucción LPM, el código de la llave se lee de la tabla en la memoria flash para el registro R0.

;; Identificar la tecla pulsada;ReadKey:

LDI ZH, ALTA (2 * KEYTABLE); Z es puntero a la tabla de códigos clave

LDI ZL, LOW (2 * KEYTABLE); leer la columna 1rmp LDI, 0b00111111; PB6 = 0cabo pKeyOut, rmpen rmp, pKeyInp; leer línea de entradarmp ori, 0b11110000; enmascarar bits superioresrmp cpi, 0b11111111; una clave en esta columna presionado?Brne KeyRowFound; encontrado clave

adiw ZL, 4; la columna no se encuentra, el punto Z una fila hacia abajo

; leer la columna 2rmp LDI, 0b01011111; PB5 = 0cabo pKeyOut, rmpen rmp, pKeyInp; leer la línea de entrada de nuevormp ori, 0b11110000; enmascarar bits superioresrmp cpi, 0b11111111; una clave en esta columna?Brne KeyRowFound; columna encontradoadiw ZL, 4; columna no encontrado, otros cuatro teclas abajo; leer la columna 3rmp LDI, 0b01101111; PB4 = 0cabo pKeyOut, rmpen rmp, pKeyInp; leer la última línearmp ori, 0b11110000; enmascarar bits superioresrmp cpi, 0b11111111; una clave en esta columna?BREQ NOKEY; inesperado: ninguna tecla en esta columna

presionadoKeyRowFound:; columna identificada, ahora identificar fila

rmp LSR; cambiar una lógica 0 en la izquierda, el bit 0 para llevar

BRCC KeyFound; un cero desplegado, se encuentra claveadiw ZL, 1; punto al siguiente código de la llave de esa

columnarjmp KeyRowFound; turno de repetición

KeyFound:; se encuentra tecla pulsadalpm; leer el código clave para R0rjmp KeyProc; countinue procesamiento clave

NOKEY:rjmp NoKeyPressed; ninguna tecla presionada

;; Tabla de conversión de código;KEYTABLE:.DB 0x0A, 0x07,0x04,0x01; La primera columna, teclas *, 7, 4 und 1.DB 0x00,0x08,0x05,0x02; segunda columna, claves 0, 8, 5 und 2.DB 0x0B, 0x09,0x06,0x03; tercera columna, teclas #, 9, 6 und 3

Supresión de rebotes

Las rutinas KeyProc y NoKeyPressed tienen para el rebote la tecla pulsada. Por ejemplo contando un contador ascendente cada vez que se identificó la misma clave. Repita esto para por ejemplo 50 milisegundos. La rutina NoKeyPressed despeja el mostrador y la tecla pulsada. Debido a que el tiempo depende de otros requisitos de tiempo necesaria del programa AVR, que no se muestra aquí.

Consejos, Desventajas

Las rutinas se muestran arriba no dejan más tiempo entre el ajuste de la dirección de la columna y de la lectura de la información de la fila. A frecuencias de reloj de alta y / o conexiones más largas entre el teclado y el procesador es necesario dejar más tiempo entre escritura y lectura (por ejemplo, mediante la inserción de instrucciones NOP). Los pull-ups internas resistencias tienen valores alrededor de 50 kW. Largas

filas o un ambiente ruidoso podrían interferir y producir fallos. Si te gusta lo menos sensible, agregue cuatro flexiones externos.Una desventaja del circuito es que requiere siete líneas de puerto exclusivo. La modificación con un convertidor AD y una red de resistencias (véase el capítulo 3) es más económico y ahorra líneas portuarias.Para la parte superior de la página

3. La conexión a un ADC con una matriz de resistencia

La mayoría de los dispositivos Tiny y Mega-AVR hoy en día tienen un convertidor AD a bordo. Sin hardware externo adicional éstos son capaces de medir voltajes analógicos y resolver estos con 10 bits de resolución. Aquellos que quieren ahorrar puertos I / O sólo se tienen para obtener el teclado para producir un voltaje analógico. Esa es la tarea de una matriz de resistencia. Sugerencia: Una versión mejorada de este texto con más ejemplos, una herramienta de software de comandos, etc. está disponible 

aquí ! Una herramienta de software gráfico para el estudio de las diferentes versiones del esquema y tamaños se puede encontrar aquí .

Matriz de Resistencia

Esta es una matriz tal resistor. Las columnas están conectadas a tierra, entre las conexiones de la columna son tres resistencias apiladas. Las filas se conectan a través de cuatro resistencias tales apilados a la tensión de servicio (por ejemplo 5 V). La entrada del convertidor AD está bloqueado por un condensador de 1 nF porque el ADC no le gusta frecuencias altas, que podrían ser capturadas por las llaves, las resistencias y las líneas más o menos largas en el medio de todo esto. Si la tecla "5" es presionado, un divisor de tensión se activa: * 1 k + 820 Ω = 1,82k a tierra, * 3,3 k + 680 + 180 Ω Ω = 4,16k a más. En

una tensión de 5 voltios una tensión dividida de 5 * 1,82 / (1,82 + 4,16) =

1.522 voltios se ve en la entrada del convertidor AD. Si consideramos 5% de tolerancia de las resistencias, la tensión resultante es en algún lugar entre 1468 y 1627 voltios. El convertidor AD 10 bits convierte esta (en 5 V de referencia de voltaje) a un valor entre 300 y 333. Si ignoramos los dos bits más bajos de el resultado (por ejemplo, dividir el resultado AD por cuatro o izquierda-ajustando el resultado - si el ADC ofrece esa función) esto produce un valor de 8 bits entre 74 y 78. Cada tecla pulsada produce un rango de tensión típica, que se convierte en el código de la llave. 

Tensiones y reconocimientos clave

Las combinaciones de resistencias producen las tensiones reunidos en la tabla siguiente. Teniendo en cuenta son los rangos de tensión de las teclas, los valores del convertidor 8-bit-AD para estas claves y los valores de detección óptimas entre las diferentes teclas.

LlaveVoltaje Valor de 8 bits-AD Detección

V (min.) V (típico). V (max.) min. típ. max. (De valor AD)

1 0225 0248 0272 11 13 14 7

2 0396 0434 0474 20 22 25 18

3 0588 0641 0698 29 33 36 28

4 0930 0969 1048 47 49 54 42

5 1468 1522 1627 74 78 84 64

6 1959 2020 2139 99 103 110 91

7 2563 2688 2809 130 137 144 121

8 3285 3396 3500 167 173 180 156

9 3740 3832 3917 190 195 201 185

* 4170 4237 4298 212 216 221 207

0 4507 4550 4588 229 232 235 225

# 4671 4700 4726 238 240 242 237

Como puede verse en la tabla, no hay superposición de los diferentes valores de detección para las teclas, teniendo tolerancia del 5% de las resistencias en cuenta. Aquellos que gustan de jugar con otras combinaciones de resistencias,

se puede descargar la hoja de cálculo ( como Open -Oficina-formato , como Excel XP-Format ). 

Sugerencias para el hardware del convertidor AD

Dispositivos ATtiny en la mayoría de los casos sólo ofrecen la oportunidad de utilizar una tensión generada internamente o la tensión de alimentación del AVR como referencia para el convertidor AD. Para la conversión teclado solamente la tensión de alimentación es adecuada como referencia. Esta opción tiene que ser seleccionado cuando se inicia el hardware del convertidor AD al inicio del programa. Muchos ATmega tipos pueden conectar la tensión de referencia a un pin externo, AREF. Este pin puede ser o bien de entrada o salida. Es una salida si cualquiera de la tensión de alimentación o la referencia interna se seleccionan como referencia convertidor AD. En este caso el pin AREF debe tener un condensador a tierra para reducir aún más el ruido de la tensión de referencia. El pin AREF es una entrada, si se selecciona una fuente de referencia externa como opción. En este caso una fuente externa proporciona la tensión de referencia. Si una fuente externa proporciona la tensión de referencia, la matriz de teclado también debe ser suministrada por esta fuente. Nota en ese caso que el teclado consume hasta 10 mA, para mejorar la sensibilidad al ruido. ATmega dispositivos permiten suministrar el convertidor AD de un pin extra (AVCC) para reducir aún más el ruido. Si sólo se utiliza el teclado de conversión AD la baja resolución necesaria de 8 bits no requiere una alimentación separada para el pasador de AVCC, puede estar ligada a la tensión de alimentación normal. Si otras tareas de medición tienen que realizarse en otros canales, el pasador AVCC debe ser conectado a la tensión de alimentación a través de una bobina de 22 uH y debe ser bloqueado por un condensador de 100 nF a tierra. 

La iniciación y la lectura del resultado convertidor AD

Para la lectura de la tensión de la matriz del teclado un AD canal convertidor se requiere. El convertidor AD se inicia una vez durante el inicio del programa. Los dos códigos de ejemplo muestran una secuencia de inicio para la conversión individual, aquí para una ATmega8, y otro para una interrupción impulsado arranque automático de la ADC, aquí para una ATtiny13.

ATmega8: arranque manual del ADC

El primer ejemplo muestra una rutina para un ATmega8, sin interrupciones, con un inicio manual y parada del convertidor AD. La señal de teclado se conecta al canal ADC0 AD.

.def Rkey = R15; Registrate en valor AD

.def Rmp = R16; Multi registro de propósito; establece MUX canalizar 0, dejó ajustar el resultado, Aref

tomado de AVCCrmp LDI, (1 << REFS0) | (1 << Adlar); ADMUX canal 0, Aref del

AVCCcabo ADMUX, rmp; cambiar conversión AD en adelante, iniciar la conversión,

tasa divisor = 128LDI rmp, (1 << ADEN) | (1 << ADSC) | (1 << ADPS2) | (1 <<

ADPS1) | (1 << ADPS0)cabo ADCSRA, rmp; espere hasta que la conversión AD es completa

WaitAdc1:; comprobar ADSC bits, la conversión completa si el bit es ceroSBIC ADCSRA, ADSC; conversión listo?rjmp WaitAdc1; aún no; leer MSB del resultado de la conversión ADen rkey, ADCH; conversor AD interruptor offrmp LDI, (1 << ADPS2) | (1 << ADPS1) | (1 << ADPS0); cambiar

ADC fueracabo ADCSRA, rmp

Tenga en cuenta que esta única conversión requiere 25 * 128 ciclos de reloj, a 1 Mcs / s reloj de 3,2 milisegundos. Sólo haga esto de esa manera, corriendo en círculos, si usted no tiene que preocuparse por otras cosas en el medio de este retardo de tiempo (excepto si estas otras cosas se hacen dentro de las interrupciones).

ATtiny13: conversión AD de inicio automático, interrumpir impulsada

Sí, un ATtiny13 con sus 8 patas puede leer nuestra matriz de teclado (no podemos conectar la matriz de teclado en sí, debido al limitado número de pines de E / S). Una rutina típica para esta tarea sería la siguiente secuencia, que convierte el voltaje en ADC3 (pin 2 del ATtiny13) continuamente (después de la conversión completa, la próxima conversión se inicia de forma automática). 

;; Iniciar convertidor AD;

; PB3 = ADC3 se utiliza para la conversiónrmp LDI, 0b00001000; desconecte el controlador digital de PB3,

ahorra corriente de alimentacióncabo DIDR0, rmp; Referencia = tensión de alimentación, Izquierda-ajustar el

resultado; ADMUX a ADC3

rmp LDI, 0b00100011; tensión de referencia = tensión de alimentación, eligió ADC3

cabo ADMUX, rmp; opción de inicio automático de selecciónrmp LDI, 0b00000000; conversión de funcionamiento libre

(autostart)ADCSRB cabo, rmp; iniciar ADC, permita la interrupción, seleccione divisor de

relojrmp LDI, 0b11101111; iniciar ADC, autostart,cabo ADCSRA, rmp; Int Habilitar, reloj divisor para 128

; la iniciación completa

Ejecución en modo de interrupción requiere definir el salto vectorial respectiva int, por ejemplo,

;; Reset y int vectores, ATtiny13;.CSEG; montar en segmento de código.ORG $ 0.000; al comienzo del segmento de código

RJMP principal; Restablecer vectorialreti; INT0 interrupción vectorialreti; PCINT0 vectorialreti; TC0 desbordamiento vectorialreti; Eeprom vector listoreti; Comparador analógico int vectorreti; TC0 Compa vectorialreti; TC0 CompB vectorialreti; WDT vectorialRJMP intadc; Conversión ADC completa vectorial

;

Por supuesto, la pila debe ser iniciado para utilizar interrupciones, y la bandera de estado de interrupción se debe establecer (SEI). El servicio intadc rutina lee el resultado de la conversión AD. Debido a ajustar izquierda ha sido seleccionado, es suficiente para leer el MSB del resultado: 

;; Servicio de Interrupción conversión AD Rutina;.def Rkey = R15; registro de resultado para el resultado de la conversiónintadc:

en rkey, ADCH; leer convertidor AD MSBreti; volver de interrupción

;

El rkey registro proporciona continuamente el valor actual de la matriz de resistencia.

Convirtiendo el resultado AD al código clave

El resultado de la conversión es, como tal, no es muy útil. Las tensiones y el resultado de la conversión no siguen las leyes matemáticas sencillas (valores de la resistencia de 4.7 a 5.6 - 6.8 a 8.2 deben haber sido diseñado por un

profesor de matemáticas de ebriedad, la fórmula V = R1 / (R1 + R2) no es muy fácil de manejar ), por lo que será mejor utilizar una tabla para resolver nuestros códigos clave. La tabla no puede ser una tabla de consulta primitivo, porque tenemos 256 resultados diferentes posibles de la conversión, y nos gustaría tablas más delgadas. Al igual que un mono, que subir al árbol matriz por ir paso a paso a través de la siguiente tabla: 

KEYTABLE:.DB 7, 255, 18, 1, 28, 2, 42, 3, 64, 4, 91, 5.DB 121, 6, 156, 7, 185, 8, 207, 9, 225, 10, 237, 0, 255, 11

El primer byte es el valor de comparación para nuestro resultado de la conversión, el segundo byte es el código de la llave, si este valor es mayor que comparar nuestro resultado. Si el resultado está entre 0 y <7: se pulsa ninguna tecla (código clave es 255), si está entre 7 y <18 el código de clave es 1, etc. O, si lo prefiere ASCII para los códigos clave: 

KEYTABLE:.DB 7, 0, 18, '1', 28, '2', 42 ', 3', 64, '4', 91 ', 5'.DB 121, '6', 156, '7', 185, '8', 207, '9', 225, '*', 237, '0', 255, '#'

El código para la traducción clave es la siguiente:

;; Convertir un resultado AD a un código clave;GetKeyCode:

; si el resultado AD puede cambiar en el medio, el resultado se debe copiar primero

mov R1, rkey; copiar resultado AD a R1LDI ZH, ALTA (2 * KEYTABLE); Z apunta a la tabla de conversiónLDI ZL, LOW (2 * KEYTABLE)

GetKeyCode1:lpm; leer un valor de tablacp R1, R0; comparar los resultados con AD valor de la tablaBRCS GetKeyCode2; menos del valor de la tabla, clave

identificadoinc R0; prueba, si se llega a final de mesaBREQ GetKeyCode2; final alcanzado de mesaadiw ZL, 2; punto a la siguiente entrada de la tablarjmp GetKeyCode1; ir en la comparación siguiente entrada

GetKeyCode2:adiw ZL, 1; punto a MSB = código de la llavelpm; leer el código clave para R0

;

Por supuesto tenemos que comprobar, si no se pulsa ninguna tecla (R0 = 0xFF resp si ASCII:. R0 = 0) y tenemos que comprobar si hay fallos (si el mismo código clave viene 20 o más veces, doy por grave. ..).

Experiencias

El trabajo de hardware y software muy fiable. En la primera versión de los valores de resistencia de la matriz eran diez veces mayor. Esta versión era más vulnerable al ruido de alta frecuencia, por ejemplo, cuando se transmite con un transmisor VHF 2 W cerca. Para la parte superior de la página   © 2006-2009 por http://www.avr-asm-tutorial.net

Pfad: Inicio => AVR visión general => Aplicaciones => Reloj digital => Código Fuente

Reloj digital con un ATmega16 - código fuente

; *********************************************; * Reloj AVR digital con una ATmega16 *; * (C) 2010 por info (at) avr-asm-tutorial.net *; *********************************************;.NOLIST.include "m16def.inc".list;; ================================================== =; Ebuggingparameters D; ================================================== =; dbg = 0: la depuración de discapacitados, ejecución normal del programa; dbg = 1: la luz primera pantalla; dbg = 2: segunda pantalla de luz; dbg = 3: tercera pantalla de luz; dbg = 4: pantalla Fouth luz; dbg = 5: visualización segundos en posición de alarma minutos; dbg = 6: resultados de visualización de ADC en hexadecimal en la pantalla de alarma;.equ dbg = 0;; ================================================== =; H ardware; ================================================== =; Tipo de procesador: ATmega16; _________; / |; Rojo Key - | ADC0 PB0 | - Entrada Pot; Blk Key - | ADC1 PB1 | - Entrada fototransistor; WHT Key - | PB2 | -; Altavoz - | OC0 | -; - | PA4 | - 1 dígito ánodo conductor

; ISP MOSI - | MOSI PA5 | - 2; MISO - | MISO PA6 | - 3; SCK - | SCK PA7 | - 4; REINICIAR - | REINICIAR AREF | - + 5V; VCC - | GND VCC | - GND; GND - | GND AVCC | - + 5V; XTAL2 - | XTAL2 PC7 | - Grandes puntos LED; XTAL1 - | XTAL1 PC6 | - g Grande; Pequeño a - | PD0 PC5 | - f siete; siete b - | PD1 PC4 | - e segm.; segm. c - | PD2 PC3 | - d displ.; displ.d - | PD3 PC2 | - c cateterismo.; cateterismo. e - | PD4 PC1 | - b; f - | PD5 PC0 | - una; g - | PD6 PD7 | - puntos LED Pequeños; | ___________; ; ================================================== =; Escriptionhowitworks D; ================================================== =; ; a) Muestra y modos de visualización; Las grandes pantallas de 7 segmentos superiores muestran el tiempo,; los más bajos, pequeños displays de 7 segmentos muestran la alarma; hora. Los LED doble de puntos más grandes de la pantalla superior; parpadeará en segundos intervalos. El doble punto más pequeño; LED de abrir y cerrar la pantalla inferior, si la alarma es; armado, y son siempre encendido, si se desarma la alarma.; b) Indicación de multiplexación; El diplay utiliza Contador / Temporizador 1 en el modo CTC; interrumpir cada 5 ms después de alcanzar su valor máximo.; Los 4 pantallas se actualizan en 20 ms, produciendo una; refrescar frecuencia de 50 cs / s.; La pantalla se apaga primero, el puntero; al dígito que se muestra es informaciones avanzadas y cifras; en SRAM se escriben en los Puertos C (pantalla grande; para el tiempo) y D (pequeña pantalla para la alarma; tiempo), el puerto del controlador ánodo adecuado mordió en; el nibble superior del Puerto A se establece activa (= 0).; c) Indicación de regulación; Pantalla de atenuación utiliza el TC1 en modo CTC y Compara; Partido B interrumpir desactivar los controladores de ánodo. Los; comparar el valor partido se calcula a partir del valor de ADC; que resulta de la fototransistor: menos luz; está en el transistor mayor es su tensión de colector; y cuanto mayor sea su valor ADC y el más alto es el com-; pare valor partido B. Tenga en cuenta que este es un no lineal; función.; d) tiempo de recuento; El conteo de tiempo TC1 utiliza en el modo y la CTC; Comparar Partido Una interrupción de recuento descendente de un contador; de 200 a cero. Si se llega a cero, se establece un indicador; y el 5-ms-contador se reinicia.; Fuera de la rutina de servicio de interrupción, el tiempo es; adelantada por un segundo, la actualización de la hora después de los 60; segundos. Si la alarma está armado, se compara el tiempo; con el tiempo de alarma y se activa una alarma cuando; tiempo = tiempo de alarma.; e) Keys

; Las teclas se leen cada vez que una estela de interrupción hasta; se llevó a cabo. Las teclas activas se reconocen después de 15 ms; y se almacena. La acción respectiva se ejecuta después; todas las teclas están inactivas durante al menos 15 ms.; La siguiente tabla muestra las reacciones clave en diferente; modos de operación.; Modo de acción clave; -------------------------------------------------- -; Normal Negro Toggle poco armado; Red Introduzca el modo de ajuste; Blanco Ingrese al modo de ajuste de hora de la alarma; Ajuste del modo de ajuste de la hora Negro Saltar Tiempo; Rojo Set de tiempo (horas o minutos); Alarma Ajuste del modo de ajuste de hora de alarma Negro Saltar; Blanco Conjunto hora de la alarma (hora o minuto); Armado Negro Desactivar armado; Red Avance hora de la alarma por la repetición; Alarmado alarma Negro Desactivar y restablecer la alarma; hora; Red Desactivar alarma y alarma anticipada; tiempo de pausa; f) conversión AD; El ADC se ejecuta con un pre-escalador de 128, mide dos; canales y se controla a través de interrupción.; Las tensiones analógicas del potenciómetro (canal; ADC0) y del colector del fototransistor; (ADC1 canal) se miden, superior al ajustado izquierda-; byte resultado se añade a una suma de 16 bits. Si 256 medición; mentos por canal tuvieron lugar, el MSB del 16 de bits; resultado se entregó a una rutina fuera de la interrupción; rutina de servicio. Los resultados de los canales se utilizan para; Ch0: si en el tiempo o el modo de ajuste de la alarma, se convirtió al; horas o minutos y se muestra; Ch1: convertirse al comparar los valores partido B para establecer la tenue; tiempo y reducir el brillo en un lugar oscuro; ambiente.; g) el ruido de alarma; TC0 proporciona un generador de AF programable mediante el establecimiento de; el temporizador en el modo CTC y alternar el OC0 pin de salida; en partido de comparar. El TC0 corre con un pre-escalador de 8,; proporcionar señales de audio entre 600 (OCR0 = 255) y; 9600 (OCR0 = 16) cs / s.; Una interrupción en alcanzar CTC superior toca una melodía; situado en el espacio EEPROM leyendo el valor CTC; y la duración del tono. Después de llegar a la mesa; final, el temporizador y la salida OC0 conmutación está desactivado.;; ================================================== =; C onstants; ================================================== =;.equ reloj = 2457600; Frecuencia Xtal.equ cSnooze = 5; snooze tiempo de duración de alarma.equ cPauseLong = $ 4.000; larga pausa para la repetición de la melodía;; ================================================== =; Egisters R

; ================================================== =;; R0 utiliza para LPM a flash y para los cálculos; R1 utiliza para los cálculos; libre R2..R8.def rFChk = R9; comprobar el ajuste dimm.def rAdcC = R10; Contador de ADC.def rAdcFL = R11; ADC resultado sumador fototransistor, byte bajo.def rAdcFH = R12; ADC resultado sumador fototransistor, byte alto.def rAdcPL = R13; Adc resultado sumador potenciómetro, byte bajo.def rAdcPH = R14; Adc resultado sumador potenciómetro, byte alto.def rSreg = R15; SREG temperatura interior ints.def rmp = R16; enteros fuera de usos múltiples.def RIMP = R17; enteros dentro de usos múltiples.def rFlag = R18; bandera de registro

.equ bArmed = 0; La alarma está activada

.equ bAlarm = 1; La alarma está activa

.equ bSetC = 2; Para ajustar el reloj

.equ bSetCm = 3; Minutos de ajuste del reloj

.equ bSetA = 4; Ajustar alarma

.equ bSetAm = 5; Minutos Establecer alarma

.equ BSEC = 6; segundo siguiente alcanzó

.equ BADC = 7; nuevo resultado ADC listo.def rC5ms = R19; Contador de 5ms a segundo.def rDCnt = R20; Display Driver contador ánodo.def rkey = R21; almacenamiento de código clave última tecla, vivo.def Reep = R23; EEPROM leer dirección.def rDurL = R24; Contador de tiempo Duración LSB.def rDurH = R25; Duración contador de tiempo MSB; R27: R26 utiliza para señalar enteros fuera; R29: R28 utiliza como puntero pantalla dentro ints; R31: R30 utiliza para señalar enteros fuera;; ================================================== =; Ubicaciones SRAM; ================================================== =;.DSEG.ORG Sram_StartsTime:.byte 4; cuatro bytes dígitos para la gran pantallaSALARM:.byte 4; cuatro bytes dígitos para la pequeña pantallaSCS:.byte 1; segundo relojSMC:.byte 1; minutos de relojSCH:.byte 1; horas relojSSM:.byte 1; minutos de la alarma de ajusteSSH:.byte 1; set hora de alarmaCarter:.byte 1; minutos de la alarmaSAH:.byte 1; hora de alarmasAdcP:.byte 1; Adc resultado ollasAdcF:.byte 1; Resultado fototransistor Adc

sKey:.byte 1; tecla pulsadasKeyC:.byte 1; contador de tecla pulsadasKeyS:.byte 1; clave seleccionada;; ================================================== =; T imings; ================================================== =;; ADC:; - Canal MUX 0 medidas olla, canal MUX 1 medidas fototransistor; - Funciona a divisor = 128; - Por interrupciones; - Resultado se deja ajustar, sólo se utilizan los 8 bits superiores; - En int, se añaden los 8 bits superiores del resultado a un bit de suma 16; - Después de 256 resultados, los 8 bits superiores de la suma se copian; - Cuando se ejecuta, una conversión requiere 13 ciclos de reloj ADC; - f = 2457600/128/13/256 = 5,77 cs / s = 173,3 ms;; ================================================== =; R esetand I ntvectors; ================================================== =;.cseg.org $ 0.000

RJMP comenzar; Restablecer vectorialnopreti; INT0nopreti; INT1nopreti; TC2COMPnopreti; TC2OVFnoprjmp TC1Capt; TC1CAPTnoprjmp TC1CompA; TC1COMPAnoprjmp TC1CompB; TC1COMPBnopreti; TC1OVFnopreti; TC0OVFnopreti; SPI, STCnopreti; USART RXCnopreti; USART UDREnopreti; USART TXCnoprjmp AdcInt; ADCnopreti; EERDYnop

reti; Anacompnopreti; TWInopreti; INT2noprjmp Tc0Comp; TC0COMPnopreti; SPM RDYnop

;; ================================================== =; Yo nterrupt S ervicio Outines R; ================================================== =;; TC1 ICR período final, mostrar siguiente dígito;TC1Capt:

en rsreg, SREG; guardar SREGLDI RIMP, 0xF0; borrar todos los conductores dígitoscabo PORTA, RIMPen rkey, PINB; leer valores claveori rDCnt, 0x08; bit 3lsl rDCnt; mostrador turno dejóBRCC TC1Capt1; fin de cicloadiw ilo, 1; siguiente dígitoRIMP ld, Y; leer dígito siguiente pantallacabo PORTC, RIMP; escribir al puertoRIMP ldd, Y + 4; leer pantalla de alarma dígitoscabo PORTD, RIMP; escribir al puertocabo PORTA, rDCnt; establecer piloto activocabo SREG, rsreg; restaurar SREGreti

TC1Capt1:LDI YH, HIGH (sTime); puntero reinicioLDI YL, LOW (sTime)RIMP ld, Y; leer primer dígitocabo PORTC, RIMP; escribir al puertoRIMP ldd, Y + 4; leer hora de la alarma primer dígitocabo PORTD, RIMP; escribir al puertoLDI rDCnt, 0xE0; mostrar empezando por el bit 4 = 0cabo PORTA, rDCntcabo SREG, rsreg; restaurar SREGreti

;; TC1 Comp A alcanzó;TC1CompA:

en rsreg, SREG; guardar SREGrC5ms diciembre; cuenta atrás para los segundosBrne TC1CompA1; no cerosbr rFlag, 1 << BSEC; bandera de conjuntoLDI rC5ms, 200; iniciar nueva

TC1CompA1:cabo SREG, rSreg; restaurar SREGreti

;; TC1 Comp B alcanzó;TC1CompB:

LDI RIMP, 0xF0; cambiar los conductores de ánodo fuera

cabo PORTA, RIMPreti

;; ADC interrupción listo;AdcInt:

en rsreg, SREG; guardar SREGen RIMP, ADMUX; bajo o alto byte?SBRC RIMP, MUX0rjmp AdcInt1en RIMP, ADCH; leer MSB ADC resultadoañadir rAdcPL, RIMP; añadir a resultarRIMP LDI, 0; añadir byte altoadc rAdcPH, RIMPRIMP LDI, (1 << Adlar) | (1 << MUX0); canal ajustado 1cabo ADMUX, RIMPRIMP LDI, (1 << ADEN) | (1 << ADSC) | (1 << ADIE) | (1 <<

ADPS2) | (1 << ADPS1) | (1 << ADPS0); iniciar la conversióncabo ADCSRA, RIMPcabo SREG, rsreg; restaurar SREGreti

AdcInt1:en RIMP, ADCH; leer MSB ADC resultadoañadir rAdcFL, RIMP; añadir a resultarRIMP LDI, 0; añadir byte altoadc rAdcFH, RIMPdiciembre rAdcC; contador de diciembreBrne AdcInt2; no ceropts sAdcP, rAdcPH; copia resultado ollapts sAdcF, rAdcFH; copia resultado fototransistorclr rAdcPL; sumadores clarasclr rAdcPHclr rAdcFLclr rAdcFHsbr rFlag, 1 << BADC; pabellón conjunto ADC

AdcInt2:LDI RIMP, 1 << Adlar; conjunto de canales 0cabo ADMUX, RIMPRIMP LDI, (1 << ADEN) | (1 << ADSC) | (1 << ADIE) | (1 <<

ADPS2) | (1 << ADPS1) | (1 << ADPS0); iniciar la conversióncabo ADCSRA, RIMPcabo SREG, rsreg; restaurar SREGreti

;; TC0 comparar partido de interrupción;Tc0Comp:

en rSreg, SREG; guardar SREGtst rDurL; duración de cero?Brne Tc0Comp0; notst rDurH; Cero MSB?BREQ Tc0CompR; sí, omita

Tc0Comp0:sbiw rDurL, 1; disminuir la duración counterBrne Tc0CompR; no es cero, ir eninc Reep; aumentar la dirección de EEPROMmov RIMP, Reep; dirección copia EEPROM leídoRIMP lsl; multiplicar por 2cabo EEARL, RIMPRIMP LDI, 0; byte superiorRIMP adc, RIMP

cabo EEARH, RIMPLDI RIMP, 1 << EERE; leer permitirá EEPROMcabo EECR, RIMPen RIMP, EEDR; leer primer byteRIMP tst; compruebe 0Brne Tc0Comp01diciembre RIMPcabo OCR0, RIMP; escribir en CTCLDI RIMP, (1 << WGM01) | (1 << COM01) | (1 << CS01); salida COM

claracabo TCCR0, RIMP; modo de ajuste y COMrjmp Tc0Comp2

Tc0Comp01:cabo OCR0, RIMP; escribir en CTCLDI RIMP, (1 << WGM01) | (1 << COM00) | (1 << CS01); salida COM

de palancacabo TCCR0, RIMP; modo de ajuste y COM

Tc0Comp2:en RIMP, EEARL; leer dirección más bajaRIMP inc; aumento direccióncabo EEARL, RIMP; establecer LSB direcciónLDI RIMP, 1 << EERE; habilitación de lecturacabo EECR, RIMP; para controlar registroen rDurH, EEDR; leer duraciónrDurL clrtst rDurH; compruebe final de la melodíaBrne Tc0Comp3; no, ir enLDI RIMP, (1 << WGM01) | (1 << COM01) | (1 << CS01); salida COM

claracabo TCCR0, RIMP; modo de ajuste y COMLDI RIMP, 0xFF; largo tiempoLDI rDurH, alta (cPauseLong); larga duracionLDI rDurL, Low (cPauseLong)LDI Reep, 0xFF; melodía reinicio después de la pausarjmp Tc0CompR

Tc0Comp3:LSR rDurHror rDurLLSR rDurHror rDurLLSR rDurHror rDurLLSR rDurHror rDurLLSR rDurHror rDurL

Tc0CompR:cabo SREG, rSreg; restaurar SREGreti

;; ================================================== =; M ainprograminit; ================================================== =;Empezar:

; pila initLDI rmp, HIGH (RAMEND); init el MSB del puntero de pilaSPH cabo, rmpLDI rmp, LOW (RAMEND); init el del puntero de pila LSBcabo SPL, rmp; puertos de inicio

rmp LDI, 0xFF; set Puertos C y D sean salidas y fueracabo DDRC, rmpcabo DDRD, rmp

; cabo PORTC, rmp; cabo PORTD, rmp

rmp LDI, 0xF0; configurar el puerto A cuatro bits superiores para ser salidas y fuera cabo DDRA, rmp

rmp LDI, 0xE0cabo PORTA, rmprmp LDI, 0x00cabo PORTC, rmpcabo PORTD, rmp; pantalla de prueba.si dbg == 1rmp LDI, 0xE0cabo PORTA, rmp

ex1: rjmp ex1.terminara si.si dbg == 2rmp LDI, 0xD0cabo PORTA, rmp

EX2: rjmp EX2.terminara si.si dbg == 3rmp LDI, 0xB0cabo PORTA, rmp

ex3: rjmp ex3.terminara si.si dbg == 4rmp LDI, 0x70cabo PORTA, rmp

ex4: rjmp ex4.terminara si

; final de la pruebarmp LDI, 0x08; set bits de puerto B 0..2 sean de entrada, 3 a

la salidacabo DDRB, rmprmp LDI, 0x07; establecidos pull-ups en insumos clave activascabo PORTB, rmp; controladores de pantalla de inicio, establecer todas las

pantallas a 0LDI YH, HIGH (SCS); punto en cuando información de inicioLDI YL, LOW (SCS)clr R0rmp LDI, 7; tiempo claro en SRAM

Start1:st Y +, R0diciembre rmpBrne Start1rcall UPDATETIME; configurar visualización de la horarcall UpDateAlarm; configurar la pantalla de alarmacabo PORTC, rmp; puertos de visualizacióncabo PORTD, rmpLDI rDCnt, 0x70; establecer última pantalla para conductorLDI YH, HIGH (sTime + 3); apuntar a mostrar inicioLDI YL, LOW (sTime + 3)clr rFlag; establecer indicadores a cerormp clr; desactivar el watchdogcabo WDTCR, rmp; ADC init

rmp LDI, 1 << Adlar; Izquierda ajustar resultado, el canal 0, VREF externa

cabo ADMUX, rmprmp clr; conjunto Srorcabo SFIOR, rmprmp LDI, (1 << ADEN) | (1 << ADSC) | (1 << ADIE) | (1 << ADPS2)

| (1 << ADPS1) | (1 << ADPS0); permitir a ADCcabo ADCSRA, rmp; rmp LDI, 1; dimm conjunto comprobando en primer ciclo ADCmov rFChk, rmp; temporizador init 0rDurL clr; establecer la duración de cero para bloquear

temporizadorclr rDurHrmp LDI, 175; conjunto de valores comparar a 175 (880 cs / s)cabo OCR0, rmpLDI rmp, (1 << WGM01) | (1 << COM00); dejar de temporizador de

la alarmacabo TCCR0, rmp; modo de ajuste y COM; temporizador init 1 como reloj y conductor dígitos

divisor .equ = (5 * reloj + 500) / 1000; 5 ms Tiempo intLDI rmp, HIGH (divisor); establecer comparar coincidir ICR1cabo ICR1H, rmpLDI rmp, LOW (divisor)cabo ICR1L, rmpLDI rmp, HIGH (divisor / 2); establecer comparar partido A como

5-ms-intcabo OCR1AH, rmpLDI rmp, LOW (divisor / 2)cabo OCR1AL, rmpLDI rmp, HIGH (divisor - 2); set comparar partido B como tenue

intcabo OCR1BH, rmpLDI rmp, LOW (divisor - 2)cabo OCR1BL, rmprmp clr; claro WGM11 y WGM10cabo TCCR1A, rmprmp LDI, (1 << WGM13) | (1 << WGM12) | (1 << CS10); ICR-CTC,

div = 1cabo TCCR1B, rmp; permitir que las interrupciones del temporizadorrmp LDI, (1 << OCIE1A) | (1 << OCIE1B) | (1 << TICIE1) | (1 <<

OCIE0); ICR1-, COMP1-, TC0 int permitecabo TIMSK, rmp; modo de suspensión conjuntoLDI rmp, 1 << SE; conjunto del sueño habilitar y modo de

suspensión 0cabo MCUCR, rmp; permitir que las interrupcionessei

; ================================================== =; M ainprogramloop; ================================================== =Lazo:

dormir; Ir a dormirnop; maniquí después de despertar

;llaves rcall; comprobar claves después de cada activación

; Verifique las banderas que se han establecidoSBRC rFlag, BSEC; saltar sobre si segunda bandera no establecercall Segundo

SBRC rFlag, BADC; saltar sobre si hay nuevos resultados de conversión ADC

rcall AdcNewrjmp Loop

;; ================================================== =; C heckkeys; ================================================== =;.equ cKeyRed = 0x06.equ cKeyBlack = 0x05.equ cKeyWhite = 0x03llaves:

andi rkey, 0x07; aislar llavesrmp lds, sKey; leer el valor clave almacenadarmp cp, rkey; comparar el valor llavekey1 BREQ; clave EQAL; clave diferente de la última llave, almacenar nueva, contador

clarapts sKey, rkey; del almacén de clavesrmp LDI, 0; recuento claropts sKeyC, rmpenriar

key1:; clave es igual última teclarmp lds, sKeyC; leer recuento de clavesrmp inc; aumentar el número de clavepts sKeyC, rmp; tiendarmp cpi, 3; tres códigos claves idénticaskey2 BREQ; idénticoBRCS key1aLDI rmp, 5pts sKeyC, rmp

key1a:enriar

key2:; llave válidarmp lds, sKey; leer código de la llavermp cpi, 0x07; clave unpressed?key3 BREQ; sípts sKeyS, rmp; almacén de claves seleccionadoenriar

key3:rmp lds, sKeyS; leer la clave seleccionadaLDI ZL, 0pts sKeyS, ZLtst rmpkey4 Brneenriar

key4:; saltos condicionales de acuerdo con banderasSBRC rFlag, bAlarm; Actualmente alarma?rjmp keyAlarm; reaccionar a la tecla durante la alarmaSBRC rFlag, bArmed; armado actualmente?rjmp keyArmed; reaccionar ante clave durante armadoSBRC rFlag, bSetC; Actualmente el ajuste del reloj?rjmp keySetC; reaccionar ante clave durante el ajuste del relojSBRC rFlag, bSetA; Actualmente se encuentra en el

establecimiento de hora de la alarma?rjmp keySetA; reaccionar a la tecla durante el ajuste de hora

de la alarma; modo normal, tratar como nueva clavermp cpi, cKeyRed; tecla roja?key5 Brne; no

sbr rFlag, 1 << bSetC; bandera de conjuntoenriar

key5:rmp cpi, cKeyWhite; tecla blanca?key6 Brne; nosbr rFlag, 1 << bSetA; bandera de conjuntoenriar

key6:rmp cpi, cKeyBlack; llave de color negro?key7 BrneLDI rmp, 1 << bArmed; bandera armada de palancaeo rFlag, rmpenriar

key7:enriar

keySetC:; teclas durante conjunto Crmp cpi, cKeyBlack; llave negro presionado = saltarBrne keySetC1cbr rFlag, (1 << bSetC) | (1 << bSetCM); banderas clarasrjmp UPDATETIME

keySetC1:rmp cpi, cKeyRed; tecla roja presionaBrne keySetC3; no; tecla roja presionaSBR rFlag, bSetCm; fijar los minutos del reloj?rjmp keySetC2; no hay, hora establecidos; minutos setrmp clr; segundo claraspts SCS, RMPrmp lds, sAdcPLDI ZL, 60rmp mul, ZLpts SMC, R1cbr rFlag, (1 << bSetC) | (1 << bSetCm); banderas clarasrjmp UPDATETIME

keySetC2:; horario fijormp lds, sAdcPLDI ZL, 24rmp mul, ZLpts SCH, R1rmp clr; segundo claraspts SCS, RMPsbr rFlag, (1 << bSetC) | (1 << bSetCm); pabellón conjunto

minutosenriar

keySetC3:; clave ilegalenriar

keySetA:; teclas durante conjunto Armp cpi, cKeyBlack; llave negro presionado = saltarkeySetA1 Brne; nocbr rFlag, (1 << bSetA) | (1 << bSetAm); banderas clarasrjmp UpDateAlarm

keySetA1:rmp cpi, cKeyWhite; tecla blanca presionado?keySetA3 Brne; no; tecla blanca pulsaSBR rFlag, bSetAm; establecer minutos de la alarma?rjmp keySetA2; no hay, hora establecidos; minutos setrmp lds, sAdcP; leer el valor ollaLDI ZL, 60

mul ZL, rmpsts sAm, R1; conjunto hora de la alarmasts SSM, R1; set Set hora de la alarmacbr rFlag, (1 << bSetA) | (1 << bSetAm); banderas de alarma

conjunto clarassbr rFlag, 1 << bArmed; set bandera armadarjmp UpDateAlarm

keySetA2:; horario fijormp lds, sAdcPLDI ZL, 24mul ZL, rmpsts Sah, R1; conjunto hora de la alarmapts SSH, R1; set Set hora de la alarmasbr rFlag, 1 << bSetAm; minutos set banderaenriar

keySetA3:enriar

keyAlarm:; clave durante la alarmarmp cpi, cKeyRed; tecla roja presionado?Brne keyAlarm1; tecla roja durante la alarma: función de repetición

keyAlarmSnooze:rmp lds, Sam; leer minutos de la alarmarmp subi, -cSnooze; añadir tiempo de pausapts sAm, rmp; y almacenarrmp cpi, 60; superior o igual 60 minutos?BRCS keyAlarmOff; no, ir enrmp subi, 60; restar 60 minutospts sAm, rmp; y almacenarrmp lds, Sah; leer horasrmp inc; siguiente horapts Sah, rmp; y almacenarrmp cpi, 24; mayor o igual 24BRCS keyAlarmOff; no, ir enrmp clr; hora de reiniciopts Sah, rmp; y almacenar

keyAlarmOff:cbr rFlag, 1 << bAlarm; bandera de alarma claraLDI rmp, (1 << WGM01) | (1 << COM00); dejar de temporizador de

la alarmacabo TCCR0, rmp; modo de ajuste y COMcbi PORTB, 3; claro poco puerto OC0rjmp UpDateAlarm;

keyAlarm1:rmp cpi, cKeyBlack; llave negro presionado?Brne keyAlarm2; no; clave de negro durante la alarma: alarma establecido y

armados fuerarmp lds, SSM; leer minutos de la alarma de ajustepts sAm, rmp; escribir en minutos de la alarmarmp lds, SSH; leer minutos de la alarmapts Sah, rmp; escribir en minutos de la alarmacbr rFlag, 1 << bArmed; clara bandera armadarjmp keyAlarmOff

keyAlarm2:; cualquier otra tecla: no hacer nadaenriar

keyArmed:; clave durante armadarmp cpi, cKeyBlack; llave negro presionadoBrne keyArmed1; no presionado; clave de negro durante la armada

cbr rFlag, 1 << bArmed; conjunto armado fuerarmp lds, SSM; leer minutos de la alarma de ajustepts sAm, rmp; escribir en minutos de la alarmarmp lds, SSH; leer minutos de la alarmapts Sah, rmp; escribir en minutos de la alarmarjmp UpDateAlarm

keyArmed1:rmp cpi, cKeyRed; tecla roja durante armadaBrne keyArmed2; no presionado; tecla roja durante el armado: incremento hora de la alarmarjmp keyAlarmSnooze; aumentar el tiempo de alarma

keyArmed2:; cualquier otra tecla: ignoreenriar

;; ================================================== =; Un secondisover; ================================================== =;En segundo lugar:

cbr rFlag, 1 << BSEC; claro segunda banderarmp lds, SCS; leer segundosrmp inc; segundo siguientepts SCS, rmp; tiendas segundos.si dbg == 5rcall dispsec.terminara sirmp cpi, 60; siguiente minuto?BRCS segundo1; no aún normp clr; segundo claraspts SCS, rmp; tienda de cerormp lds, SMC; leer minutormp inc; minuto siguientepts SMC, rmp; minutos de tiendasrmp cpi, 60; siguiente hora?Brne UPDATETIMErmp clr; minutos claraspts SMC, rmp; minutos de tiendasrmp lds, SCH; leer horasrmp inc; siguiente horapts SCH, rmp; horario de la tiendarmp cpi, 24; día siguiente?Brne UPDATETIMErmp clr; hora claraspts SCH, RMPrjmp UPDATETIME

Segundo1:; puntos de tiempo de parpadeoSBRC rFlag, bSetCrjmp Second4rmp ror; bit más bajo para llevarrmp lds, sTime; carga representada primer dígitoBRCS segundo2; bajo bit = 1rmp sbr, 1 << 7; claro llevadorjmp segundo3

Segundo2:rmp cbr, 1 << 7; conjunto dirigido

Segundo3:pts sTime, rmp; que aparece primero dígitos; puntos de alarma de parpadeo

Second4:SBR rFlag, bArmed; si no regreso armado

enriarrmp lsl; bit 7 para llevarrmp lds, SALARM; leer posición de alarmaBRCS Second5rmp andi, 0x7F; poco clara 7rjmp Second6

Second5:rmp sbr, 1 << 7; poco juego 7

Second6:pts SALARM, rmp; tienda byte de alarmaenriar

dispsec:rmp lds, SCSLDI XH, alta (SALARM + 2)LDI XL, Low (SALARM + 2)rcall To7Segrmp lds, SCSenriar

; ================================================== =; U pdatedisplay; ================================================== =;; Actualización mostrada hora de la alarma;UpDateAlarm:

LDI XH, alta (SALARM)LDI XL, Low (SALARM)rmp lds, Sahrcall To7Segrmp lds, Samrjmp To7Seg

;; Actualiza la hora que se muestra;UPDATETIME:

SBRC rFlag, bArmed; si armado, comparar hora de la alarmarcall CheckAlarm; comprobar el tiempo de alarmaSBRC rFlag, bSetC; si de ajuste del reloj activo, omitirenriarLDI XH, alta (sTime); punto en cuandoLDI XL, LOW (sTime)rmp lds, SCH; leer horasrcall To7Segrmp lds, SMC; leer minuto

To7Seg:clr R0; R0 es contraproducente

To7Seg1:subi rmp, 10BRCS To7Seg2inc R0rjmp To7Seg1

To7Seg2:subi rmp, -10LDI ZH, ALTA (2 * Tab7Seg); cuadro de cargasLDI ZL, LOW (2 * Tab7Seg)añadir ZL, R0BRCC To7Seg3inc ZH

To7Seg3:lpmst X +, R0

LDI ZH, ALTA (2 * Tab7Seg); cuadro de cargasLDI ZL, LOW (2 * Tab7Seg)añadir ZL, rmpBRCC To7Seg4inc ZH

To7Seg4:lpmst X +, R0enriar

; Tabla de conversión decimal a 7 segmentosTab7Seg:.db 0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10; valores hexadecimales.db 0x08,0x03,0x27,0x21,0x06,0x0E;; ================================================== =; C heckalarmtimereached; ================================================== =;CheckAlarm:

lds R0, SCH; leer horas relojrmp lds, Sah; leer hora de alarmacp R0, rmp; iguales?Brne CheckAlarmRetlds R0, SMC; leer minutos de relojrmp lds, Sam; leer minutos de la alarmacp R0, rmp; iguales?Brne CheckAlarmRetsbr rFlag, 1 << bAlarm; conjunto del indicador de alarmaSer Reep; frente hasta el final de EEPROMLDI rDurL, 1; comenzar en la nueva dirección en el ciclo intclr rDurHrmp LDI, (1 << WGM01) | (1 << COM01) | (1 << CS01); iniciar

temporizador de la alarmacabo TCCR0, rmp; modo de ajuste y COM y preescala = 8

CheckAlarmRet:enriar

;; ================================================== =; N ew Un dcresultprovided; ================================================== =;AdcNew:

cbr rFlag, 1 << BADC; clara bandera ADC.si dbg == 6rcall dispadc.terminara sidiciembre rFChk; cheque tenue ajustar?Brne AdcNew2; no ajustermp LDI, 0x10; establecido countermov rFChk, rmprmp lds, sAdcF; leer el valor fototransistorrmp cpi, 0xFF; oscuridad?BRCS AdcNew1; noLDI rmp, HIGH (divisor / 2); establecer un medio tiempocabo OCR1BH, rmpLDI rmp, LOW (divisor / 2)cabo OCR1BL, rmprjmp AdcNew2

AdcNew1:rmp LDI, HIGH (divisor-30); establecer a tiempo completo

cabo OCR1BH, rmprmp LDI, LOW (divisor-30)cabo OCR1BL, rmp

AdcNew2:rmp lds, sAdcP; leer el valor ollaSBR rFlag, bSetC; Ajuste de C?rjmp AdcNew4; N ° C; establecer CSBR rFlag, bSetCm; minutos de ajuste?rjmp AdcNew3; visualización minutos de ajuste ollaLDI XH, alta (sTime + 2); puntero del conjuntoLDI XL, Low (sTime + 2)LDI ZL, 60; 60 minutosrjmp Mult; multiplique y visualización

AdcNew3:; horas de visualización de ajusteLDI XH, alta (sTime); puntero del conjuntoLDI XL, Low (sTime)LDI ZL, 24; multiplicar por 24rjmp Mult; multiplicar y mostrar

AdcNew4:SBR rFlag, bSetA; Un entorno?ret; noSBR rFlag, bSetAm; ¿minutos?rjmp AdcNew5; noLDI XH, alta (SALARM + 2); puntero del conjuntoLDI XL, Low (SALARM + 2)LDI ZL, 60rjmp Mult; multiplicar y mostrar

AdcNew5:LDI XH, alta (SALARM); puntero del conjuntoLDI XL, Low (SALARM)LDI ZL, 24rjmp Mult

;; Multiplicar y mostrar;Mult:

mul ZL, rmprmp mov, R1rjmp To7Seg

;; ================================================== =; Ebug D: D isplayadcresult; ================================================== =;dispadc:

LDI XH, HIGH (SALARM)LDI XL, LOW (SALARM)rmp lds, sAdcPrcall dispadc1lds rmp, sAdcF

dispadc1:empuje rmprmp de intercambiorcall dispadc2rmp pop

dispadc2:rmp andi, 0x0FLDI ZH, ALTA (2 * Tab7Seg)LDI ZL, LOW (2 * Tab7Seg)

añadir ZL, rmpBRCC dispadc3inc ZH

dispadc3:lpmst X +, R0enriar

;; ================================================== =; C opyrightinformation; ================================================== =;.db "C (2) 10 0ybh tt: p // ww.wva-rsa-mutotirlan.te";; ================================================== =; M elodyin EEPROM; ================================================== =;.eseg.org $ 0.000;.equ cPa = 10; duración de la pausa.equ Cd = 9,216; tono de duración constante;; Tabla de frecuencia.equ cf2e = 659.equ cf2f = 698.equ cf2g = 784.equ cf2a = 880.equ CF2H = 988.equ cf3c = 1047.equ CF3D = 1175.equ cf3e = 1319.equ cf3f = 1397.equ cf3g = 1568.equ cf3a = 1760.equ cf3h = 1976.equ cf4c = 2093.equ cf4d = 2349.equ cf4e = 2637.equ cf4f = 2794.equ cf4g = 3136.equ cf4a = 3520.equ cf4h = 3951.equ cf5c = 4186; Mesa de CTC para estas frecuencias.equ cc2e = reloj / 16 / cf2e.equ cc2f = reloj / 16 / cf2f.equ cc2g = reloj / 16 / cf2g.equ cc2a = reloj / 16 / cf2a.equ cc2h = reloj / 16 / CF2H.equ cc3c = reloj / 16 / cf3c.equ CC3D = reloj / 16 / CF3D.equ cc3e = reloj / 16 / cf3e.equ cc3f = reloj / 16 / cf3f.equ cc3g = reloj / 16 / cf3g.equ cc3a = reloj / 16 / cf3a.equ cc3h = reloj / 16 / cf3h.equ cc4c = reloj / 16 / cf4c.equ cc4d = reloj / 16 / cf4d.equ cc4e = reloj / 16 / cf4e

.equ cc4f = reloj / 16 / cf4f

.equ cc4g = reloj / 16 / cf4g

.equ cc4a = reloj / 16 / cf4a

.equ cc4h = reloj / 16 / cf4h

.equ cc5c = reloj / 16 / cf5c; constantes duración tono.equ cd2e = cd / cc2e.equ cd2f = cd / cc2f.equ cd2g = cd / cc2g.equ CD2a = cd / cc2a.equ cd2h = cd / cc2h.equ cd3c = cd / cc3c.equ cd3d = cd / CC3D.equ CD3e = cd / cc3e.equ cd3f = cd / cc3f.equ cd3g = cd / cc3g.equ cd3a = cd / cc3a.equ cd3h = cd / cc3h.equ cd4c = cd / cc4c.equ cd4d = cd / cc4d.equ CD4E = cd / cc4e.equ cd4f = cd / cc4f.equ cd4g = cd / cc4g.equ cd4a = cd / cc4a.equ cd4h = cd / cc4h.equ cd5c = cd / cc5c; melodía; 3a 4g 4g 4f; 4e 4d 4d; 4c 4c 3h 4f; 4f 4g-4f; mesacc3g .db, cd3g, cc3g, cd3g, cc3f, cd3f, cc2a, CD2a.db cc3e, CD3e, CC3D, cd3d, CC3D, cd3dcc3c .db, cd3c, cc2h, cd2h, cc3c, cd3c, cc3f, cd3f.db cc3f, cd3f, cc3g, cd3g, cc3f, cd3f; final de la tabla.db 0,0;; Fin del código fuente;

1111111111111111111111111111111111111111111111111111111111111111111111111111

; *********************************************; * Reloj AVR digital con una ATmega16 *; * (C) 2010 por info (at) avr-asm-tutorial.net *; *********************************************;.NOLIST.include "m16def.inc".list;; ================================================== =

; Ebuggingparameters D; ================================================== =; dbg = 0: la depuración de discapacitados, ejecución normal del programa; dbg = 1: la luz primera pantalla; dbg = 2: segunda pantalla de luz; dbg = 3: tercera pantalla de luz; dbg = 4: pantalla Fouth luz; dbg = 5: visualización segundos en posición de alarma minutos; dbg = 6: resultados de visualización de ADC en hexadecimal en la pantalla de alarma;.equ dbg = 0;; ================================================== =; H ardware; ================================================== =; Tipo de procesador: ATmega16; _________; / |; Rojo Key - | ADC0 PB0 | - Entrada Pot; Blk Key - | ADC1 PB1 | - Entrada fototransistor; WHT Key - | PB2 | -; Altavoz - | OC0 | -; - | PA4 | - 1 dígito ánodo conductor; ISP MOSI - | MOSI PA5 | - 2; MISO - | MISO PA6 | - 3; SCK - | SCK PA7 | - 4; REINICIAR - | REINICIAR AREF | - + 5V; VCC - | GND VCC | - GND; GND - | GND AVCC | - + 5V; XTAL2 - | XTAL2 PC7 | - Grandes puntos LED; XTAL1 - | XTAL1 PC6 | - g Grande; Pequeño a - | PD0 PC5 | - f siete; siete b - | PD1 PC4 | - e segm.; segm. c - | PD2 PC3 | - d displ.; displ.d - | PD3 PC2 | - c cateterismo.; cateterismo. e - | PD4 PC1 | - b; f - | PD5 PC0 | - una; g - | PD6 PD7 | - puntos LED Pequeños; | ___________; ; ================================================== =; Escriptionhowitworks D; ================================================== =; ; a) Muestra y modos de visualización; Las grandes pantallas de 7 segmentos superiores muestran el tiempo,; los más bajos, pequeños displays de 7 segmentos muestran la alarma; hora. Los LED doble de puntos más grandes de la pantalla superior; parpadeará en segundos intervalos. El doble punto más pequeño; LED de abrir y cerrar la pantalla inferior, si la alarma es; armado, y son siempre encendido, si se desarma la alarma.; b) Indicación de multiplexación; El diplay utiliza Contador / Temporizador 1 en el modo CTC; interrumpir cada 5 ms después de alcanzar su valor máximo.; Los 4 pantallas se actualizan en 20 ms, produciendo una; refrescar frecuencia de 50 cs / s.; La pantalla se apaga primero, el puntero; al dígito que se muestra es informaciones avanzadas y cifras; en SRAM se escriben en los Puertos C (pantalla grande

; para el tiempo) y D (pequeña pantalla para la alarma; tiempo), el puerto del controlador ánodo adecuado mordió en; el nibble superior del Puerto A se establece activa (= 0).; c) Indicación de regulación; Pantalla de atenuación utiliza el TC1 en modo CTC y Compara; Partido B interrumpir desactivar los controladores de ánodo. Los; comparar el valor partido se calcula a partir del valor de ADC; que resulta de la fototransistor: menos luz; está en el transistor mayor es su tensión de colector; y cuanto mayor sea su valor ADC y el más alto es el com-; pare valor partido B. Tenga en cuenta que este es un no lineal; función.; d) tiempo de recuento; El conteo de tiempo TC1 utiliza en el modo y la CTC; Comparar Partido Una interrupción de recuento descendente de un contador; de 200 a cero. Si se llega a cero, se establece un indicador; y el 5-ms-contador se reinicia.; Fuera de la rutina de servicio de interrupción, el tiempo es; adelantada por un segundo, la actualización de la hora después de los 60; segundos. Si la alarma está armado, se compara el tiempo; con el tiempo de alarma y se activa una alarma cuando; tiempo = tiempo de alarma.; e) Keys; Las teclas se leen cada vez que una estela de interrupción hasta; se llevó a cabo. Las teclas activas se reconocen después de 15 ms; y se almacena. La acción respectiva se ejecuta después; todas las teclas están inactivas durante al menos 15 ms.; La siguiente tabla muestra las reacciones clave en diferente; modos de operación.; Modo de acción clave; -------------------------------------------------- -; Normal Negro Toggle poco armado; Red Introduzca el modo de ajuste; Blanco Ingrese al modo de ajuste de hora de la alarma; Ajuste del modo de ajuste de la hora Negro Saltar Tiempo; Rojo Set de tiempo (horas o minutos); Alarma Ajuste del modo de ajuste de hora de alarma Negro Saltar; Blanco Conjunto hora de la alarma (hora o minuto); Armado Negro Desactivar armado; Red Avance hora de la alarma por la repetición; Alarmado alarma Negro Desactivar y restablecer la alarma; hora; Red Desactivar alarma y alarma anticipada; tiempo de pausa; f) conversión AD; El ADC se ejecuta con un pre-escalador de 128, mide dos; canales y se controla a través de interrupción.; Las tensiones analógicas del potenciómetro (canal; ADC0) y del colector del fototransistor; (ADC1 canal) se miden, superior al ajustado izquierda-; byte resultado se añade a una suma de 16 bits. Si 256 medición; mentos por canal tuvieron lugar, el MSB del 16 de bits; resultado se entregó a una rutina fuera de la interrupción; rutina de servicio. Los resultados de los canales se utilizan para; Ch0: si en el tiempo o el modo de ajuste de la alarma, se convirtió al; horas o minutos y se muestra; Ch1: convertirse al comparar los valores partido B para establecer la tenue

; tiempo y reducir el brillo en un lugar oscuro; ambiente.; g) el ruido de alarma; TC0 proporciona un generador de AF programable mediante el establecimiento de; el temporizador en el modo CTC y alternar el OC0 pin de salida; en partido de comparar. El TC0 corre con un pre-escalador de 8,; proporcionar señales de audio entre 600 (OCR0 = 255) y; 9600 (OCR0 = 16) cs / s.; Una interrupción en alcanzar CTC superior toca una melodía; situado en el espacio EEPROM leyendo el valor CTC; y la duración del tono. Después de llegar a la mesa; final, el temporizador y la salida OC0 conmutación está desactivado.;; ================================================== =; C onstants; ================================================== =;.equ reloj = 2457600; Frecuencia Xtal.equ cSnooze = 5; snooze tiempo de duración de alarma.equ cPauseLong = $ 4.000; larga pausa para la repetición de la melodía;; ================================================== =; Egisters R; ================================================== =;; R0 utiliza para LPM a flash y para los cálculos; R1 utiliza para los cálculos; libre R2..R8.def rFChk = R9; comprobar el ajuste dimm.def rAdcC = R10; Contador de ADC.def rAdcFL = R11; ADC resultado sumador fototransistor, byte bajo.def rAdcFH = R12; ADC resultado sumador fototransistor, byte alto.def rAdcPL = R13; Adc resultado sumador potenciómetro, byte bajo.def rAdcPH = R14; Adc resultado sumador potenciómetro, byte alto.def rSreg = R15; SREG temperatura interior ints.def rmp = R16; enteros fuera de usos múltiples.def RIMP = R17; enteros dentro de usos múltiples.def rFlag = R18; bandera de registro

.equ bArmed = 0; La alarma está activada

.equ bAlarm = 1; La alarma está activa

.equ bSetC = 2; Para ajustar el reloj

.equ bSetCm = 3; Minutos de ajuste del reloj

.equ bSetA = 4; Ajustar alarma

.equ bSetAm = 5; Minutos Establecer alarma

.equ BSEC = 6; segundo siguiente alcanzó

.equ BADC = 7; nuevo resultado ADC listo.def rC5ms = R19; Contador de 5ms a segundo.def rDCnt = R20; Display Driver contador ánodo.def rkey = R21; almacenamiento de código clave última tecla, vivo.def Reep = R23; EEPROM leer dirección.def rDurL = R24; Contador de tiempo Duración LSB.def rDurH = R25; Duración contador de tiempo MSB; R27: R26 utiliza para señalar enteros fuera; R29: R28 utiliza como puntero pantalla dentro ints; R31: R30 utiliza para señalar enteros fuera;; ================================================== =; Ubicaciones SRAM; ================================================== =

;.DSEG.ORG Sram_StartsTime:.byte 4; cuatro bytes dígitos para la gran pantallaSALARM:.byte 4; cuatro bytes dígitos para la pequeña pantallaSCS:.byte 1; segundo relojSMC:.byte 1; minutos de relojSCH:.byte 1; horas relojSSM:.byte 1; minutos de la alarma de ajusteSSH:.byte 1; set hora de alarmaCarter:.byte 1; minutos de la alarmaSAH:.byte 1; hora de alarmasAdcP:.byte 1; Adc resultado ollasAdcF:.byte 1; Resultado fototransistor AdcsKey:.byte 1; tecla pulsadasKeyC:.byte 1; contador de tecla pulsadasKeyS:.byte 1; clave seleccionada;; ================================================== =; T imings; ================================================== =;; ADC:; - Canal MUX 0 medidas olla, canal MUX 1 medidas fototransistor; - Funciona a divisor = 128; - Por interrupciones; - Resultado se deja ajustar, sólo se utilizan los 8 bits superiores; - En int, se añaden los 8 bits superiores del resultado a un bit de suma 16; - Después de 256 resultados, los 8 bits superiores de la suma se copian; - Cuando se ejecuta, una conversión requiere 13 ciclos de reloj ADC; - f = 2457600/128/13/256 = 5,77 cs / s = 173,3 ms;; ================================================== =; R esetand I ntvectors; ================================================== =;.cseg.org $ 0.000

RJMP comenzar; Restablecer vectorialnopreti; INT0nopreti; INT1nopreti; TC2COMP

nopreti; TC2OVFnoprjmp TC1Capt; TC1CAPTnoprjmp TC1CompA; TC1COMPAnoprjmp TC1CompB; TC1COMPBnopreti; TC1OVFnopreti; TC0OVFnopreti; SPI, STCnopreti; USART RXCnopreti; USART UDREnopreti; USART TXCnoprjmp AdcInt; ADCnopreti; EERDYnopreti; Anacompnopreti; TWInopreti; INT2noprjmp Tc0Comp; TC0COMPnopreti; SPM RDYnop

;; ================================================== =; Yo nterrupt S ervicio Outines R; ================================================== =;; TC1 ICR período final, mostrar siguiente dígito;TC1Capt:

en rsreg, SREG; guardar SREGLDI RIMP, 0xF0; borrar todos los conductores dígitoscabo PORTA, RIMPen rkey, PINB; leer valores claveori rDCnt, 0x08; bit 3lsl rDCnt; mostrador turno dejóBRCC TC1Capt1; fin de cicloadiw ilo, 1; siguiente dígitoRIMP ld, Y; leer dígito siguiente pantallacabo PORTC, RIMP; escribir al puertoRIMP ldd, Y + 4; leer pantalla de alarma dígitoscabo PORTD, RIMP; escribir al puertocabo PORTA, rDCnt; establecer piloto activocabo SREG, rsreg; restaurar SREGreti

TC1Capt1:LDI YH, HIGH (sTime); puntero reinicioLDI YL, LOW (sTime)

RIMP ld, Y; leer primer dígitocabo PORTC, RIMP; escribir al puertoRIMP ldd, Y + 4; leer hora de la alarma primer dígitocabo PORTD, RIMP; escribir al puertoLDI rDCnt, 0xE0; mostrar empezando por el bit 4 = 0cabo PORTA, rDCntcabo SREG, rsreg; restaurar SREGreti

;; TC1 Comp A alcanzó;TC1CompA:

en rsreg, SREG; guardar SREGrC5ms diciembre; cuenta atrás para los segundosBrne TC1CompA1; no cerosbr rFlag, 1 << BSEC; bandera de conjuntoLDI rC5ms, 200; iniciar nueva

TC1CompA1:cabo SREG, rSreg; restaurar SREGreti

;; TC1 Comp B alcanzó;TC1CompB:

LDI RIMP, 0xF0; cambiar los conductores de ánodo fueracabo PORTA, RIMPreti

;; ADC interrupción listo;AdcInt:

en rsreg, SREG; guardar SREGen RIMP, ADMUX; bajo o alto byte?SBRC RIMP, MUX0rjmp AdcInt1en RIMP, ADCH; leer MSB ADC resultadoañadir rAdcPL, RIMP; añadir a resultarRIMP LDI, 0; añadir byte altoadc rAdcPH, RIMPRIMP LDI, (1 << Adlar) | (1 << MUX0); canal ajustado 1cabo ADMUX, RIMPRIMP LDI, (1 << ADEN) | (1 << ADSC) | (1 << ADIE) | (1 <<

ADPS2) | (1 << ADPS1) | (1 << ADPS0); iniciar la conversióncabo ADCSRA, RIMPcabo SREG, rsreg; restaurar SREGreti

AdcInt1:en RIMP, ADCH; leer MSB ADC resultadoañadir rAdcFL, RIMP; añadir a resultarRIMP LDI, 0; añadir byte altoadc rAdcFH, RIMPdiciembre rAdcC; contador de diciembreBrne AdcInt2; no ceropts sAdcP, rAdcPH; copia resultado ollapts sAdcF, rAdcFH; copia resultado fototransistorclr rAdcPL; sumadores clarasclr rAdcPHclr rAdcFLclr rAdcFHsbr rFlag, 1 << BADC; pabellón conjunto ADC

AdcInt2:

LDI RIMP, 1 << Adlar; conjunto de canales 0cabo ADMUX, RIMPRIMP LDI, (1 << ADEN) | (1 << ADSC) | (1 << ADIE) | (1 <<

ADPS2) | (1 << ADPS1) | (1 << ADPS0); iniciar la conversióncabo ADCSRA, RIMPcabo SREG, rsreg; restaurar SREGreti

;; TC0 comparar partido de interrupción;Tc0Comp:

en rSreg, SREG; guardar SREGtst rDurL; duración de cero?Brne Tc0Comp0; notst rDurH; Cero MSB?BREQ Tc0CompR; sí, omita

Tc0Comp0:sbiw rDurL, 1; disminuir la duración counterBrne Tc0CompR; no es cero, ir eninc Reep; aumentar la dirección de EEPROMmov RIMP, Reep; dirección copia EEPROM leídoRIMP lsl; multiplicar por 2cabo EEARL, RIMPRIMP LDI, 0; byte superiorRIMP adc, RIMPcabo EEARH, RIMPLDI RIMP, 1 << EERE; leer permitirá EEPROMcabo EECR, RIMPen RIMP, EEDR; leer primer byteRIMP tst; compruebe 0Brne Tc0Comp01diciembre RIMPcabo OCR0, RIMP; escribir en CTCLDI RIMP, (1 << WGM01) | (1 << COM01) | (1 << CS01); salida COM

claracabo TCCR0, RIMP; modo de ajuste y COMrjmp Tc0Comp2

Tc0Comp01:cabo OCR0, RIMP; escribir en CTCLDI RIMP, (1 << WGM01) | (1 << COM00) | (1 << CS01); salida COM

de palancacabo TCCR0, RIMP; modo de ajuste y COM

Tc0Comp2:en RIMP, EEARL; leer dirección más bajaRIMP inc; aumento direccióncabo EEARL, RIMP; establecer LSB direcciónLDI RIMP, 1 << EERE; habilitación de lecturacabo EECR, RIMP; para controlar registroen rDurH, EEDR; leer duraciónrDurL clrtst rDurH; compruebe final de la melodíaBrne Tc0Comp3; no, ir enLDI RIMP, (1 << WGM01) | (1 << COM01) | (1 << CS01); salida COM

claracabo TCCR0, RIMP; modo de ajuste y COMLDI RIMP, 0xFF; largo tiempoLDI rDurH, alta (cPauseLong); larga duracionLDI rDurL, Low (cPauseLong)LDI Reep, 0xFF; melodía reinicio después de la pausarjmp Tc0CompR

Tc0Comp3:

LSR rDurHror rDurLLSR rDurHror rDurLLSR rDurHror rDurLLSR rDurHror rDurLLSR rDurHror rDurL

Tc0CompR:cabo SREG, rSreg; restaurar SREGreti

;; ================================================== =; M ainprograminit; ================================================== =;Empezar:

; pila initLDI rmp, HIGH (RAMEND); init el MSB del puntero de pilaSPH cabo, rmpLDI rmp, LOW (RAMEND); init el del puntero de pila LSBcabo SPL, rmp; puertos de iniciormp LDI, 0xFF; set Puertos C y D sean salidas y fueracabo DDRC, rmpcabo DDRD, rmp

; cabo PORTC, rmp; cabo PORTD, rmp

rmp LDI, 0xF0; configurar el puerto A cuatro bits superiores para ser salidas y fuera cabo DDRA, rmp

rmp LDI, 0xE0cabo PORTA, rmprmp LDI, 0x00cabo PORTC, rmpcabo PORTD, rmp; pantalla de prueba.si dbg == 1rmp LDI, 0xE0cabo PORTA, rmp

ex1: rjmp ex1.terminara si.si dbg == 2rmp LDI, 0xD0cabo PORTA, rmp

EX2: rjmp EX2.terminara si.si dbg == 3rmp LDI, 0xB0cabo PORTA, rmp

ex3: rjmp ex3.terminara si.si dbg == 4rmp LDI, 0x70cabo PORTA, rmp

ex4: rjmp ex4.terminara si

; final de la prueba

rmp LDI, 0x08; set bits de puerto B 0..2 sean de entrada, 3 a la salida

cabo DDRB, rmprmp LDI, 0x07; establecidos pull-ups en insumos clave activascabo PORTB, rmp; controladores de pantalla de inicio, establecer todas las

pantallas a 0LDI YH, HIGH (SCS); punto en cuando información de inicioLDI YL, LOW (SCS)clr R0rmp LDI, 7; tiempo claro en SRAM

Start1:st Y +, R0diciembre rmpBrne Start1rcall UPDATETIME; configurar visualización de la horarcall UpDateAlarm; configurar la pantalla de alarmacabo PORTC, rmp; puertos de visualizacióncabo PORTD, rmpLDI rDCnt, 0x70; establecer última pantalla para conductorLDI YH, HIGH (sTime + 3); apuntar a mostrar inicioLDI YL, LOW (sTime + 3)clr rFlag; establecer indicadores a cerormp clr; desactivar el watchdogcabo WDTCR, rmp; ADC initrmp LDI, 1 << Adlar; Izquierda ajustar resultado, el canal 0,

VREF externacabo ADMUX, rmprmp clr; conjunto Srorcabo SFIOR, rmprmp LDI, (1 << ADEN) | (1 << ADSC) | (1 << ADIE) | (1 << ADPS2)

| (1 << ADPS1) | (1 << ADPS0); permitir a ADCcabo ADCSRA, rmp; rmp LDI, 1; dimm conjunto comprobando en primer ciclo ADCmov rFChk, rmp; temporizador init 0rDurL clr; establecer la duración de cero para bloquear

temporizadorclr rDurHrmp LDI, 175; conjunto de valores comparar a 175 (880 cs / s)cabo OCR0, rmpLDI rmp, (1 << WGM01) | (1 << COM00); dejar de temporizador de

la alarmacabo TCCR0, rmp; modo de ajuste y COM; temporizador init 1 como reloj y conductor dígitos

divisor .equ = (5 * reloj + 500) / 1000; 5 ms Tiempo intLDI rmp, HIGH (divisor); establecer comparar coincidir ICR1cabo ICR1H, rmpLDI rmp, LOW (divisor)cabo ICR1L, rmpLDI rmp, HIGH (divisor / 2); establecer comparar partido A como

5-ms-intcabo OCR1AH, rmpLDI rmp, LOW (divisor / 2)cabo OCR1AL, rmpLDI rmp, HIGH (divisor - 2); set comparar partido B como tenue

intcabo OCR1BH, rmpLDI rmp, LOW (divisor - 2)cabo OCR1BL, rmp

rmp clr; claro WGM11 y WGM10cabo TCCR1A, rmprmp LDI, (1 << WGM13) | (1 << WGM12) | (1 << CS10); ICR-CTC,

div = 1cabo TCCR1B, rmp; permitir que las interrupciones del temporizadorrmp LDI, (1 << OCIE1A) | (1 << OCIE1B) | (1 << TICIE1) | (1 <<

OCIE0); ICR1-, COMP1-, TC0 int permitecabo TIMSK, rmp; modo de suspensión conjuntoLDI rmp, 1 << SE; conjunto del sueño habilitar y modo de

suspensión 0cabo MCUCR, rmp; permitir que las interrupcionessei

; ================================================== =; M ainprogramloop; ================================================== =Lazo:

dormir; Ir a dormirnop; maniquí después de despertar

;llaves rcall; comprobar claves después de cada activación

; Verifique las banderas que se han establecidoSBRC rFlag, BSEC; saltar sobre si segunda bandera no establecercall SegundoSBRC rFlag, BADC; saltar sobre si hay nuevos resultados de

conversión ADCrcall AdcNewrjmp Loop

;; ================================================== =; C heckkeys; ================================================== =;.equ cKeyRed = 0x06.equ cKeyBlack = 0x05.equ cKeyWhite = 0x03llaves:

andi rkey, 0x07; aislar llavesrmp lds, sKey; leer el valor clave almacenadarmp cp, rkey; comparar el valor llavekey1 BREQ; clave EQAL; clave diferente de la última llave, almacenar nueva, contador

clarapts sKey, rkey; del almacén de clavesrmp LDI, 0; recuento claropts sKeyC, rmpenriar

key1:; clave es igual última teclarmp lds, sKeyC; leer recuento de clavesrmp inc; aumentar el número de clavepts sKeyC, rmp; tiendarmp cpi, 3; tres códigos claves idénticaskey2 BREQ; idénticoBRCS key1aLDI rmp, 5pts sKeyC, rmp

key1a:enriar

key2:; llave válida

rmp lds, sKey; leer código de la llavermp cpi, 0x07; clave unpressed?key3 BREQ; sípts sKeyS, rmp; almacén de claves seleccionadoenriar

key3:rmp lds, sKeyS; leer la clave seleccionadaLDI ZL, 0pts sKeyS, ZLtst rmpkey4 Brneenriar

key4:; saltos condicionales de acuerdo con banderasSBRC rFlag, bAlarm; Actualmente alarma?rjmp keyAlarm; reaccionar a la tecla durante la alarmaSBRC rFlag, bArmed; armado actualmente?rjmp keyArmed; reaccionar ante clave durante armadoSBRC rFlag, bSetC; Actualmente el ajuste del reloj?rjmp keySetC; reaccionar ante clave durante el ajuste del relojSBRC rFlag, bSetA; Actualmente se encuentra en el

establecimiento de hora de la alarma?rjmp keySetA; reaccionar a la tecla durante el ajuste de hora

de la alarma; modo normal, tratar como nueva clavermp cpi, cKeyRed; tecla roja?key5 Brne; nosbr rFlag, 1 << bSetC; bandera de conjuntoenriar

key5:rmp cpi, cKeyWhite; tecla blanca?key6 Brne; nosbr rFlag, 1 << bSetA; bandera de conjuntoenriar

key6:rmp cpi, cKeyBlack; llave de color negro?key7 BrneLDI rmp, 1 << bArmed; bandera armada de palancaeo rFlag, rmpenriar

key7:enriar

keySetC:; teclas durante conjunto Crmp cpi, cKeyBlack; llave negro presionado = saltarBrne keySetC1cbr rFlag, (1 << bSetC) | (1 << bSetCM); banderas clarasrjmp UPDATETIME

keySetC1:rmp cpi, cKeyRed; tecla roja presionaBrne keySetC3; no; tecla roja presionaSBR rFlag, bSetCm; fijar los minutos del reloj?rjmp keySetC2; no hay, hora establecidos; minutos setrmp clr; segundo claraspts SCS, RMPrmp lds, sAdcPLDI ZL, 60rmp mul, ZLpts SMC, R1cbr rFlag, (1 << bSetC) | (1 << bSetCm); banderas clarasrjmp UPDATETIME

keySetC2:; horario fijormp lds, sAdcPLDI ZL, 24rmp mul, ZLpts SCH, R1rmp clr; segundo claraspts SCS, RMPsbr rFlag, (1 << bSetC) | (1 << bSetCm); pabellón conjunto

minutosenriar

keySetC3:; clave ilegalenriar

keySetA:; teclas durante conjunto Armp cpi, cKeyBlack; llave negro presionado = saltarkeySetA1 Brne; nocbr rFlag, (1 << bSetA) | (1 << bSetAm); banderas clarasrjmp UpDateAlarm

keySetA1:rmp cpi, cKeyWhite; tecla blanca presionado?keySetA3 Brne; no; tecla blanca pulsaSBR rFlag, bSetAm; establecer minutos de la alarma?rjmp keySetA2; no hay, hora establecidos; minutos setrmp lds, sAdcP; leer el valor ollaLDI ZL, 60mul ZL, rmpsts sAm, R1; conjunto hora de la alarmasts SSM, R1; set Set hora de la alarmacbr rFlag, (1 << bSetA) | (1 << bSetAm); banderas de alarma

conjunto clarassbr rFlag, 1 << bArmed; set bandera armadarjmp UpDateAlarm

keySetA2:; horario fijormp lds, sAdcPLDI ZL, 24mul ZL, rmpsts Sah, R1; conjunto hora de la alarmapts SSH, R1; set Set hora de la alarmasbr rFlag, 1 << bSetAm; minutos set banderaenriar

keySetA3:enriar

keyAlarm:; clave durante la alarmarmp cpi, cKeyRed; tecla roja presionado?Brne keyAlarm1; tecla roja durante la alarma: función de repetición

keyAlarmSnooze:rmp lds, Sam; leer minutos de la alarmarmp subi, -cSnooze; añadir tiempo de pausapts sAm, rmp; y almacenarrmp cpi, 60; superior o igual 60 minutos?BRCS keyAlarmOff; no, ir enrmp subi, 60; restar 60 minutospts sAm, rmp; y almacenarrmp lds, Sah; leer horasrmp inc; siguiente horapts Sah, rmp; y almacenarrmp cpi, 24; mayor o igual 24BRCS keyAlarmOff; no, ir enrmp clr; hora de reinicio

pts Sah, rmp; y almacenarkeyAlarmOff:

cbr rFlag, 1 << bAlarm; bandera de alarma claraLDI rmp, (1 << WGM01) | (1 << COM00); dejar de temporizador de

la alarmacabo TCCR0, rmp; modo de ajuste y COMcbi PORTB, 3; claro poco puerto OC0rjmp UpDateAlarm;

keyAlarm1:rmp cpi, cKeyBlack; llave negro presionado?Brne keyAlarm2; no; clave de negro durante la alarma: alarma establecido y

armados fuerarmp lds, SSM; leer minutos de la alarma de ajustepts sAm, rmp; escribir en minutos de la alarmarmp lds, SSH; leer minutos de la alarmapts Sah, rmp; escribir en minutos de la alarmacbr rFlag, 1 << bArmed; clara bandera armadarjmp keyAlarmOff

keyAlarm2:; cualquier otra tecla: no hacer nadaenriar

keyArmed:; clave durante armadarmp cpi, cKeyBlack; llave negro presionadoBrne keyArmed1; no presionado; clave de negro durante la armadacbr rFlag, 1 << bArmed; conjunto armado fuerarmp lds, SSM; leer minutos de la alarma de ajustepts sAm, rmp; escribir en minutos de la alarmarmp lds, SSH; leer minutos de la alarmapts Sah, rmp; escribir en minutos de la alarmarjmp UpDateAlarm

keyArmed1:rmp cpi, cKeyRed; tecla roja durante armadaBrne keyArmed2; no presionado; tecla roja durante el armado: incremento hora de la alarmarjmp keyAlarmSnooze; aumentar el tiempo de alarma

keyArmed2:; cualquier otra tecla: ignoreenriar

;; ================================================== =; Un secondisover; ================================================== =;En segundo lugar:

cbr rFlag, 1 << BSEC; claro segunda banderarmp lds, SCS; leer segundosrmp inc; segundo siguientepts SCS, rmp; tiendas segundos.si dbg == 5rcall dispsec.terminara sirmp cpi, 60; siguiente minuto?BRCS segundo1; no aún normp clr; segundo claraspts SCS, rmp; tienda de cerormp lds, SMC; leer minutormp inc; minuto siguientepts SMC, rmp; minutos de tiendasrmp cpi, 60; siguiente hora?

Brne UPDATETIMErmp clr; minutos claraspts SMC, rmp; minutos de tiendasrmp lds, SCH; leer horasrmp inc; siguiente horapts SCH, rmp; horario de la tiendarmp cpi, 24; día siguiente?Brne UPDATETIMErmp clr; hora claraspts SCH, RMPrjmp UPDATETIME

Segundo1:; puntos de tiempo de parpadeoSBRC rFlag, bSetCrjmp Second4rmp ror; bit más bajo para llevarrmp lds, sTime; carga representada primer dígitoBRCS segundo2; bajo bit = 1rmp sbr, 1 << 7; claro llevadorjmp segundo3

Segundo2:rmp cbr, 1 << 7; conjunto dirigido

Segundo3:pts sTime, rmp; que aparece primero dígitos; puntos de alarma de parpadeo

Second4:SBR rFlag, bArmed; si no regreso armadoenriarrmp lsl; bit 7 para llevarrmp lds, SALARM; leer posición de alarmaBRCS Second5rmp andi, 0x7F; poco clara 7rjmp Second6

Second5:rmp sbr, 1 << 7; poco juego 7

Second6:pts SALARM, rmp; tienda byte de alarmaenriar

dispsec:rmp lds, SCSLDI XH, alta (SALARM + 2)LDI XL, Low (SALARM + 2)rcall To7Segrmp lds, SCSenriar

; ================================================== =; U pdatedisplay; ================================================== =;; Actualización mostrada hora de la alarma;UpDateAlarm:

LDI XH, alta (SALARM)LDI XL, Low (SALARM)rmp lds, Sahrcall To7Segrmp lds, Samrjmp To7Seg

;; Actualiza la hora que se muestra;UPDATETIME:

SBRC rFlag, bArmed; si armado, comparar hora de la alarmarcall CheckAlarm; comprobar el tiempo de alarmaSBRC rFlag, bSetC; si de ajuste del reloj activo, omitirenriarLDI XH, alta (sTime); punto en cuandoLDI XL, LOW (sTime)rmp lds, SCH; leer horasrcall To7Segrmp lds, SMC; leer minuto

To7Seg:clr R0; R0 es contraproducente

To7Seg1:subi rmp, 10BRCS To7Seg2inc R0rjmp To7Seg1

To7Seg2:subi rmp, -10LDI ZH, ALTA (2 * Tab7Seg); cuadro de cargasLDI ZL, LOW (2 * Tab7Seg)añadir ZL, R0BRCC To7Seg3inc ZH

To7Seg3:lpmst X +, R0LDI ZH, ALTA (2 * Tab7Seg); cuadro de cargasLDI ZL, LOW (2 * Tab7Seg)añadir ZL, rmpBRCC To7Seg4inc ZH

To7Seg4:lpmst X +, R0enriar

; Tabla de conversión decimal a 7 segmentosTab7Seg:.db 0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10; valores hexadecimales.db 0x08,0x03,0x27,0x21,0x06,0x0E;; ================================================== =; C heckalarmtimereached; ================================================== =;CheckAlarm:

lds R0, SCH; leer horas relojrmp lds, Sah; leer hora de alarmacp R0, rmp; iguales?Brne CheckAlarmRetlds R0, SMC; leer minutos de relojrmp lds, Sam; leer minutos de la alarmacp R0, rmp; iguales?Brne CheckAlarmRetsbr rFlag, 1 << bAlarm; conjunto del indicador de alarmaSer Reep; frente hasta el final de EEPROMLDI rDurL, 1; comenzar en la nueva dirección en el ciclo intclr rDurHrmp LDI, (1 << WGM01) | (1 << COM01) | (1 << CS01); iniciar

temporizador de la alarmacabo TCCR0, rmp; modo de ajuste y COM y preescala = 8

CheckAlarmRet:enriar

;; ================================================== =; N ew Un dcresultprovided; ================================================== =;AdcNew:

cbr rFlag, 1 << BADC; clara bandera ADC.si dbg == 6rcall dispadc.terminara sidiciembre rFChk; cheque tenue ajustar?Brne AdcNew2; no ajustermp LDI, 0x10; establecido countermov rFChk, rmprmp lds, sAdcF; leer el valor fototransistorrmp cpi, 0xFF; oscuridad?BRCS AdcNew1; noLDI rmp, HIGH (divisor / 2); establecer un medio tiempocabo OCR1BH, rmpLDI rmp, LOW (divisor / 2)cabo OCR1BL, rmprjmp AdcNew2

AdcNew1:rmp LDI, HIGH (divisor-30); establecer a tiempo completocabo OCR1BH, rmprmp LDI, LOW (divisor-30)cabo OCR1BL, rmp

AdcNew2:rmp lds, sAdcP; leer el valor ollaSBR rFlag, bSetC; Ajuste de C?rjmp AdcNew4; N ° C; establecer CSBR rFlag, bSetCm; minutos de ajuste?rjmp AdcNew3; visualización minutos de ajuste ollaLDI XH, alta (sTime + 2); puntero del conjuntoLDI XL, Low (sTime + 2)LDI ZL, 60; 60 minutosrjmp Mult; multiplique y visualización

AdcNew3:; horas de visualización de ajusteLDI XH, alta (sTime); puntero del conjuntoLDI XL, Low (sTime)LDI ZL, 24; multiplicar por 24rjmp Mult; multiplicar y mostrar

AdcNew4:SBR rFlag, bSetA; Un entorno?ret; noSBR rFlag, bSetAm; ¿minutos?rjmp AdcNew5; noLDI XH, alta (SALARM + 2); puntero del conjuntoLDI XL, Low (SALARM + 2)LDI ZL, 60rjmp Mult; multiplicar y mostrar

AdcNew5:LDI XH, alta (SALARM); puntero del conjuntoLDI XL, Low (SALARM)LDI ZL, 24rjmp Mult

;

; Multiplicar y mostrar;Mult:

mul ZL, rmprmp mov, R1rjmp To7Seg

;; ================================================== =; Ebug D: D isplayadcresult; ================================================== =;dispadc:

LDI XH, HIGH (SALARM)LDI XL, LOW (SALARM)rmp lds, sAdcPrcall dispadc1lds rmp, sAdcF

dispadc1:empuje rmprmp de intercambiorcall dispadc2rmp pop

dispadc2:rmp andi, 0x0FLDI ZH, ALTA (2 * Tab7Seg)LDI ZL, LOW (2 * Tab7Seg)añadir ZL, rmpBRCC dispadc3inc ZH

dispadc3:lpmst X +, R0enriar

;; ================================================== =; C opyrightinformation; ================================================== =;.db "C (2) 10 0ybh tt: p // ww.wva-rsa-mutotirlan.te";; ================================================== =; M elodyin EEPROM; ================================================== =;.eseg.org $ 0.000;.equ cPa = 10; duración de la pausa.equ Cd = 9,216; tono de duración constante;; Tabla de frecuencia.equ cf2e = 659.equ cf2f = 698.equ cf2g = 784.equ cf2a = 880.equ CF2H = 988.equ cf3c = 1047.equ CF3D = 1175.equ cf3e = 1319.equ cf3f = 1397.equ cf3g = 1568

.equ cf3a = 1760

.equ cf3h = 1976

.equ cf4c = 2093

.equ cf4d = 2349

.equ cf4e = 2637

.equ cf4f = 2794

.equ cf4g = 3136

.equ cf4a = 3520

.equ cf4h = 3951

.equ cf5c = 4186; Mesa de CTC para estas frecuencias.equ cc2e = reloj / 16 / cf2e.equ cc2f = reloj / 16 / cf2f.equ cc2g = reloj / 16 / cf2g.equ cc2a = reloj / 16 / cf2a.equ cc2h = reloj / 16 / CF2H.equ cc3c = reloj / 16 / cf3c.equ CC3D = reloj / 16 / CF3D.equ cc3e = reloj / 16 / cf3e.equ cc3f = reloj / 16 / cf3f.equ cc3g = reloj / 16 / cf3g.equ cc3a = reloj / 16 / cf3a.equ cc3h = reloj / 16 / cf3h.equ cc4c = reloj / 16 / cf4c.equ cc4d = reloj / 16 / cf4d.equ cc4e = reloj / 16 / cf4e.equ cc4f = reloj / 16 / cf4f.equ cc4g = reloj / 16 / cf4g.equ cc4a = reloj / 16 / cf4a.equ cc4h = reloj / 16 / cf4h.equ cc5c = reloj / 16 / cf5c; constantes duración tono.equ cd2e = cd / cc2e.equ cd2f = cd / cc2f.equ cd2g = cd / cc2g.equ CD2a = cd / cc2a.equ cd2h = cd / cc2h.equ cd3c = cd / cc3c.equ cd3d = cd / CC3D.equ CD3e = cd / cc3e.equ cd3f = cd / cc3f.equ cd3g = cd / cc3g.equ cd3a = cd / cc3a.equ cd3h = cd / cc3h.equ cd4c = cd / cc4c.equ cd4d = cd / cc4d.equ CD4E = cd / cc4e.equ cd4f = cd / cc4f.equ cd4g = cd / cc4g.equ cd4a = cd / cc4a.equ cd4h = cd / cc4h.equ cd5c = cd / cc5c; melodía; 3a 4g 4g 4f; 4e 4d 4d; 4c 4c 3h 4f; 4f 4g-4f; mesacc3g .db, cd3g, cc3g, cd3g, cc3f, cd3f, cc2a, CD2a.db cc3e, CD3e, CC3D, cd3d, CC3D, cd3dcc3c .db, cd3c, cc2h, cd2h, cc3c, cd3c, cc3f, cd3f

.db cc3f, cd3f, cc3g, cd3g, cc3f, cd3f; final de la tabla.db 0,0;; Fin del código fuente;