;--------------------------------------------------------------------------------
; Programa: Contador 0-99 por interrupción
; Version: 0.0
;
; Dispositivo: ATmega8 Compilador: AVRASM2
; Entorno IDE: AVR Studio4.15 Simulador: Proteus 7.5sp3
;
; Notas: Este programa realiza un conteo ascendente de 0 a 99 mediante
; 2 Displays de 7 segmentos, y un pulsador que incrementa la cuenta
;
; Registros: r16 para configuraciones, y despues con r15 manipula los datos de
; unidades y decenas. r30 y r31 (Z) para direccionamiento indirecto
; de las constantes en memoria de programa que se almacenan de los
; datos del display de 7 segmentos. r28 y r29 (Y), para copia de la
; dirección original de las constantes. r17 y r18 son usadas para
; los retardos de 25ms y 1ms
;
; Conexiones: C0 -> Anodo Display 1
; C1 -> Anodo Display 2
; D0 -> Segmento a del Display
; D1 -> Segmento b del Display
; D2 -> Pulsador
; D3 -> Segmento c del Display
; D4 -> Segmento d del Display
; D5 -> Segmento e del Display
; D6 -> Segmento f del Display
; D7 -> Segmento g del Display
;--------------------------------------------------------------------------------
;DIRECTIVAS EN ENSAMBLADOR
.include "m8def.inc" ;ATmega8
.equ unidades=$60
.equ decenas=$61
.def flag=r19
;reset-vector address $0000
.org $0000
rjmp main ;ve al main
rjmp int_ext ;va a la interrupción externa
seg7:.db 0x80,0xf1,0x48,0x60,0x31,0x22,0x02,0xb0,0x00,0x20
int_ext:
ser flag ;ponemos flag a 255
reti ;retorno de rutina de interrupción, habilitando I del SREG
;PROGRAMA PRINCIPAL
main:
ldi r16,$04 ;Configuracion de...
out sph,r16
ldi r16,$5F
out spl,r16 ;...la pila: Stack: $045F=RAMEND
ser r16 ;r16 <- $FF
out ddrc,r16 ;portC salida
ldi r16,$fb ;r16 <- $fb
out ddrd,r16 ;portD salidas, excepto D2
ldi r16,3 ;r16 <- 3
out mcucr,r16 ;configuramos a modo sleep idle, y flanco de subida para INT0
ldi r16,$40 ;r16 <- $40
out gicr,r16 ;activamos la máscara de la INT0
clr r16 ;r16 <- 0
out gifr,r16 ;limpiarmos flags de interrupcion INTF0 e INTF1
sts unidades,r16 ;unidades <- 0
sts decenas,r16 ;decenas <- 0
clr flag ;bandera para identificar interrupción pueta a 0
sei ;se habilitan las interrupciones globales
ldi r30,low(seg7) ;se carga en Z
ldi r31,high(seg7) ;la dirección en flash de los datos del display
ldi r16,2 ;r16 <- 2
add r30,r16 ;adecuamos el puntero Z para qeu apunte a bytes
loop:
cpi flag,255 ;preguntamos si flag es 255
breq incremento ;si es 255, la interrupción ocurrió, saltamos a incrementar unidades
multi:
rcall multiplexar ;vamos a visualizar los datos en los displays
rjmp loop ;bucle infinito
incremento:
;rcall delay25m ;retardo antirrebote
rcall multiplexar ;mostramos datos, hasta que se suelte el pulsador
sbic pind,2 ;pin D2 esta todavía siendo pulsado?
rjmp incremento ;si, está pulsado, volvemos a generar retardo, sino se salta instrucción
lds r16,unidades ;r16 <- unidades
lds r17,decenas ;r17 <- decenas
inc r16 ;incrementamos el valor de r16 que contiene el valor de unidades
cpi r16,10 ;r16<10?
brmi salir ;si es menor, salimos, sino...
clr r16 ;r16 <- 0, unidades a cero
inc r17 ;incrementamos r17 que contiene el valor de decenas
cpi r17,10 ;r17<10?
brmi salir ;si es menor, salimos, sino...
clr r17 ;r17 <- 0,decenas a cero
salir:
sts unidades,r16 ;unidades <- r16
sts decenas,r17 ;decenas <- r17
clr flag ;ponemos flag a 0
rjmp multi ;volvemos a multiplexar, con los nuevos datos
multiplexar:
sbi portc,0 ;apagamos ambos
sbi portc,1 ;displays
lds r16,unidades ;r16 <- unidades
lds r15,decenas ;r17 <- decenas
mov r28,r30 ;copiamos la dirección donde estan
mov r29,r31 ;los datos del display
add r30,r16 ;se suma el valor de unidades, para desplazarse en la tabla
lpm r16,Z ;r16 <- (Z)
mov r30,r28 ;r30 <- r28
add r30,r15 ;se suma el valor de decenas, para desplazarse en la tabla
lpm r15,Z ;r17 <- (Z)
mov r30,r28 ;r30 <- r28
out portd,r16 ;se muestra en el display de unidades, el valor correspondiente
cbi portc,1 ;enciende el display correspondiente
rcall delay1m ;tiempo de retardo para que sea visible al ojo
sbi portc,1 ;se apaga el display encendido anteriormente
nop nop nop nop nop nop nop nop ;apagando transistor, requiere un tiempo para apagarse
out portd,r15 ;se muestra en el display de decenas, el valor correspondiente
cbi portc,0 ;enciende el display correspondiente
rcall delay1m ;tiempo de retardo para que sea visible al ojo
sbi portc,0 ;se apaga el display encendido anteriormente
ret
; =============================
; delay loop generator
; 100000 cycles:
; -----------------------------
; delaying 99990 cycles:
delay25m:
ldi R17, $A5
WGLOOP0: ldi R18, $C9
WGLOOP1: dec R18
brne WGLOOP1
dec R17
brne WGLOOP0
; -----------------------------
; delaying 9 cycles:
ldi R17, $03
WGLOOP2: dec R17
brne WGLOOP2
; -----------------------------
; delaying 1 cycle:
nop
ret
; =============================
; =============================
; delay loop generator
; 4000 cycles:
; -----------------------------
; delaying 3999 cycles:
delay1m:
ldi R17, $1F
WGLOOP00: ldi R18, $2A
WGLOOP11: dec R18
brne WGLOOP11
dec R17
brne WGLOOP00
; -----------------------------
; delaying 1 cycle:
nop
ret
; =============================