binary to bcd conversion

Go To Last Post
13 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

hi
does anyone know if theres a function in winavr for converting binary to bcd? i think ive looked thru almost the whole libc manual without finding anything (i doubt its in the parity section...). also looked thru the website best match i came up with was the math library in user projects, but thats written in assembly and i dont know how to deal with that in a C program .
thanks.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

let me re phrase:
is there a faster/ more elegant way of doing it than this.i care about speed more than code size.

int ones;
int tens;
int hundreds
int thousands;
int val;

thousands = val/1000;
if(val >= 1000)
val -=thousands*1000;
hundreds = val/100;
if(val >= 1000)
val -=hundreds*100;
tens = val/10;
ones = val%10;

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi twidget2,

A more elegant way of dealing with binairy to BCD conversion is by using the itoa() function in stdlib. That function returns the representation of the number as a chararray (string). When the function returns you might want to subtract the ascii "offset" 0x30 that leaves you with the BCD representation of the number.

Yet another approach is by using the div() function in for loop, that function returns the struct div_t (quotient and remainder from a division). Devide by 10, the remainder of the first division are the units, then divide the quotient by ten... repeat the loop until the quotient == 0.

HTH,
Koen.

Assumptio mater errorum est

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You could try this for v = 0..9999

unsigned short BIN2DEC(unsigned short v)
{
	unsigned short x = 0;
	unsigned char i = 0;
	do {
		x |= (v % 10) << i;
		v /= 10;
		i += 4;
	} while(i < 16);	
	return x;
}

C.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

thanks the itoa() should actualy work better since i was going to convert to ascii after that anyway. problem is the documentation in the libc manual is a bit over my head. can you give me an example on hox to use it. my value is somewhere between 0 and 500.think my problem may be that i dont understand pointer very well since i never had to use them in my c++ class let me see if i get this right

#include

int main(void)
{
int temp = 501;
char buff[4];
itoa(temp,buff,10);

at this point buff 0 = 1
buff 1 = 0
buff 2 = 5
and buff 3 = 0/ in ascii right ? or am i missing something

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

That is correct, if you don't care about codesize you can also use sprintf();

int main (void)
{
  char buffer[10];
  int value = 567;

  char length = sprintf (buffer, "%u", value);
}

HTH,
KK.

Assumptio mater errorum est

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Actually, I think it is buf[0] = '5', buf[1] = '0', buf[2] = '1', buf[3] = '\0';
Do you actually need the BCD value or just the ASCII result?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

the ascii result. i need the data in a form that i can send to a character lcd.also going to send it to the usart so that i can read it with hyperterminal and graph it in excel. the reason im looking for speed over code size is that the whole output section is going into an interrupt routine which cant take longer than 1/60th of a second at 13.5 MHz

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Oeps, yes avee is right.

Assumptio mater errorum est

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I'm sure itoa will satisfy your needs. I measured around 1000 cycles for a conversion and that wil take about 75 microseconds for your 13.5 MHz crystal. It is the UART speed you should take care of if you want less than 1/60 s
C.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

does the usart realy eat up that much time? what do pc rs232 ports generaly top out at? i used avr calc to figure out that if i want 0% error i should be transmitting at 31250baud or 62500 if i set the U2X bit. but i settled for 9600 at .44% error cause i didnt know how fast serial ports go... figure if worse comes to worse ill make the uart transmit routine interrupt driven.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

for example, at 9600 baud, you will get about 1 char/ms from the serial port. 17 chars will eat your 1/60 ms time. So look out for what you're actually sending out.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I just did what youre doing, and I can tell you that the RS232 is going to take the most time. I had a chip send 16 bits to a dac, another chip read the dac and clock in 10 bits back to the first chip, and then send 10 chars over uart. All the parts up to the uart was just a blip on the scope compared to the uart section.