Перейти к содержанию
    

преобразования 16 bit to 5 digit ASCII

Здравствуйте!!! Господа

Подскажите как преобразовать в BCD формат для отображения на LCD в этой программе я не знаю ПОМОГИТЕ ПОЖАЛУЙСТА!!!

мне надо от 0 до 9999. Пишу на асме

1.;********************************************************************
***** 

2. ;* * 

3. ;* Convert unsigned 16 bit to 5 digit ASCII * 

4. ;* * 

5. ;* * 

6. ;* * 

7. ;************************************************************************* 

8. ; 

9. ;Входной: R17, R16 = 16 bit значение 0… 65535

10.; выход: R20, R18, R19, R17, R16 = 5 цифр (ASCII)

11.; цикл: 20… 170

12. 

13.push temp

14. 

15.LCDCLR ;очистка LCD 

16.LCD_COORD 1,0;

17. 

18.pop temp

19. 

20. bin16_ascii: 

21. 

22. 

23. 

24.inc temp

25. ldi r17,0

26. 

27. 

28. 

29.; ldi r21, 10 + ’0′ 

30.; _bcd0: dec r21 

31.; subi r16, low(-100000) ;+100000 

32.; sbci r17, high(-100000) 

33.; brcs _bcd0 

34. 

35. ldi r20, -1 + ’0′ 

36. _bcd1: inc r20 

37. subi r16, low(10000) ;-10000 

38. sbci r17, high(10000) 

39. brcc _bcd1 

40. 

41. ldi r19, 10 + ’0′ 

42. _bcd2: dec r19 

43. subi r16, low(-1000) ;+1000 

44. sbci r17, high(-1000) 

45. brcs _bcd2 

46. 

47. ldi r18, -1 + ’0′ 

48. _bcd3: inc r18 

49. subi r16, low(100) ;-100 

50. sbci r17, high(100) 

51. brcc _bcd3 

52. 

53. ldi r17, 10 + ’0′ 

54. _bcd4: dec r17 

55. subi r16, -10 ;+10 

56. brcs _bcd4 

57. 

58. subi r16, -’0′ 

59. 

60. ;————————————————————————-

61. 

62. rcall RD_DATA;

63. 

64. 

65. 

66. 

67.reti ;выход

Изменено пользователем IgorKossak
[codebox] для длинного кода, [code] - для короткого!!!

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Подскажите как преобразовать в BCD формат для отображения на LCD в этой программе я не знаю ПОМОГИТЕ ПОЖАЛУЙСТА!!!

мне надо от 0 до 9999. Пишу на асме

Да я так же делал - вычитанием выделял тысячи (сначала обнуляем счетчик тысяч, а потом вычитаем из преобразуемого числа 1000, пока результат >=0, всякий раз при вычитании увеличивая счетчик тысяч на единичку), сотни и проч. Только писал на Си. На Си пишите, это гораздо проще. Там даже соотв функция готовая есть, если я не ошибаюсь ...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

;

Вот написал такую программу, но она считает только до 9-и кто подскажет что не так?

 

;Не судите строго я новичек. А на C писать не умею.

; ПРОГРАММА - счетчик электронный для счета импульсов
;
; Кварц - 4 МГц
;
.include file "C:\AVR\AvrAssembler2\Appnotes\tn2313def.inc"

;======================================================
#define F_CPU (4000000)
;Здесь идёт определение тактовой частоты. Нужно для 
;библиотеки задержек,используемой в этой либе. 
;Частота в Герцах.
;======================================================
.def		temp	=r16		;временный
.def		temp1	=r17		;временный
.def		temp2	=r18		;временный
.def		temp3	=r19		;временный
.def		temp4	=r20		;временный


.CSEG
.org	0
rjmp START		; На основную программу

.org	INT0addr
rjmp	Forward	;Oбработкa прерывания по INT0 (инкремент)
.org	INT1addr
rjmp	Back		;Oбработкa прерывания по INT1 (декремент)

