Follow along with the video below to see how to install our site as a web app on your home screen.
Note: This feature may not be available in some browsers.
This is for 8 bits and PIC 18F, but it may give you an idea. You want hex digits, I assume?Suraj143 said:Hi guys I have a 10 bit result from AD converter which are in two 8 bit GP registers.
Now I want to convert this binary value to decimal value to show in the four segments.
If you have any idea (easy way) please share with me.
fhex db "0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f"
;****************************************************************
; fixhex - subroutine takes byte passed in W - splits it into two
; ascii bytes representing hex digits and outputs them to RS232
fixhex movwf temp ;store it for later
movwf dec1 ;and put it in dec1 too
movlw 0xf0 ;mask out low nybble
andwf dec1
swapf dec1 ;swap nybbles
movlw fhex ;point W to table start
addwf dec1 ;add offset to desired digit
clrf TBLPTRH ;set up table pointer
movff dec1,TBLPTRL
tblrd * ;read the byte
movf TABLAT,W ;get it in W
call rs_send ;transmit it
fixhx2 movlw 0x0f ;mask out high nybble
andwf temp
movlw fhex ;point W to table start
addwf temp ;add offset
movff temp,TBLPTRL
tblrd * ;read the byte
movf TABLAT,W ;get it in W
call rs_send ;transmit it
return
Then this may help give you a clue where to go. Again it's for 8 bit, so you'll have to take it from here.Suraj143 said:Hi futz thanks for your idea I'll make a note on that BTW i have never done 18F yet.
I need 0-9 digits format no need hex.
;*********************************************************
;*fix - subroutine takes byte passed in W - splits it into
;*two ascii bytes in dec1 and dec2, representing decimal digits.
fix: movwf dec2 ;put number in dec2
clrf count ;count = 0
movlw 0x0a ;W = 10
tens: subwf dec2,F ;subtract 10 from number
btfsc STATUS,C ;check if result <10
goto again ;no, go again
movf count,W ;yes, put count in W
addlw 0x30 ;add $30 to make it an ASCII number
movwf dec1 ;and store it in dec1
movf dec2,W ;get remainder (2nd digit)
addlw 0x0a ;put the last subtract back
addlw 0x30 ;add $30 to make it ASCII
movwf dec2 ;store it back in dec2
return ;and return
again: incf count,F ;increment count
goto tens ;go again
;======= Bin2Dec10G.asm ============= Sep 04 =========
; Test of 10b binary to 4 digit conversion as
; based on division by powers of 10.
;
; E. A., Grens
;
; For most PICs - here for 16F628 with 4 MHz
; internal oscillator.
;
; Average processor cycles for execution of
; subroutine over the input range 0x000 to 0x3FF
; is 88. No variables required except the
; input blh, blo and the out BCD digits.
; Subroutine length 38.
;======================================================
list p=16f628
radix dec
#include
__config 0x3D30
;-------Set Up RAM Variables---------------------------
blo equ 0x20 ;lsbyte of 10b binary
bhi equ 0x21 ;msb
d4 equ 0x23 ;msdigit
d3 equ 0x24
d2 equ 0x25
d1 equ 0x26 ;lsd
;-------Program Code--------------------------------
org 0x00 ;Effective Reset Vector
;
nop
goto Start ;Jump by interrupt
;
Start
movlw 0x07
movwf CMCON ;Digital I/O
movlw 0x03 ;Test input
movwf bhi
movlw 0xFF
movwf blo
movlw 0x04
call Bin2decg
Hold
goto Hold ;Finished
Bin2decg ;10b binaey to BCD
clrf d1
clrf d2
clrf d3
clrf d4
clrc
rrf bhi,f ;N = 4*Q + R
rrf blo,f ;blo = Q
rrf d1,f ;d1 = R as temp, R25
goto B2d2 ;repeat
B2d3
addwf blo,f ;get remainder
; after /100, C = 0
rlf d1,f ;*4 and add R back in
rlf blo,f
rlf d1,f
rlf blo,f ;4*blo + R = N -
; 1000*d4 - 100*d3
movlw 10
B2d4
subwf blo,f ;blo = N - 1000*d4 -
; 100*d3 - 10*d2
skpc
goto B2d5 ;blo10
goto B2d4
B2d5
addwf blo,f ;put last 10 back, C=0
movf blo,w
movwf d1
return
end
It counts the number of times it can successfully subtract 10 from the value (the value is less than 10 at that point). The count (number of successful subtracts of 10) becomes the 10s digit.Suraj143 said:Hi pdfruth thanks for your excellent coding.For sure I'll work with that after futz coding.
@ futz
I'm dreaming why its subtracting 10.
Wrong! (I think)Suraj143 said:Hi futz I have small problem.
The CARRY bit will set when subtracting from smaller value.
Ex: 5-10 will set carry bit.
In my example 19-10 = 9 so the carry bit will CLEAR.
It will never goto increment count.
So the new result is
D1= 0
D2= 19
Please tell me am I right or wrong?
There it is. When borrowing it works the other way.C: Carry/borrow bit
For ADDWF, ADDLW, SUBLW, and SUBWF instructions
1 = A carry-out from the Most Significant bit of the result occurred
0 = No carry-out from the Most Significant bit of the result occurred
Note: For borrow, the polarity is reversed. A subtraction is executed by adding the two’s
complement of the second operand.
futz said:The count variable is the one to watch. It keeps track of the number of successful subtractions. Count is the value that becomes your tens digit, not dec1 or dec2.
Ah, excellent! I started writing a 16 bit converter last night. Ran out of time. Hadda sleep. I'm gonna finish mine tonight without cheating, and then look at what's probably a better algorithm at Nigel's site.Nigel Goodwin said:Check my analogue PIC tutorial, it includes excellent routines to convert the analogue readings to decimal and display them - I've used it for years (it came off the PICList originally) and it's always worked flawlessly.
blueroomelectronics said:I would think the DAW instruction might come in handy, not used it yet myself...
Start movf ADRESL,W ;move lower byte of AD to W
call BCD10
movf Digit2,W
call BCD100
movf Digit3,W
call BCD1000
goto Start
BCD10 clrf Digit2
movwf Digit1
Tens movlw .10
subwf Digit1,W
btfss STATAUS,c
goto DoneDigit2
movwf Digit1
incf Digit2,F
goto Tens
DoneDigit2 Return
BCD100 clrf Digit3
movwf Digit2
Hundreds movlw .10
subwf Digit2,W
btfss STATUS,C
goto DoneDigit3
movwf Digit2
incf Digit3,F
goto Hundreds
DoneDigit3 Return
BCD1000 clrf Digit4
movwf Digit3
Thousands movlw .10
subwf Digit3,W
btfss STATUS,C
goto DoneDigit4
movwf Digit3
incf Digit4,F
goto Thousands
DoneDigit4 Return