You are on page 1of 6

;This program counts up from 0 to 99 and then rolls over to zero.

;The numbers are displayed on the seven segments.


;Connect the 7-segment module to the upper pins of JA and JB.
;The code is in AVR assembly. Use AVR Studio IDE to make the hex file.
;For more information see www.microdigitaled.com and
www.digilentinc.com
.INCLUDE "M64DEF.INC"

;ATmega64 is used by Cerebot2 board

;initialize SP (Stack Pointer)


LDI
R20, HIGH(RAMEND)
OUT
SPH, R20
LDI
R20, LOW(RAMEND)
OUT
SPL, R20
;JA (PORTA) and JB(PORTC) as outputs
LDI
R20, 0xFF
OUT
DDRA, R20
OUT
DDRC, R20
L1:
L2:
L3:
L4:
===
===

LDI
LDI
LDI

R22, 0 ;R22 = 0
(The left digit)
R21, 0 ;R21 = 0
(The right digit)
R18,50 ;scan the 7-segments 50 times and then count up

;==============================================================
;Right 7-segment
;==============================================================

LDI
ZH, HIGH(SEVEN_SEG_LOOKUP<<1)
LDI
ZL, LOW(SEVEN_SEG_LOOKUP<<1)
;Z points to
SEVEN_SEG_LOOKUP
ADD
ZL, R21
LPM
R20,Z
;R20 = SEVEN_SEG_LOOKUP[R21]
;put the high nibble of R20 on JB (PORTC)
MOV
R16, R20
;R16 = R20
ANDI R16, 0x70
SWAP R16
OUT
PORTC, R16
;put the low nibble of R20 on JA (PORTA)
MOV
R16, R20
;R16 = R20
ANDI R16, 0x0F ;R16 = R16 & 0x0F
OUT
PORTA, R16
;PORTA = R16
CALL

DELAY_10ms

;wait for a while

;R20 = 0x3F (to display '0' on 7-segment we should put 0x07 on


the port)
LDI
R20, 0x3F
===

;==============================================================
;Left 7-segment
;==============================================================

===

LDI

ZH, HIGH(SEVEN_SEG_LOOKUP<<1)

LDI
ZL, LOW(SEVEN_SEG_LOOKUP<<1)
;Z points to
SEVEN_SEG_LOOKUP
ADD
ZL, R22
LPM
R20,Z
;R20 = SEVEN_SEG_LOOKUP[R22]
;put the high nibble of R20 on JB (PORTC)
MOV
R16, R20
;R16 = R20
ANDI R16, 0x70
ORI
R16, 0x80
;enable the catode for the Left 7segment

SWAP R16
OUT
PORTC, R16
;put the low nibble of R20 on JA (PORTA)
MOV
R16, R20
ANDI R16, 0x0F
OUT
PORTA, R16

L3

CALL

DELAY_10ms

;wait for a while

DEC
BRNE
INC
CPI
BRNE

R18
L4
R21
;increase the right digit
R21,10
L3
;If the right digit is less than 10 then go to

LDI
INC

R21,0
R22

CPI
BRNE
RJMP

R22,10 ;If the left digit is less than 10


L2
;then go to L2.
L1
;otherwise, goto L1 and start from beginning

;otherwise, load R21 with 0 and


;increase the left digit.

;
======================================================================
=
;The Delay subroutine creates a delay which is 10 ms for XTAL = 8MHz.
;
======================================================================
=
DELAY_10ms:
PUSH R21
PUSH R22
LDI
R21, 64
;R21 = 64
DL1:LDI R22, 250
;R22 = 250
DL2:NOP

DL2

DL1

.ORG

NOP
DEC R22
BRNE
DL2

;R22 = R22 - 1
;if R22 is not equal to zero then go to

DEC R21
BRNE
DL1

;R21 = R21 - 1
;if R21 is not equal to zero then go to

POP
POP
RET
$100

R22
R21

;To display 0 on 7-segment we should put 0x3F on it, to display 1 we


should put 0x06, and so on.
;The lookup array contains the number that we should put on 7-segment,
when we want to display each number.
;
'0'
'1'
'2'
'3'
'4'
'5'
'6'
'7'
'8'
'9'
SEVEN_SEG_LOOKUP:
.DB
0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F,
0x6F

http://www.microdigitaled.com/AVR/Hardware/Digilent_asm/6_sevenSeg2.as
m

/*
* display.asm
*
* Created: 13/09/2015 15:13:51
* Author: Rodry
*/
;-------------------------------------------------------------------------------;
Programa:
Contador 0-99 por interrupcin
;
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
;
direccin 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 interrupcin externa
seg7:.db 0x80,0xf1,0x48,0x60,0x31,0x22,0x02,0xb0,0x00,0x20
int_ext:
ser flag
reti
SREG
;PROGRAMA PRINCIPAL
main:

;ponemos flag a 255


;retorno de rutina de interrupcin, habilitando I del

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 mscara 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 interrupcin pueta a 0
sei
;se habilitan las interrupciones globales
ldi r30,low(seg7)
;se carga en Z
ldi r31,high(seg7)
;la direccin 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 interrupcin 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 todava siendo pulsado?
rjmp incremento
;si, est pulsado, volvemos a generar retardo, sino
se salta instruccin
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
sbi portc,1
lds r16,unidades
lds r15,decenas
mov r28,r30
mov r29,r31
add r30,r16
la tabla

;apagamos ambos
;displays
;r16 <- unidades
;r17 <- decenas
;copiamos la direccin donde estan
;los datos del display
;se suma el valor de unidades, para desplazarse en

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
; =============================

You might also like