16bit to BCD Conversion
Straightforward BCD conversion example, based on the double dabble scheme. A 16bit unsigned integer is split into BCD segments represented by an array of 5 unsigned 8 bit integers.
Surprisingly, the sprintf function included with the COSMIC compiler cannot handle 8 bit unsigned integers, so here another 16 bit temporary variable is used when outputting the numbers.
Below is also a version for when you want the BCDs in the other direction. Useful for 7 segment displays.
Normal order
Normal order
void bcdconv(void)
{
u8 bcd[5]={0,0,0,0,0};
u16 number=15; u8 curBit=0;u16 result=0;
u8 i=0;u8 j=0;
for (i=0;i<16 ; i++){
//Check for BCDs that are >4
for (j=0;j<5;j++){
if (bcd[j]>4){
bcd[j] = bcd[j]+3;
}
}
//Check if bits need to be carried over
for (j=0;j<4;j++){
if ((bcd[j] & 0b11110000)>=16){
bcd[j+1] = bcd[j+1]+1;
}
}
//Now do left shift of all BCDs
for (j=0;j<5;j++){
bcd[j] = bcd[j]<<1;
}
//Check if bits need to be carried over to next bcd segment
for (j=0;j<4;j++){
if ((bcd[j] & 0b11110000)>=0b00010000){
bcd[j+1] = bcd[j+1]+1;//Move bit
bcd[j] &= 0b00001111;//Remove 'illegal' bits
}
}
//Select next bit from number to shift in
curBit = extractBit(number, 15-i);
//Input new bit to the right of first BCD
bcd[0] |= curBit;
}
j=0;
for (j=0;j<5;j++){
result = bcd[j];
sprintf(str, "%u", result);
SerialPutString(str);
SerialPutString("\r\n");
}
}
u8 extractBit(u16 value, u8 pos) {
return (value >> pos) & 0x01;
}
Inverted BCD order
Inverted BCD order
void bcdconv(u16 number){
u8 curBit=0;
s8 i=0;s8 j=0;
//Clear bcd
bcd[0]=0;bcd[1]=0;bcd[2]=0;bcd[3]=0;bcd[4]=0;bcd[5]=0;
for (i=0;i<16 ; i++){
//Check for BCDs that are >4
for (j=4;j>=0;j--){
if (bcd[j]>4){
bcd[j] = bcd[j]+3;
}
}
//Check if bits need to be carried over
for (j=4;j>0;j--){
if ((bcd[j] & 0b11110000)>=16){
bcd[j-1] = bcd[j-1]+1;
}
}
//Now do left shift of all BCDs
for (j=4;j>=0;j--){
bcd[j] = bcd[j]<<1;
}
//Check if bits need to be carried over to next bcd segment
for (j=4;j>0;j--){
if ((bcd[j] & 0b11110000)>=0b00010000){
bcd[j-1] = bcd[j-1]+1;//Move bit
bcd[j] &= 0b00001111;//Remove 'illegal' bits
}
}
//Select next bit from number to shift in
curBit = extractBit(number, 15-i);
//Input new bit to the right of first BCD
bcd[4] |= curBit;
}
}
u8 extractBit(u16 value, u8 pos) {
return (value >> pos) & 0x01;
}