Generació de la Sèrie de Fibonacci en Assembler AVR amb Subrutines
Enviado por Programa Chuletas y clasificado en Informática y Telecomunicaciones
Escrito el en
catalán con un tamaño de 3,95 KB
Implementació de la Sèrie de Fibonacci en Assembler AVR
Aquest codi implementa un generador de la sèrie de Fibonacci utilitzant subrutines en llenguatge Assembler per a microcontroladors AVR. La sèrie es calcula i s'emmagatzema a la memòria SRAM, mentre que el nombre d'elements desitjats s'introdueix mitjançant un port d'entrada.
Definició de Variables i Registres
Es defineixen els registres utilitzats per emmagatzemar els elements de la sèrie, el comptador d'elements i els paràmetres de retard.
.EQU TAULA_FIB = 0X200 ; Inici de la taula de la sèrie en SRAM
.DEF FIB_1 = R16 ; Primer element de la sèrie de Fibonacci
.DEF FIB_2 = R17 ; Segon element de la sèrie de Fibonacci
.DEF FIB_3 = R18 ; Tercer element de la sèrie de Fibonacci
.DEF N_ELEMENTS = R19 ; R19 marcarà quants números de Fibonacci volem que ens generi
.DEF CMPT_ELS = R20 ; Comptador d'elements generats (Registre 20)
.DEF E_ACTUAL = R21
.DEF CMPT_1 = R22
.DEF CMPT_2 = R23
Configuració dels Ports d'E/S
Es configura el Port D com a sortida per mostrar els resultats i el Port B com a entrada per llegir el nombre d'elements a generar.
Ports_definition:
LDI R24, 0b11111111 ; Ports D seran tots de sortida
OUT DDRD, R24
LDI R25, 0b00000000 ; Ports B seran tots d'entrada
OUT DDRB, R25
IN N_ELEMENTS, PINB ; N_ELEMENTS valdrà el que valgui PINB. El valor de PINB l'entrem manualment a la finestra I/O
; NOP ; No s'aplica perquè hi ha instruccions immediatament després de IN que no llegeixen el valor entrat.
Inici del Programa (Start)
S'inicialitza el punter de memòria (registres X) i es carreguen els dos primers elements de la sèrie (1 i 1).
Start:
LDI XL, LOW(TAULA_FIB) ; Inicialitza punter taula (punter = indicador del registre amb el que treballarem)
LDI XH, HIGH(TAULA_FIB)
CLR CMPT_ELS ; Esborra comptador
LDI FIB_1,1 ; Primer element de la sèrie
MOV E_ACTUAL,FIB_1
ST X+,R16 ; Emmagatzema element en memòria i incrementa punter
CALL ENVIAR_NUM
INC CMPT_ELS ; Incrementa nombre d'elements
LDI FIB_2,1 ; Segon element de la sèrie
MOV E_ACTUAL,FIB_2
CALL ENVIAR_NUM
ST X+,R17 ; Emmagatzema element en memòria i incrementa punter
INC CMPT_ELS ; Incrementa nombre d'elements en 1 (CMPT_ELS + 1)
MOV FIB_3,FIB_1 ; Generació del tercer element
ADD FIB_3,FIB_2 ; De la sèrie FIB_3 = FIB_1 + FIB_2
ST X+,R18 ; Emmagatzema element en memòria i incrementa punter
INC CMPT_ELS ; Incrementa nombre d'elements
Bucle de Generació (NEXT_FIB)
Bucle principal per calcular iterativament els elements restants de la sèrie fins a arribar a N_ELEMENTS.
NEXT_FIB:
MOV FIB_1,FIB_2 ; Desplacem els elements de la sèrie
MOV FIB_2,FIB_3
MOV FIB_3,FIB_1 ; Generació del següent element
ADD FIB_3,FIB_2 ; De la sèrie FIB_3 = FIB_1 + FIB_2
MOV E_ACTUAL,FIB_3
ST X+,FIB_3 ; Emmagatzema element en memòria i incrementa punter
CALL ENVIAR_NUM
INC CMPT_ELS ; Incrementa nombre d'elements en 1 (CMPT_ELS + 1)
CP CMPT_ELS,N_ELEMENTS ; Hem calculat ja N_ELEMENTS?
BRLO NEXT_FIB ; No, repetir operacions
fi:
JMP fi ; Fi del programa
Subrutina ENVIAR_NUM
Envia l'element actual de Fibonacci al Port D de sortida.
ENVIAR_NUM: ; Enviarà el número al port de sortida i iniciarà el retard
OUT PORTD, E_ACTUAL
;CALL RETARD_50ms
RET
Subrutina de Retard (RETARD_50ms)
Implementació d'un retard de 50 mil·lisegons mitjançant bucles anidats. (Nota: 1 us = 1 CK, assumint una freqüència de rellotge específica per a la temporització).
RETARD_50ms: ; 1 ms = 1000 us. 1 us = 1 CK.
LOAD_CMPT_1:
LDI CMPT_1,62 ; 1 CK
LOAD_CMPT_2:
LDI CMPT_2,67 ; 1 CK
DESCOMPTE_2:
DEC CMPT_2 ; 1 CK
BRNE DESCOMPTE_2; 2 CK (si deixa passar), 1 CK (si retorna a DESCOMPTE_1)
DESCOMPTE_1:
DEC CMPT_1 ; 1 CK
BRNE LOAD_CMPT_2; 2 CK (si deixa passar), 1 CK (si retorna a DESCOMPTE_2)
RET ; 4 CK