|
преобразования 16 bit to 5 digit ASCII, ПРЕОБРАЗОВАНИЯ ЧИСЕЛ ДЛЯ ЖКИ |
|
|
|
Jul 13 2013, 19:29
|
Группа: Новичок
Сообщений: 5
Регистрация: 13-07-13
Из: Москва
Пользователь №: 77 516

|
Здравствуйте!!! Господа Подскажите как преобразовать в BCD формат для отображения на LCD в этой программе я не знаю ПОМОГИТЕ ПОЖАЛУЙСТА!!! мне надо от 0 до 9999. Пишу на асме CODE 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 - Jul 15 2013, 07:07
Причина редактирования: [codebox] для длинного кода, [code] - для короткого!!!
|
|
|
|
|
 |
Ответов
(1 - 10)
|
Jul 14 2013, 09:38
|
Группа: Новичок
Сообщений: 5
Регистрация: 13-07-13
Из: Москва
Пользователь №: 77 516

|
; Вот написал такую программу, но она считает только до 9-и кто подскажет что не так? ;Не судите строго я новичек. А на C писать не умею. CODE ; ПРОГРАММА - счетчик электронный для счета импульсов ; ; Кварц - 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 - Jul 15 2013, 07:08
Причина редактирования: [codebox] для длинного кода, [code] - для короткого!!!
|
|
|
|
|
Jul 14 2013, 10:53
|
Группа: Новичок
Сообщений: 5
Регистрация: 13-07-13
Из: Москва
Пользователь №: 77 516

|
Вы о чем?)))Я просто не знаю куда цифры подставить и откуда потом снять эти значения, а так в протеусе все работает
|
|
|
|
|
Aug 19 2013, 11:28
|
Местный
  
Группа: Участник
Сообщений: 246
Регистрация: 4-12-06
Пользователь №: 23 101

|
Вычитанием 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
|
|
|
|
|
Sep 15 2013, 16:26
|
Участник

Группа: Участник
Сообщений: 52
Регистрация: 15-05-13
Пользователь №: 76 836

|
можно ещё вот так: Код ;*************************************************************************** ;* ;* "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
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|