PIC16Fxx中装配到LCD显示屏的编号

时间:2018-10-08 18:13:15

标签: assembly pic

我正在使用PIC16。

我对如何将汇编中的数字(二进制​​/十六进制/十进制)转换为ASCII以显示在LCD显示器中感到困惑,例如:

我这里有一个号码存储在寄存器中

number = 0x04d2(十进制为1234)

 0x30 = 0x04
 0x31 = 0xd2 

我将如何将其转换为ASCII,以便LCD在显示屏上显示1234?

不使用除法。

5 个答案:

答案 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字符。

我将把这项工作留给原始海报。祝你好运。