;********************************************
;* WrittenBy GIROLAMO LAROSA *
;* for AVR AtMega8535 *
;* Clock Frequency: 7.3728Mhz *
;* *
;* Clock with AtMega8535 and 6 7seg display *
;* Crystal HC-49/U *
;* 6 decoder 7448 *
;* *
;********************************************
.device atmega8535
.nolist
.include "D:\Programmi\Atmel\AVR Tools\AvrAssembler\Appnotes\m8535def.inc"
.list
;============================
;Declaration
.def temp = r16
.def temp2= r17
.def displayCounter= r18
.def displayNumber = r19
.def Tens = r20
.def Ones = r21
.def secondi = r24
.def SSR = r25
.org 0x00
;===========================
;Interrupt Vector
rjmp Init ; Reset
rjmp EXT_INT0 ; External Interrupt, enabled with bush button ENTER
rjmp EXT_INT1 ; rjmp EXT_INT1
reti ; timer2 comp
reti ; timer2 ovf
reti ; timer1 capt
rjmp TIMER1COMPA ; timer/counter1 compare MachA enabled every 1s
reti
reti
reti
reti
reti
reti
reti
reti
reti
reti
reti
reti
reti
;===========================
;Start the program:
Init:
ldi temp,high(RAMEND) ; Set Stack Pointer to the top of the RAM
out SPH,temp ;
ldi temp,low(RAMEND) ;
out SPL,temp ;
sei
;Input/Output
ser temp
out DDRA,temp ;PA0-6 output (7-seg)
out DDRB,temp ;PC0-5 output(Select Display) PC0=display1,PC1=display2...PC5=display6
out DDRC,temp ;test Interrupt
clr temp
out PortA,temp ;No pullUp resistor
out PortB,temp
;Initial condition register
ldi tens,12
ldi ones,12
ldi displayCounter,100
clr displayNumber
clr ZH
;LookUp table
ldi temp,0b01111110 ;0
mov R0,temp
ldi temp,0b00110000 ;1
mov R1,temp
ldi temp,0b01101101 ;2
mov R2,temp
ldi temp,0b01111001 ;3
mov R3,temp
ldi temp,0b00110011 ;4
mov R4,temp
ldi temp,0b01011011 ;5
mov R5,temp
ldi temp,0b01011111 ;6
mov R6,temp
ldi temp,0b01110000 ;7
mov R7,temp
ldi temp,0b01111111 ;8
mov R8,temp
ldi temp,0b01111011 ;9
mov R9,temp
;External Interrupt ENABLE
ldi temp,0b00001010 ;Falling edge of INT0,INT1 generates an interrup(EX_INT0,EX_INT1)
out MCUCR,temp
ldi temp,0b11000000 ;External Interrupt 0,1 Enabel
out GICR,temp
; SETUP TCNT1 CTC mode with prescaler clk/64
ldi temp,0b00000000
out TCCR1A,temp
ldi temp,(0<<ICNC1)|(0<<ICES1)|(1<<WGM13)|(1<<WGM12)|(1<<CS10)|(1<<CS11);
out TCCR1B,temp
;Load in OCR1A top value for compare match
ldi temp,0x3D ;TOP VALUE FOR TCNT1(3D08 ex 0r 15624 dec)
out OCR1AH,temp
out ICR1H,temp
ldi temp,0x08
out OCR1AL,temp
out ICR1L,temp
; ENABLE COMPARE MATCH INTERRUPT AT 15624, clock frequency 1Mh Interrupt every 1s
ldi temp,(0<<OCIE2)|(0<<TOIE2)|(0<<TICIE1)|(1<<OCIE1A)|(0<<OCIE1B)|(0<<TOIE1)|(0<OCIE0);
out TIMSK,temp
ldi temp,(0<<TOV1)
out TIFR,temp
rjmp Start
; *********************************
; * *
; * START *
; * *
; *********************************
Display:
dec displayCounter ; cambia display ogni 100 colpi di clock circa
breq PC+2
rjmp display
ldi displayCounter,100
cpi DisplayNumber,2 ; se displayNumber Ë a 2 lo resetto
brne PC+2
clr DisplayNumber
ldi ZL,20; ; faccio puntare ZL a tens o a ones, registri che uso per far puntare alle decine o unit‡ del "secondo corrente"
add ZL,displayNumber;se Ë attivo il secondo display, allora mando su zl tens, se Ë attivo il primo mando ones su zl
ld temp,Z
clr ZL
add ZL,temp
out PortA,temp ; preparo la porta con il numero dalla lookUp table
inc displayNumber
in temp,PinB ;
lsl temp ;shift a sinistra per attivare di volta in volta il prossimo transistor
sbrs temp,1 ; visto che per ora ho solo 2 display passo dal primo al secondo e viceversa
ldi temp, 0b00000001;
out PortB,temp ;attivo il transistor relativo o a tens o a ones
ret
DigitConvert: ; ogni volta che scatta l'interrupt di compare match mi incremento il reg secondi che utilizzo di in questa subroutines
clr Tens ;per far puntare tens e ones ai reg corrispondenti della lookup table
clr Ones
FindTens:
subi secondi,10; mi controllo se i secondi sono > di 10
brcs FindOnes ;se non Ë cosÏ passo a findones
inc Tens ; se sono > di 10 incremento tens(secondo display
rjmp FindTens ; ritorno indietro per riverificare
FindOnes:
subi secondi,-10; ritorno i secondi al valore di origine
mov ones,secondi, faccio puntare ones al reg della look up table relativa a secondi
ret
Start:
rcall digitConvert ; richiamo la subroutine di conversione
rcall display ;richiamo la subroutines di visualizzazione
rjmp Start ;loop a start
;===============================================
;* SUBROUTINES *
;===============================================
;1s Passed
TIMER1COMPA: ; interrupt di compare match che scatta ogni secondo viste le impostazioni del timercounter1
push SSR
in SSR,Sreg ;save SREG
push temp
inc secondi
cpi secondi,60 ; qui mi occupo solamente di incrementare il reg secondi e di controllare se sono arrivato a 60
brne PC+2
clr secondi ; se sono a 60, reset il reg
pop SSR
out SREG,SSR
pop SSR
ret
; queste due subroutines sono in previsione di un futuro implemento di 2 tasti per il settaggio dell'orologgio
EXT_INT0:
reti
; External Interrupt, enabled with bush button ENTER
EXT_INT1:
reti
deluca wrote:@girolamo, al fine di facilitare il test,
posta uno zip contenente il progetto proteus e il codice hex così provo a simularlo sul mio pc.
Return to Microcontrollori e microprocessori
Users browsing this forum: No registered users and 14 guests