Полная версия этой страницы:
преобразование 32бита в BCD
помогите как преобразовать в асм-е 32 бита (или 24) в bcd формат для индикации на datavision экране.
может есть у кого действующий кусок программы.
си не знаю/не предлогать.
в апноте есть же на 16 бит - преобразовать в 24 вроде не сложно я преобразовывал
если проблема останется - могу покапаться в архивах
aleksey_g
Apr 7 2006, 12:51
Цитата(индюк @ Apr 7 2006, 04:34)

помогите как преобразовать в асм-е 32 бита (или 24) в bcd формат для индикации на datavision экране.
может есть у кого действующий кусок программы.
си не знаю/не предлогать.
Все таки здесь С + асм неоптимально, но работает.
Пробуйте если мне неизменяет память это подправленый исходник аппнота
делалась давно - извиняюсь за корявость
Код
;**************************************************
; in temp4 -temp3-temp2-temp
; входное значение не более 99 999 999 (dec)
; out temp8-temp7-temp6-temp5
; time cpu = 1760 cycle
.equ _AtBCD5 =2;address of tBCD0
.equ _AtBCD7 =5;address of tBCD1
bin2BCD32:
pushz
push r20
push r21
ldi r20,32;Init loop counter
clr temp8
clr temp7;clear result (3 bytes)
clr temp6
clr temp5
clr ZH;clear ZH (not needed for AT90Sxx0x)
_bBCDx_1:
lsl TEMP;shift input value
rol TEMP2;through all bytes
rol temp3
rol temp4
rol temp5;
rol temp6
rol temp7
rol temp8
dec r20;decrement loop counter
brne _bBCDx_2;if counter not zero
pop r21
pop r20
popz
ret; return
_bBCDx_2:
ldi zl,_AtBCD7+1;Z points to result MSB + 1
_bBCDx_3:
ld r21,-Z;get (Z) with pre-decrement
subi r21,-$03;add 0x03
sbrc r21,3;if bit 3 not clear
st Z,r21; store back
ld r21,Z;get (Z)
subi r21,-$30;add 0x30
sbrc r21,7;if bit 7 not clear
st Z,r21; store back
cpi ZL,_AtBCD5;done all three?
brne _bBCDx_3;loop again if not
rjmp _bBCDx_1
спасибо, попробую. я начинающий.
2 kovrov
чотто или я делаю не так или у вас чувство юмора хорошее, но в симуляторе программа просто переписывает значания регистров без видимых изменений.
наверное вы чтото не так делаете,
а на чувство юмора я действительно не жалуюсь
а если серьезно обратите внимание на эти строки:
.equ _AtBCD5 =2;address of tBCD0
.equ _AtBCD7 =5;address of tBCD1
и
ldi zl,_AtBCD7+1;Z points to result MSB + 1
_bBCDx_3:
ld r21,-Z;get (Z) with pre-decrement
здесь стоит косвенная адресация к регистру
ячейка памяти по адресу в Z имеено ссылается на данные регистра с адресом _ATBCD5
поэтому _ATBCD5 = 2 а это есть регистр R2, он же темп5
или если короче
то
temp5= r2
temp6= r3
temp7= r4
temp8= r5
и ни как иначе или правьте _ATBCD5,7 под адрес своего регистра
а, понял, щас еще раз все запущу. вы уж извините, что я так, начинающий я. мне разжовывать все пока надо.
спасибо огромное - работает на ура!
а где бы мне посмотреть как число 6000д умножить на 25д и прибавить или вычесть из результата 10700д?
и еще как вычитать и прибавлять по единице от 6000д?
Любой контроллер как правило работает на 16ричной системе от 0 до F
поэтому работать с десятичными числами на уровне арифметики - не разумно
работайте с 16ричными значениями а потом преобразовывайте в десятичные...
а умножение делать на авр сам бог велел - в смысле очень просто.....
да я просто имел ввиду что числа именно такие, конечно я и собираюсь их умножать в бине а не в деке. я хоть и начинающий но не настолько же!!! я начинающий в плане математики. так я много чего для себя могу.
расскажите чего как мне сделать плиз!
Romario
Apr 9 2006, 16:42
ну и до кучи - честно стыренный алгоритм с телесистем.
Автору поста не смотреть, т.к. на С.
может кому пригодится. Самое сложное тут умноить на 429497
Сам алгоритм можно понять, но немного поясню.
w тут используется чтобы засечь ведущий не 0.
Код
static u8_t * PutWord(u8_t *p, u16_t w) {
vu32_t res32;
vu32_t ret ;
u64_t res48 = (u64_t)w * 429497ull;
////////////////////////////////////////////////////////
res32 = (res48 >> 16);
res32++;
// десятки тыщ
w = res32 >> 16;
if (w) {
*p++ = w | '0';
}
// тыщи
ret = (res32 = (res32 & 0xffff) * 10) >> 16;
if (ret || w) {
w = 1;
*p++ = ret | '0';
}
// сотни
ret = (res32 = (res32 & 0xffff) * 10) >> 16;
if (ret || w) {
w = 1;
*p++ = ret | '0';
}
// десятки
ret = (res32 = (res32 & 0xffff) * 10) >> 16;
if (ret || w) {
*p++ = ret | '0';
}
// еденицы
*p++ = (((res32 & 0xffff) * 10) >> 16) | '0';
return p;
}
Для просмотра полной версии этой страницы, пожалуйста,
пройдите по ссылке.