;*************************************************************************
START:
;	ldi	temp,$0F
;	out	WDTCR,temp	;Включение сторожевого таймера 1,9 секунды.

;======================================================
ldi Temp1,RamEnd		; установка указателя стека
out SPL,Temp1
;Инициализация стека. Обязательно!!!
;------------------------------------------------------

   ldi	temp1,0b00000000
      out	DDRD,temp1	;Направление данных PortD (1)-выходы
      ldi	temp1,0b11111111
      out	PORTD,temp1
      ldi	temp1,0b11111111
      out	DDRB,temp1	;Направление данных порта B на вывод,В.1,2 -как входы
   out	PORTB,temp1	;Выдать данные на порт В


;	rcall	LongDelay	;программная задержка при включении
wdr			;сбросить стор. таймер

;     sbic pinb,Kn_2 ;если кнопка не нажата перейти на следующую команду
    ldi temp1,(1<<ISC01|1<<ISC11);устанавливаем прерывания INT0 и INT1 по спадающему фронту (ШУЛМ)

   out MCUCR,temp1
;**************************************************************************

   rcall lcd_init;Инициализация дисплея.

nop
   nop

ldi temp,225

;**************************************************************************

sei ;разрешаем прерывания
Inf: 
    ldi temp1,(1<<INT1)+(1<<INT0);разрешаем прерывания INT1,INT0
    out GIMSK,temp1

rjmp Inf              ;бесконечный цикл


;*************************************************************************
Forward:;(ПРИБАВИТЬ)

;*************************************************************************

inc temp
ldi r17,0
; ldi r16,9

rcall bin16_ascii

;ldi r16,0x45
;rcall LCD_SetAddressDD

;-------------------------------------------------------------------------

reti                            ;выход из обработчика

;//////////////////////////////////////////////////////////////////////////////
;*************************************************************************
bin16_ascii:
;************************************************************************* 
;*                                                                       * 
;*                      Convert unsigned 16 bit to 5 digit ASCII         * 
;*                                                                       * 
;*                                                                       * 
;*                                                                       * 
;************************************************************************* 
; 
;входной: R17, R16 = 16 bit значение 0... 65535
; выход: R20, R18, R19, R17, R16 = 5 цифр (ASCII)
; цикл: 20... 170

        ldi     r21, 10 + '0' 
_bcd0:  dec     r21 
        subi    r16, low(-100000)         ;+100000 
        sbci    r17, high(-100000) 
        brcs    _bcd0 

        ldi     r20, -1 + '0' 
_bcd1:  inc     r20 
        subi    r16, low(10000)         ;-10000 
        sbci    r17, high(10000) 
        brcc    _bcd1 

        ldi     r19, 10 + '0' 
_bcd2:  dec     r19 
        subi    r16, low(-1000)         ;+1000 
        sbci    r17, high(-1000) 
        brcs    _bcd2 

        ldi     r18, -1 + '0' 
_bcd3:  inc     r18 
        subi    r16, low(100)           ;-100 
        sbci    r17, high(100) 
        brcc    _bcd3 

        ldi     r17, 10 + '0' 
_bcd4:  dec     r17 
        subi    r16, -10                ;+10 
        brcs    _bcd4 

        subi    r16, -'0' 

;-------------------------------------------------------------------------


push	temp

ldi r16,0x01 ;Команда очистки дисплея
rcall LCD_WriteCommand
ldi r16,0x45
rcall LCD_SetAddressDD

pop	temp




;Число должно быть в r16,чтоб отобразить на LCD
        rcall  LCD_WriteData 

; А вывод кода неупакованного BCD на дисплей зависит от его типа (дисплея).
; Если требуются ASCII символы, перед выводом добавляете к цифре $30 (0x30h).
ret

Back:;(Отнять)
;//////////////////////////////////////////////////////////////////////////////
;*************************************************************************

dec temp
ldi r17,0
; ldi r16,9

rcall bin16_ascii

;ldi r16,0x45
;rcall LCD_SetAddressDD

;-------------------------------------------------------------------------

