Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: преобразование 32бита в BCD
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > AVR
индюк
помогите как преобразовать в асм-е 32 бита (или 24) в bcd формат для индикации на datavision экране.
может есть у кого действующий кусок программы.
си не знаю/не предлогать.
Kovrov
в апноте есть же на 16 бит - преобразовать в 24 вроде не сложно я преобразовывал
если проблема останется - могу покапаться в архивах
aleksey_g
Цитата(индюк @ Apr 7 2006, 04:34) *
помогите как преобразовать в асм-е 32 бита (или 24) в bcd формат для индикации на datavision экране.
может есть у кого действующий кусок программы.
си не знаю/не предлогать.


Все таки здесь С + асм неоптимально, но работает.
Kovrov
Пробуйте если мне неизменяет память это подправленый исходник аппнота
делалась давно - извиняюсь за корявость


Код
;**************************************************
; 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
чотто или я делаю не так или у вас чувство юмора хорошее, но в симуляторе программа просто переписывает значания регистров без видимых изменений.
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д?
Kovrov
Любой контроллер как правило работает на 16ричной системе от 0 до F
поэтому работать с десятичными числами на уровне арифметики - не разумно
работайте с 16ричными значениями а потом преобразовывайте в десятичные...
а умножение делать на авр сам бог велел - в смысле очень просто.....
индюк
да я просто имел ввиду что числа именно такие, конечно я и собираюсь их умножать в бине а не в деке. я хоть и начинающий но не настолько же!!! я начинающий в плане математики. так я много чего для себя могу.

расскажите чего как мне сделать плиз!
Kovrov
http://www.atmel.com/dyn/products/app_note...p?family_id=607
здесь вы найдете все ответы на свои вопросы!!
Romario
ну и до кучи - честно стыренный алгоритм с телесистем.
Автору поста не смотреть, т.к. на С.
может кому пригодится. Самое сложное тут умноить на 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;
}
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.