我正在使用PIC16。
我对如何将汇编中的数字(二进制/十六进制/十进制)转换为ASCII以显示在LCD显示器中感到困惑,例如:
我这里有一个号码存储在寄存器中
number = 0x04d2(十进制为1234)
0x30 = 0x04
0x31 = 0xd2
我将如何将其转换为ASCII,以便LCD在显示屏上显示1234?
不使用除法。
答案 0 :(得分:1)
在PIC16汇编器中看起来像16位除以10一样...
;Input RegA2 as low byte RegA1 as High byte
;Result of division by 10 is stored back to RegA2 and RegA1
;Remainder of division is stored in RegA0
;RegAE is temporary storage
clrf RegA0
movlw 16
movwf RegAE
lslf RegA2, f
divI16by_c10_
rlf RegA1, f
rlf RegA0, f
movlw 10
subwf RegA0, f
btfsc Carry
bra divI16by_c10_OK
addwfc RegA0, f
bcf Carry
divI16by_c10_OK
rlf RegA2, f
decfsz RegAE, f
bra divI16by_c10_
return
只需复制到C语言...
答案 1 :(得分:0)
这是用C语言编写的示例,但是在汇编中只需做很少的改动就可以完成。
static void Console_printNum(
uint32_t num,
uint8_t base,
uint8_t point)
{
#define CHAR_BUFSIZE 33
const char* const numchars[] = {"0","1","2","3","4","5","6","7","8","9",
"A","B","C","D","E","F"};
const char* buf[CHAR_BUFSIZE];
const char** pStr = &(buf[CHAR_BUFSIZE-1]);
do {
*(--pStr) = numchars[num % base];
num /= base;
} while( num != 0 );
while( pStr < &buf[CHAR_BUFSIZE-1] ) { //copy the buffer into the queue
if((&buf[CHAR_BUFSIZE-1] - pStr) == point) {
Console_printStr("."); //print decimal point
}
Console_printStr(*pStr++);
}
}
答案 2 :(得分:0)
要将数字转换为ASCII,只需添加0x30
。
0十进制0x30 ASCII
1个十进制0x30 ASCII
2个十进制0x32 ASCII
...
当然,您必须将数字分成几位数。
答案 3 :(得分:0)
在这里工作是我的工作方式。
B_HIGH_BYTE和B_LOW_BYTE是要转换为ASCII的数字,这里的所有其他内容只是一个临时变量
我手动将数字除以d'10000',d'1000',d'100',d'10',最后剩下的就是:)
可能不是购买使其满足我的需求的最快方法。谢谢您的所有建议。
;====================================SPECIAL DIVISION========================
SPECIAL_DIVISION
clrf SPECIAL_DIV_COUNTER
clrf SPECIAL_DIV_HIGH_BYTE
clrf SPECIAL_DIV_LOW_BYTE
clrf SPECIAL_DIV_PREV_ANS_HIGH_BYTE
clrf SPECIAL_DIV_PREV_ANS_LOW_BYTE
movf B_HIGH_BYTE, 0
movwf SPECIAL_DIV_HIGH_BYTE
movf B_LOW_BYTE, 0
movwf SPECIAL_DIV_LOW_BYTE
loop_SD ;getting 5th digit
movf SPECIAL_DIV_HIGH_BYTE,0
movwf SPECIAL_DIV_PREV_ANS_HIGH_BYTE
movf SPECIAL_DIV_LOW_BYTE,0
movwf SPECIAL_DIV_PREV_ANS_LOW_BYTE
movlw 0x10
subwf SPECIAL_DIV_LOW_BYTE,1
btfss STATUS,0
goto $+2
goto $+3
movlw 0x01
subwf SPECIAL_DIV_HIGH_BYTE,1
btfss STATUS,0
goto $+7
movlw 0x27
subwf SPECIAL_DIV_HIGH_BYTE,1
btfss STATUS,0
goto $+3
incf SPECIAL_DIV_COUNTER
goto loop_SD
movf SPECIAL_DIV_COUNTER,0
addlw 0x30
call display_digit
clrf SPECIAL_DIV_COUNTER
movf SPECIAL_DIV_PREV_ANS_HIGH_BYTE,0
movwf SPECIAL_DIV_HIGH_BYTE
movf SPECIAL_DIV_PREV_ANS_LOW_BYTE,0
movwf SPECIAL_DIV_LOW_BYTE
loop_SD2 ;getting 4th digit
movf SPECIAL_DIV_HIGH_BYTE,0
movwf SPECIAL_DIV_PREV_ANS_HIGH_BYTE
movf SPECIAL_DIV_LOW_BYTE,0
movwf SPECIAL_DIV_PREV_ANS_LOW_BYTE
movlw 0xe8
subwf SPECIAL_DIV_LOW_BYTE,1
btfss STATUS,0
goto $+2
goto $+3
movlw 0x01
subwf SPECIAL_DIV_HIGH_BYTE,1
btfss STATUS,0
goto $+7
movlw 0x03
subwf SPECIAL_DIV_HIGH_BYTE,1
btfss STATUS,0
goto $+3
incf SPECIAL_DIV_COUNTER
goto loop_SD2
movf SPECIAL_DIV_COUNTER,0
addlw 0x30
call display_digit
clrf SPECIAL_DIV_COUNTER
movf SPECIAL_DIV_PREV_ANS_HIGH_BYTE,0
movwf SPECIAL_DIV_HIGH_BYTE
movf SPECIAL_DIV_PREV_ANS_LOW_BYTE,0
movwf SPECIAL_DIV_LOW_BYTE
loop_SD3 ;getting 3rd digit
movf SPECIAL_DIV_HIGH_BYTE,0
movwf SPECIAL_DIV_PREV_ANS_HIGH_BYTE
movf SPECIAL_DIV_LOW_BYTE,0
movwf SPECIAL_DIV_PREV_ANS_LOW_BYTE
movlw 0x64
subwf SPECIAL_DIV_LOW_BYTE,1
btfss STATUS,0
goto $+2
goto $+3
movlw 0x01
subwf SPECIAL_DIV_HIGH_BYTE,1
btfss STATUS,0
goto $+3
incf SPECIAL_DIV_COUNTER
goto loop_SD3
movf SPECIAL_DIV_COUNTER,0
addlw 0x30
call display_digit
clrf SPECIAL_DIV_COUNTER
movf SPECIAL_DIV_PREV_ANS_HIGH_BYTE,0
movwf SPECIAL_DIV_HIGH_BYTE
movf SPECIAL_DIV_PREV_ANS_LOW_BYTE,0
movwf SPECIAL_DIV_LOW_BYTE
loop_SD4 ;getting 2nd digit
movf SPECIAL_DIV_HIGH_BYTE,0
movwf SPECIAL_DIV_PREV_ANS_HIGH_BYTE
movf SPECIAL_DIV_LOW_BYTE,0
movwf SPECIAL_DIV_PREV_ANS_LOW_BYTE
movlw 0x0a
subwf SPECIAL_DIV_LOW_BYTE,1
btfss STATUS,0
goto $+2
goto $+3
movlw 0x01
subwf SPECIAL_DIV_HIGH_BYTE,1
btfss STATUS,0
goto $+3
incf SPECIAL_DIV_COUNTER
goto loop_SD4
movf SPECIAL_DIV_COUNTER,0
addlw 0x30
call display_digit
clrf SPECIAL_DIV_COUNTER
movf SPECIAL_DIV_PREV_ANS_HIGH_BYTE,0
movwf SPECIAL_DIV_HIGH_BYTE
movf SPECIAL_DIV_PREV_ANS_LOW_BYTE,0
movwf SPECIAL_DIV_LOW_BYTE
movf SPECIAL_DIV_LOW_BYTE,0 ;getting 1st digit
addlw 0x30
call display_digit
return
答案 4 :(得分:0)
我将如何将其转换为ASCII,以便LCD将 在显示屏上显示1234?
不使用除法。
“不使用除法”是棘手的部分。第一步是将16位二进制数转换为BCD表示形式。最好的可用方法有几个名称,最常见的是“双重涉猎”算法。这是PIC16F的示例:
;
; See:
; https://en.wikipedia.org/wiki/Double_dabble
;
BIN2BCD_VAR UDATA
A_reg: res 2
D_reg: res 3
mBits: res 1
BIN2BCD_CODE CODE
;
; Function: Bin2BCD
; Input: A_reg, 16-bit binary
;
; Output: D_reg, 3 bytes of packed BCD digits
;
Bin2BCD:
banksel D_reg
clrf D_reg+0 ; Clear result
clrf D_reg+1
clrf D_reg+2
movlw D'16' ; Set bit counter
movwf mBits
ConvertBit:
movlw H'33' ; Correct BCD value so that
addwf D_reg+0,F ; subsequent shift yields
btfsc D_reg+0,.3 ; correct value.
andlw H'F0'
btfsc D_reg+0,.7
andlw H'0F'
subwf D_reg+0,F
movlw H'33'
addwf D_reg+1,F
btfsc D_reg+1,.3
andlw H'F0'
btfsc D_reg+1,.7
andlw H'0F'
subwf D_reg+1,F
rlf A_reg+0,F ; Shift out a binary bit ...
rlf A_reg+1,F
rlf D_reg+0,F ; ... and into BCD value.
rlf D_reg+1,F
rlf D_reg+2,F
decfsz mBits,F ; Repeat for all bits
goto ConvertBit
return
下一部分是将BCD表示一次转换为4位ASCII字符。
我将把这项工作留给原始海报。祝你好运。