reti                            ;выход из обработчика
;**************************************************************************
; Подпрограммы выдержек времени (0,5 сек и 2,5 миллисекунды)

LongDelay:	;Задержка 0,5 сек
push	temp1
ldi	temp1,$85
out	TCNT1H,temp1	;загрузим старший байт Т1
ldi	temp1,$EE
out	TCNT1L,temp1	;загрузим младший байт Т1
rjmp	PUSK

Delay:		;Задержка 2,5 мсек
push	temp1
ldi	temp1,$FF
out	TCNT1H,temp1	;загрузим старший байт Т1
ldi	temp1,$64
out	TCNT1L,temp1	;загрузим младший байт Т1

PUSK:		;запуск таймера
ldi	temp1,3
out	TCCR1B,temp1	;загрузим к-т предделителя Т1 и запустим его

LooP:		;цикл
in	temp1,TIFR
sbrs	temp1,7	;таймер-счетчик переполнен?
rjmp	LooP
ldi	temp1,0
out	TCCR1B,temp1	;остановить счетчик таймера
ldi	temp1,$80
out	TIFR,temp1	;сбросить флаг переполнения таймера
pop	temp1
ret

.include file "C:\AVR\WH4\hd44780.asm"

; Подключение библиотеки для
                     ; работы с дисплеем.

Изменено пользователем IgorKossak
[codebox] для длинного кода, [code] - для короткого!!!

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вы о чем?)))Я просто не знаю куда цифры подставить и откуда потом снять эти значения, а так в протеусе все

работает

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Хе...

Можно и по одной единице вычитать из исходного числа

или десятками(если время есть)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вычитанием 50000,10000,5000,10000 и т.д.

hex в Yh:Yl результат в регистрах tmp1..tmp3

работает довольно быстро

 

//;                 hex16tobcd                                             
hex2utobcdf:; Y -><1:2:3> 6:55:35 max

    clr    tmp1
    clr    tmp2
    clr    tmp3            ; 159 циклов в худшем случае (59999)
    cp2i    Yh,Yl,50000                ; 65 в лучшем (0)
                brlo hxl50k
    subi    tmp1,-5    sub2i    Yh,Yl,50000                
hxl50k: cp2i    Yh,Yl,10000
                brlo hxl10k
    inc    tmp1        sub2i    Yh,Yl,10000
                rjmp hxl50k
hxl10k: cp2i    Yh,Yl,5000
                brlo hxl5k
    subi    tmp2,-$50    sub2i    Yh,Yl,5000
hxl5k: cp2i    Yh,Yl,1000
                brlo hxl1k
    subi    tmp2,-$10    sub2i    Yh,Yl,1000
                rjmp hxl5k
hxl1k: cp2i    Yh,Yl,500
                brlo hxl5c
    subi    tmp2,-5    sub2i    Yh,Yl,500
hxl5c: cp2i    Yh,Yl,100    
                brlo hxl1c
    inc    tmp2        sub2i    Yh,Yl,100
                rjmp hxl5c
hxl1c: cpi    Yl,50        brlo hxl50
    subi    tmp3,-$50    subi    Yl,50
hxl50: cpi    Yl,10        brlo hxl10
    subi    tmp3,-$10    subi    Yl,10
                rjmp hxl50
hxl10: or    tmp3,Yl

    ret



.MACRO CP2I        ///CP2I r1,r2, 1234   compare <1:2> with 1234
           push  r26
        cpi    @1,low(@2)        
     ldi    r26,high(@2)
     cpc    @0,r26
     pop    r26
.ENDMACRO              
   

               
.MACRO SUB2I        ///    SUB2I Yh,Yl,1234      ; <@0:@1> - 1234 --> <@0:@1>  
        subi     @1,low(@2) 
     sbci    @0,high(@2)
.ENDMACRO

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

можно ещё вот так:

 

;***************************************************************************
;*
;* "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
;*
;***************************************************************************

;    Courtesy Atmel app note AVR204.ASM

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
    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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...