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

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

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;
}