# Sending 16-BIT number to an LCD

Discussion in 'General Electronics Chat' started by Siyom, Oct 15, 2012.

1. ### Siyom Thread Starter Member

Aug 9, 2012
33
0
When programming with assembly,how do you send a 16 bit value to the LCD,do you need to break the numbers down,because in assembly you can only send single characters and a number like 8760 is a bit too much,even if i take it in binary i just don't see i can send it to LCD

2. ### Dodgydave AAC Fanatic!

Jun 22, 2012
5,156
772
if its a dot matrix lcd, you use a full 8bit port to select the matrix address, 4bits row, 4bits column

3. ### Papabravo Expert

Feb 24, 2006
10,340
1,850
Divide and conquer. The maximum nuber of decimal digits in a 16-bit unsigned number is 5. So

1. Set DIVISOR to 10,000 = 10^4 and compute the QUOTIENT and the REMAINDER.
2. Add the value of ASCII '0' to the QUOTIENT and send that to the display.
3. Reduce the value of DIVISOR by a factor of 10 to 1000 = 10^3
4. Compute the QUOTIENT and REMAINDER of the step 1. REMAINDER divided by DIVISOR.
5. Add the value of ASCII '0' to the QUOTIENT and send that to the display.
6. Reduce the value of DIVISOR by a factor of 10 to 100 = 10^2
7. Compute the QUOTIENT and REMAINDER of the step 4. REMAINDER divided by DIVISOR.
8. Add the value of ASCII '0' to the QUOTIENT and send that to the display.
9. Reduce the value of DIVISOR by a factor of 10 to 10 = 10^1
10. Compute the QUOTIENT and REMAINDER of the step 7. REMAINDER divided by DIVISOR.
11. Add the value of ASCII '0' to the QUOTIENT and send that to the display.
12. Add the value of ASCII '0' to the REMAINDER and send that to the display.

I'm just curious -- how did you imagine it was done?

Siyom likes this.
4. ### takao21203 Distinguished Member

Apr 28, 2012
3,578
463
Yes could divide.

You can also maintain individual digit counters (each occupying 8 bits).
Then you get rid of the division which is not so much desireable in assembler.

5. ### JohnInTX Moderator

Jun 26, 2012
2,394
1,051
First, assuming you are working with binary numbers, you must convert the binary to BCD (binary coded decimal). For example, your value 8760 is 2238 hex. This won't do for displays so convert to BCD.

The algorithm shown converts a 16 bit binary number in two registers (22h 38h in your case) and converts them to a packed BCD number (two digits 0-9 in each byte) in 3 registers (to hold the 5 digits required). So 22h 38h will convert to 00h 87h 60h.

Next, you need to unpack the BCD since you will be outputting one digit at a time. The particular routine I grabbed does this for 4 individual digits but you get the idea. It could also be done on the fly.. These unpacked digits in 4 registers look like 08h 07h 06h 00h (the 5 MSdigit was unused in this project but its valid in R0).

Finally, for each digit you'll have to convert it to agree with what the display wants. For 7 segment displays, each byte value can be used as as is as an index into a table of segment patterns. For a terminal UART or dot matrix LCDdisplay using the standard Hitachi 44780 or similar, you'll need to convert the unpacked BCD to ASCII which is done simply by adding 30h to each digit giving 38h 37h 36h 30h. Send these 4 to the display and it will read 8738 just like you want. Of course, there is more formatting you can do but I find this to be a good method regardless of the assembler / processor you use.

Its also expandable to as many bits (24 or 32 or more) as you have RAM/time for. Also, its for a PIC but the basic algorithm will work on any processor.

Code ( (Unknown Language)):
1. ;***********************  BIN2BCD.asm  *****************************
2.
3. ;********************************************************************
4. ;                  Binary To BCD Conversion Routine
5. ;      This routine converts a 16 Bit unsigned binary Number to a 5 Digit
6. ; BCD Number.
7. ;
8. ;       The 16 bit binary number is input in locations H_Byte and
9. ; L_Byte with the high byte in H_Byte.
10.
11. ;        The BCD result is returned as packed BCD in R0-R1-R2 as 0d dd dd (R0 has MSdigit, R2 has 2 LSdigits)
12.
13. ;       In this one, the lower 4 digits of the BCD number are returned UNPACKED in 4 bytes:
14. ;    MSDcode-LSD code.  (PROJECT SPECIFIC but shows you how to do it)
15. ;    Since the 4 umpacked bytes have the form 0d where d is 0h-9h, each can be used as an
16. ;    index into a segment table (for 7-segment LEDs) or added to 30h to convert each
17. ;    to an ASCII character for terminal UART or Hitachi LCD controllers.
18.
19. ;   Calls: adjBCD  1 level
20. ;   Uses FSR
21. ;     Originally written for 16C5x
22. ;
23. ;*******************************************************************;
24.
25. B_2unpakedBCD_1:
26.           bcf     STATUS,0        ; clear the carry bit
27.           movlw   .16
28.           movwf   BitCount
29.           clrf    R0
30.           clrf    R1
31.           clrf    R2
32.
33.  ; Left shift binary and partial BCD.. R0-R1-R2-H_Byte-L_Byte
34. loop16: rlf     L_Byte,F
35.           rlf     H_Byte,F
36.           rlf     R2,F
37.           rlf     R1,F
38.           rlf     R0,F
39.
40.           decfsz  BitCount,F    ; iff not 16 bits yet, adjust each 4 bit nibble
42.
43.           goto    unpakit        ; else, done, packed BCD in R0,R1,R2 unpack it to 4 BCD
44.
45. adjDEC:   movlw   R2ADDR        ; sets pointer to R2 in bank 1
47.
50.
53.
54.           goto    loop16
55.
57.           movwf      FSR
58.           movlw   03h            ; BCD-adjust lower nibble in reg
60.           movwf   temp
61.           btfsc   temp,3        ; test if result > 7 ( bit 3 == 1)
62.           movwf   INDF            ; save it iff so.. else ignore it
63.           movlw   30h
65.           movwf   temp
66.           btfsc   temp,7        ; test if result > 7 (bit 7 == 1)
67.           movwf   INDF          ; save as MS nibble iff so
68.           retlw   0
69.
70.           ;********************  UNPACK BCD  ****************************
71.           ; Unpacks BCD output from B2_BCD into overlayed Segment regs
72.           ; as codes  Puts the 5th (MSD) digit in temp
73.           ; Runs in bank 1, returns bank 0
74.         ; NOTE THIS IS PROJECT-SPECIFIC..
75.
76. unpakit:
77.           movf    R0,W
78.           movwf   B2_BCD_5th_dig
79.
80.           swapf   R1,W            ; copy lower 4 BCD to 4 RAM locations as 0d where d is the digit
81.           andlw   0fh
82.           movwf   MSDcode
83.
84.           movf    R1,W
85.           andlw   0fh
86.           movwf   MSDcode+1
87.
88.           swapf   R2,W
89.           andlw   0fh
90.           movwf   MSDcode+2
91.
92.           movf    R2,W
93.           andlw   0fh
94.           movwf   LSDcode
95.           clrf    FSR
96.           retlw   0
97.
98.

Siyom likes this.
6. ### Siyom Thread Starter Member

Aug 9, 2012
33
0
Thank you very much