Обсуждаем контроллеры компании Atmel.
Ответить

AVR Assembler, razyasnite plz (BIN2BCD16)

Сб янв 07, 2006 14:01:01

Разбирался я тут с одной докой Atmel AVR204: BCD Arihmetics , преобразование 16 разрядного двоичного числа в десятично-двоичный код вот эта прцедурка

Код:
;***************************************************************************
;*
;* "bin2BCD16" - 16-bit Binary to BCD conversion
;*
;* This subroutine converts a 16-bit number (fbinH:fbinL) to a 5-digit
;* packed BCD number represented by 3 bytes (tBCD2:tBCD1:tBCD0).
;* MSD of the 5-digit number is placed in the lowermost nibble of tBCD2.
;* 
;* Number of words   :25
;* Number of cycles   :751/768 (Min/Max)
;* Low registers used   :3 (tBCD0,tBCD1,tBCD2)
;* High registers used  :4(fbinL,fbinH,cnt16a,tmp16a)   
;* Pointers used   :Z
;*
;***************************************************************************

;***** Subroutine Register Variables

.equ   AtBCD0   =13      ;address of tBCD0
.equ   AtBCD2   =15      ;address of tBCD1

.def   tBCD0   =r13      ;BCD value digits 1 and 0
.def   tBCD1   =r14      ;BCD value digits 3 and 2
.def   tBCD2   =r15      ;BCD value digit 4
.def   fbinL   =r16      ;binary value Low byte
.def   fbinH   =r17      ;binary value High byte
.def   cnt16a   =r18      ;loop counter
.def   tmp16a   =r19      ;temporary value

;***** Code

bin2BCD16:
   ldi   cnt16a,16   ;Init loop counter   
   clr   tBCD2      ;clear result (3 bytes)
   clr   tBCD1      
   clr   tBCD0      
   clr   ZH      ;clear ZH (not needed for AT90Sxx0x)
bBCDx_1:lsl   fbinL      ;shift input value
   rol   fbinH      ;through all bytes
   rol   tBCD0      ;
   rol   tBCD1
   rol   tBCD2
   dec   cnt16a      ;decrement loop counter
   brne   bBCDx_2      ;if counter not zero
   ret         ;   return

bBCDx_2:ldi   r30,AtBCD2+1   ;Z points to result MSB + 1
bBCDx_3:
   ld   tmp16a,-Z   ;get (Z) with pre-decrement
;----------
;For AT90Sxx0x, substitute the above line with:
;
;   dec   ZL
;   ld   tmp16a,Z
;
;----------
   subi   tmp16a,-$03   ;add 0x03
   sbrc   tmp16a,3   ;if bit 3 not clear
   st   Z,tmp16a   ;   store back
   ld   tmp16a,Z   ;get (Z)
   subi   tmp16a,-$30   ;add 0x30
   sbrc   tmp16a,7   ;if bit 7 not clear
   st   Z,tmp16a   ;   store back
   cpi   ZL,AtBCD0   ;done all three?
   brne   bBCDx_3      ;loop again if not
   rjmp   bBCDx_1      


В упор не понял : .equ AtBCD0 =13 ;address of tBCD0
.equ AtBCD2 =15 ;address of tBCD1
откуда эти значения каков их смысл, соответственно непонятна эта строка
ldi r30,AtBCD2+1 ;Z points to result MSB + 1
после ее выполнения R30=10 ! как? И пожалуйста объясните как работает эта команда
ld tmp16a,-Z ;get (Z) with pre-decrement
Не конечно понятно что загружаем в регистр tmp16a (R19)
значение ячейки памяти данных адрес которой указан в Z,-1? Только где находится эта ячейка и что в ней?
[/code]

Сб янв 07, 2006 14:58:26

Конструктор
.EQU Name = value
- присвоение константы.

Соответственно, выражением
ldi r30,AtBCD2+1
мы записываем в R30 значение константы AtDCD2, увеличенной на 1
В результате, в R30 имеем число 16 (десятичная нотация) или 0х10 в шестнадцатеричной

Z - это регистровая пара, состоящая из регистров ZH (R31) и ZL (R30)
То есть, загружая константу в R30, мы загрузили младшую половину пары Z.
В Z у нас лежит адрес какой-то ячейки ОЗУ. Командой ld, мы грузим содержимое этой ячейки в регистр.

Сб янв 07, 2006 15:43:47

В результате, в R30 имеем число 16 (десятичная нотация) или 0х10 в шестнадцатерично

Конечно как я сразу не догадался, что то мозга заклинила увидел 10 подумал почему то что десятичная система Ж).

Но как же ld tmp16a,-Z если в Z , было 16D получается что мы загружаем данные находящиеся по адресу 15D(SRAM?) вот что тревожит а если у меня в главной программе используется эти ячейки? Почему тогда сразу не написать что эта подпрограмма использует 9 регистров и 16 ячеек памяти а то про регистры написали, а про ячейки памяти ни слова.

Сб янв 07, 2006 17:06:14

Ну застолби ты в главной программе эти адреса.

.DSEG
.ORG 0xff
Reserved: .byte 1

Начиная с адреса 0xff в ОЗУ, выделяем 1 байт памяти под переменную Reserved.

.DSEG прописывается до начала CSEG
Ответить