# BCD to ASCII

Status
Not open for further replies.

#### tbr75

##### New Member
Hi, I'm using an 89c51cc03 atmel microcontroller to receive strings from a GPS and sending latitude and longitude to a 2x16 LCD screen. I am stuck on converting a number in BCD to ASCII to send to the screen. Here is what I have:

Code:
int ConvertToASCII(long BCD)
{int x,y,z;
x = BCD & 0x0F;
y = BCD & 0xF0;
y = y >> 4;
z = x + y;
z = z | 0x30;
return z;
}

My entire program is attached. Thanks for any help.
Trent

#### Attachments

6.2 KB · Views: 261

#### ericgibbs

##### Well-Known Member
Hi, I'm using an 89c51cc03 atmel microcontroller to receive strings from a GPS and sending latitude and longitude to a 2x16 LCD screen. I am stuck on converting a number in BCD to ASCII to send to the screen. Here is what I have:

Code:
int ConvertToASCII(long BCD)
{int x,y,z;
x = BCD & 0x0F;
y = BCD & 0xF0;
y = y >> 4;
z = x + y;
z = z | 0x30;
return z;
}

My entire program is attached. Thanks for any help.
Trent

hi,
Is the GPS string 'packed' BCD. ? eg: 98h representing '9' and '8'
Do you have an example of the 'raw' GPS data string that you could post.?

#### tbr75

##### New Member
I believe I currently have it in packed BCD, and need to take it to ASCII. Here is an example string coming from the GPS:

$GPGGA,111636.932,2447.0949,N,12100.5223,E,1,11,0.8,118.2,M,,,,0000*02<CR><LF> I also have another failed attempt at converting to ASCII, but I think it might be closer. Code: unsigned char ConvertToASCII(long BCD) {int i; unsigned char d; for(i=0;i<6;i++) {d[i] = BCD % 10; BCD = BCD/10; } BCD = 0; for(i=0;i<6;i++) {BCD = ((BCD + (d[i])*pow(10,i)) + 0x30); } return BCD; } I'll also show my ConvertToBCD subprogram my professor helped me with: Code: long ConvertToBCD(long avg) {int i; unsigned char d; for(i=0;i<6;i++) {d[i] = avg % 10; avg = avg/10; } avg = 0; for(i=0;i<6;i++) {avg = avg << 4; avg = avg | d[5-i]; } return avg; } Thanks. #### Attachments • NewestProject.txt 6.3 KB · Views: 177 #### ericgibbs ##### Well-Known Member Most Helpful Member hi, A$GPGGA string is ASCII, why do you want to convert in order to display it.???
NMEA data

extract:
Code:
[B]GGA[/B] - essential fix data which provide 3D location and accuracy data.
$GPGGA,123519,4807.038,N,01131.000,E,1,08,0.9,545.4,M,46.9,M,,*47 Where: GGA Global Positioning System Fix Data 123519 Fix taken at 12:35:19 UTC 4807.038,N Latitude 48 deg 07.038' N 01131.000,E Longitude 11 deg 31.000' E 1 Fix quality: 0 = invalid 1 = GPS fix (SPS) 2 = DGPS fix 3 = PPS fix 4 = Real Time Kinematic 5 = Float RTK 6 = estimated (dead reckoning) (2.3 feature) 7 = Manual input mode 8 = Simulation mode 08 Number of satellites being tracked 0.9 Horizontal dilution of position 545.4,M Altitude, Meters, above mean sea level 46.9,M Height of geoid (mean sea level) above WGS84 ellipsoid (empty field) time in seconds since last DGPS update (empty field) DGPS station ID number *47 the checksum data, always begins with * Last edited: #### ericgibbs ##### Well-Known Member Most Helpful Member hi, A$GPGGA string is ASCII, why do you want to convert in order to display it.???
NMEA data

extract:
Code:
[B]GGA[/B] - essential fix data which provide 3D location and accuracy data.
\$GPGGA,123519,4807.038,N,01131.000,E,1,08,0.9,545.4,M,46.9,M,,*47  Where:      GGA          Global Positioning System Fix Data      123519       Fix taken at 12:35:19 UTC      4807.038,N   Latitude 48 deg 07.038' N      01131.000,E  Longitude 11 deg 31.000' E      1            Fix quality: 0 = invalid                                1 = GPS fix (SPS)                                2 = DGPS fix                                3 = PPS fix 			       4 = Real Time Kinematic 			       5 = Float RTK                                6 = estimated (dead reckoning) (2.3 feature) 			       7 = Manual input mode 			       8 = Simulation mode      08           Number of satellites being tracked      0.9          Horizontal dilution of position      545.4,M      Altitude, Meters, above mean sea level      46.9,M       Height of geoid (mean sea level) above WGS84                       ellipsoid      (empty field) time in seconds since last DGPS update      (empty field) DGPS station ID number      *47          the checksum data, always begins with *

Sorry about the crap format, I tried various methods.................no luck!

#### tbr75

##### New Member
Sorry, I should have been more specific with what I'm doing. I am receiving the data from the GPS, storing the latitude and longitude, then I have two buttons. One of which saves your current location, another that calculates the distance between a new current location and the saved location. In order to do the calculation, it had to be in binary. Now I've got it back to BCD, but cannot figure out the ASCII conversion. I have yet another attempt:

Code:
ConvertToASCII(long BCD)
{unsigned char y = 0, i =0;
int x = 0;
long j = 1000000000;
if (BCD == 0)
SBUF = 0 | 0x30;
else
{
while(j != 0)
{x = BCD/j;
if(x == 0)
j = j/10;
if(x != 0 && x < 10)
{y = x | 0x30;
j = j/10;
distbuf[i] = y;
i++;
}
if(x > 9)
{x = (x%10) | 0x30;
j = j/10;
distbuf[i] = x;
i++;
}
}
SBUF = distbuf;
}
}

I have my program attached. My thought process on this is that I'm passing a long, so if I were to start by dividing by 1 trillion(max digits for a long is around 4.5 trillion I think) I would get the max digit from BCD. If it's zero it saves nothing. But as j decreases, once I finally get a number I add 30h and save it in distbuf. Then, once x is greater than 9, I start to mod it by 10 and take the last digit as j continues to decrease. Once again, I add 30h and then save it in distbuf. It worked on paper I guess, but it sure isn't working when I implement it.

#### Attachments

6.6 KB · Views: 208

#### BrownOut

##### Banned
Well, first of all, you're dividing a number stored in binary form by a decimal number to try to isolate each nibble, but decimal and binary don't mix. For example, if you had a 32-bit number 0xFFFFFFFF, and you divided it by 0x10000000, you'd get 0xF. But by dividing it by 10000000, you get 1AD, which is wrong. Same for BCD stored in long integers. Also, you're dividing the same number by progressively smaller numbers, hoping to get descending nibbles, but you're gonna end up with larger results. ie, when you divide 0x98xxxxxx by 0x10000000, you get 0x9. Then when you divide the same number by 0x1000000, you get 0x98, whereas you only wanted 0x8. It would be better to work from least significant nibble to most, and use the results from each division for the next iteration. Ie, start by dividing by 0x10 to get the lowest nibble (take the remainder), then divide that result by 0x10 again, and so on...

Last edited:

#### birdman0_o

##### Active Member
If it is still relevant, the ASCII chart is isomorphic. To map the BCD integers onto the ASCII table simply add .48 or 0x30. Simple!

Status
Not open for further replies.

Replies
4
Views
17K
Replies
1
Views
2K
Replies
3
Views
2K
Replies
18
Views
2K
Replies
1
Views
4K 