![]() | ![]() | ![]() |
| |||||||
| Micro Controllers Discuss all aspects of micro controllers - building them, coding them, etc. All controllers are welcome - PIC, BASIC, Z8 Encore!, etc. |
![]() |
| | Tools |
| | #1 |
|
I posted a long time ago about the DS1820 sensors, I could never get the timing right so gave up on them. I managed to get the things to respond this time around though, and have been firing the byte that comes from the DS1820 into the serial port of my pc so I can see it on hyperterminal. A problem has arisen when trying to convert the byte given by the sensor into ascii characters to send back to the PC. For now I have been rotating right to cut off the bit that represents .5 for simplicity, but I still can't get my head around how to do it. I've been trying to convert to BCD, then adding 30h to each nibble to convert the ascii character. I can find loads of code, but nothing that actually explains how to do it, I find reading other people's assembly really hard for some reason (unless commented well). I'll try and explain the way I have been doing it. I've got a loop with a count (starting at 8 ), and bit 0 is tested. If it is set, subroutines are called with data tables that contain the amount of ones and the amount of tens for the value of that bit. I.e. 1 in the tens table and 6 in the ones table for bit 4, then I use the wcount value to jump to the appropriate position in the table, and add up all the ones and all the tens in the byte. Code: ADDONES
movf WCOUNT,W
addwf PCL,F
dt 8,4,2,6,8,4,2,1 ; amount of ones for each bit value (backwards)
; 1,2,4,8,16,32,64,128
ADDTENS
movf WCOUNT,W
addwf PCL,F
dt 2,6,3,1,0,0,0,0 ; amount of tens for each bit value (backwards)
BTOBCD
movlw 0x08
movwf WCOUNT ; Move 8 into wcount to limit the amount of times we go round
movlw 0x00
BTOBCDL
btfsc BCDTEMP,0 ; Test bit in BCDTEMP
call ADDONES ; if it is set, go to the addones thing and get the amount of ones
addwf BCDONES,F ; add the returned table value to the bcdones reg
movlw 0x00
btfsc BCDTEMP,0 ; do the same for the tens
call ADDTENS
addwf BCDTENS,F
movlw 0x00
rrf BCDTEMP,1 ; rotate bcdtemp right one, chop off the bit we've done
decfsz WCOUNT,1 ; decrement wcount, so that a different table value is returned
goto BTOBCDL ; if not 0 all bits not done so go back
movf BCDONES,W
movwf TEMP
movlw 0x0A ; subtract 10 from bcdones, if it goes negative don't increment
subwf BCDONES,F
btfss STATUS,C
incf BCDTENS
btfss STATUS,C ;
clrf BCDONES
movlw 0x30 ; add 30h to each register to turn it into ascii
addwf BCDONES,F
movlw 0x30
addwf BCDTENS,F
return
Hope I have provided enough info for some help, as I am really running out of ideas! If my idea of doing it is complete and utter rubbish let me know! Thanks.
__________________ LCDGallery | |
| |
| | #2 |
|
You've not made yourself very clear?. I'm not sure what you actually want to send to the PC?. Are you wanting to send decimal values?, in which case why mention binary at all?. Or do you want to send binary?. Obviously in either case you need to send it as a series of ASCII characters that will display on the PC under Hyperterminal (or similar). So assuming it's an eight bit value, and as high as possible, do you want to send it as: Decimal: '255' Binary: '11111111' Hexadecimal: 'FF' There are routines in my tutorials for both decimal and hex, and binary is very trivial to do. | |
| |
| | #3 |
|
I mean that I want to send the ascii characters that represent the binary value, i.e. 2 and 1 for 00010101. I can send a string of 1s and 0s fine, just can't convert. Say I get 00010001 from the temperature sensor, I want to send this to the pc as the ascii characters 1 and 7, and i'm having a hard time getting to ascii characters from the binary value.
__________________ LCDGallery | |
| |
| | #4 |
|
I've seen this happen a few times; people get confused between the number systems and how it all works. Okay, so you're reading a value from your sensor and you want to see that value in Hyperterminal, right? Some things that you need to understand first... Terminal programs only deal with one byte at a time. And the data sent/received is in binary. If you send the value 48 to Hyperterminal you don't get to see "48" on the screen, because terminal programs convert the binary numbers to ASCII and the value 48 in ASCII is the character "0". To see the value "48" on the screen you have to send two separate bytes: 52 and 56. (ASCII codes are here: www.asciitable.com) So first ask yourself how the value is coming from the sensor. Is it a single byte having the range 0-255? Or is it a multiple byte value where each byte contains a decimal place? Let's work through each case. Your situation may be neither of these, but this will give you an idea how things work. If the value coming from the sensor is a single binary value in the range 0-255 and you want to see this exact number in Hyperterminal then you need to do some conversion. You want to break apart the value into three separate values (one for each digit), convert that to its ASCII character, and send it. So if the sensor value is 48 then you want to divide this by 100 (ignoring any remainder) and you have your first digit (in this case, 0). Multiply this number by 100 and subtract from the original number, then divide by 10 and you have the second digit. Multiply this by 10 and subtract from the previous iteration and you have the final digit. It'll look like this: value = 48 firstdigit = value / 100 value = value - firstdigit*100 seconddigit = value / 10 value = value - seconddigit*10 thirddigit = value You now have: firstdigit = 0 seconddigit = 4 thirdigit = 8 But if you send these to Hyperterminal you will only see the ASCII characters of those values. Since zero is ASCII 48 you just add 48 to each digit and then send them. The second case - reading each decimal digit from the sensor - is even easier and you'll already know by the first example how to do it. Mike | |
| |
| | #5 | |
|
I'm competent with the number systems and how it works, I can make whatever I want appear how I want it on hyperterminal, the only problem i'm having is converting the data from the sensor to something that I want. Quote:
Thanks very much for your help!
__________________ LCDGallery | ||
| |
| | #6 | |
| Quote:
The following should achieve that. Code: WriteDecimal clrf Decimal10 Count10s incf Decimal10,F addlw 0f6h; -10 btfsc STATUS,C goto Count10s movwf Units movfw Decimal10 addlw 2fh call SendByte movfw Units addlw 30h+0ah SendByte Note that the code calls sendbyte to send the 10s part and then "follows through" to send the units part. Therefore your send to PC routine should start where the SendByte label is. HTH Mike. | ||
| |
| | #7 |
|
Iy you need the hundreds bit as well, then Code: WriteDecimal clrf Decimal100
Count100s incf Decimal100,F
addlw 100h-100; -100
btfsc STATUS,C
goto Count100s
addlw 100
clrf Decimal10
Count10s incf Decimal10,F
addlw 0f6h; -10
btfsc STATUS,C
goto Count10s
movwf Units
movfw Decimal100
addlw 2fh
call SendByte
movfw Decimal10
addlw 2fh
call SendByte
movfw Units
addlw 30h+0ah
SendByte
| |
| |
| | #8 | |
| Quote:
But having read the follow up posts, it's clear you want to display the DECIMAL value of the number. There are plenty of routines you can use to do this, my tutorials include the one that I use - it's a 16 bit routine, but you can just zero the upper byte. Calling the routine converts the original binary/hexadecimal number into seperate decimal digits in five GPR's, ones, tens, hundreds etc. You would only need to use the values in the bottom three, then simply convert then to ASCII and send them out the serial port. Check my analogue tutorials and serial tutorials (and for that matter LCD tutorials) all of which do almost exactly what you need. | ||
| |
| | #9 | |
| Quote:
__________________ LCDGallery | ||
| |
| | #10 |
|
Pommie: That little code snippet works perfectly, thanks very much! No idea why I didn't think of doing it like that. It's like what I had written but a much simpler version. Thanks again for everyones help.
__________________ LCDGallery | |
| |
|
| Tags |
| ascii, binary, convert |
| Thread Tools | |
| Display Modes | |
| |