⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lab2.asm

📁 Source code in assembler for using interupts with atmega16 and creating an easy cronometer.
💻 ASM
字号:
.include "C:\Program Files\Labcenter Electronics\Proteus 6 Professional\Tools\AVRASM\APPNOTES\m16def.inc"

.equ TIME_LIMIT = 15625                    ; pana unde tre' sa numere contoru pe 16 biti.

.dseg

digit_table:        .BYTE        10       ; tabela de cifre
digit:              .BYTE        1        ; cifra curenta

.cseg

;tabela de intreruperi
.org 0
    jmp main                              ; reset interrupt

.org $0C
    jmp cmp_handler                       ; TMR0/A compare int

.org $2A

main:                        
    ldi r16, HIGH(RAMEND)                 ; initializeaza stiva
    out SPH, r16
    ldi r16, LOW(RAMEND)
    out SPL, r16

    call init_portb                       ; initializeaza portul B
    call init_alimentare_display_LED      ; initializeaza portul D
    call build_table                      ; construieste tabela pentru cifre
    call init_digit                       ; seteaza valoarea initiala pentru digit (0) + afiseaza
    call init_timer1                      ; initializeaza timer1 (bate secunda)

    sei                                   ; da drumu la intreruperi
loop:
    jmp loop



; initializeaza portul B: trebuie setat pe output. fiecare pin trebuie lasat in 1 logic
; pentru ca 7-segment sa nu afiseze nimic
init_portb:
    ; TODO #1
	ldi r16, 0b11111111
	out DDRB, r16
	out PORTB, r16
    ret

    

init_alimentare_display_LED:
    push r16
    ldi r16, 0
    out DDRD, r16
    out PORTD, r16
    sbi DDRD, 7   ; pin 7 = alimentare display
    pop r16
    ret


; initializeaza variabila digit la 0 si apeleaza functia de afisare

init_digit:
    ; TODO #2
	ldi r16, 0
	sts digit,r16 
	call print_digit
    ret



    
; initializeaza timer 1 pentru a produce o intrerupere la exact o secunda, folosind TIME_LIMIT
; pentru un factor de prescale de 1024, mod clear timer on compare    ).

init_timer1:
    ; TODO #3

	; TCCR
	ldi r16, 0
	out TCCR1A, r16
	ldi r16, (1<<WGM12)|(1<<CS12)|(1<<CS10)
	out TCCR1B, r16

	; OCR
	ldi r16, HIGH(TIME_LIMIT)
	out OCR1AH, r16
	ldi r16, LOW(TIME_LIMIT)
	out OCR1AL, r16 

	;TIMSK
	ldi r16,(1<<OCIE1A)
	out TIMSK,r16 

    ret

    


; handler pentru intreruperea de compare a timer1. trebuie sa schimbe valoarea din variabila
; digit si sa apeleze functia de afisare

cmp_handler:
    ; TODO #4

	push r17
  	push  r16                  ; salvam un registru in stiva 
  	in r16, SREG               ; citim valoarea din  SREG in registrul general r16 
  	push r16                   ; punem pe stiva valoarea 

	lds r16, digit
	inc r16
	
	ldi r17,10
	cp r16,r17 ;am ajuns la 10 ?
	
	brne dupa_reset ; daca nu e 10, sar peste reset

	ldi r16,0

dupa_reset:

	sts digit,r16
	call print_digit

	; -- refacerea continutului initial al registrelor
  	pop r16                    ; scoate din stiva r16 
  	out SREG, r16              ; reface SREG 
  	pop r16
	pop r17    

    reti; 
    
    
    
; afiseaza pe 7-segment cifra continuta in variabila digit. citeste digit_table[digit]
; si trimite valoarea in portul B
print_digit:                    
    push r16
    push XL
    push XH
    
    ldi XL, LOW(digit_table)
    ldi XH, HIGH(digit_table)
    lds r16, digit
    add XL, r16
    ldi r16, 0
    adc XH, r16

    ld r16, X
    out PORTB, r16

    pop XH
    pop XL
    pop r16
    ret

; construieste tabela digit_table. este un vector cu 10 pozitii. digit_table[i] reprezenta
; valoare care trebuie scrisa in portul B, pentru ca pe 7-segment sa apara cifra i

build_table:                    
    push r16
    push XL
    push XH    
    
    ldi XL, LOW(digit_table)
    ldi XH, HIGH(digit_table)

    ldi r16, 0b00000001            ; 0
    st X+,r16
    ldi r16, 0b11001111            ; 1
    st X+,r16
    ldi r16, 0b00010010            ; 2
    st X+,r16
    ldi r16, 0b00000110            ; 3
    st X+,r16
    ldi r16, 0b01001100            ; 4
    st X+,r16
    ldi r16, 0b00100100            ; 5
    st X+,r16
    ldi r16, 0b00100000            ; 6
    st X+,r16
    ldi r16, 0b00001111            ; 7
    st X+,r16
    ldi r16, 0b00000000            ; 8
    st X+,r16
    ldi r16, 0b00000100            ; 9
    st X,r16

    pop XH
    pop XL
    pop r16
    ret

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -