简体   繁体   中英

transfer 16 bit pattern into another register by left shifting

I'm in the way to implement double dabble algorithm in C to perform binary to BCD notation. I'm using a pic16f876a. I'm not sure, but i guess there's no default operation to do this, so i want to transfer/left shift one bit at a time from the original register to another in this fashion:

0000 0000 0000   11110011   Initialization
0000 0000 0001   11100110  < Left Shift
0000 0000 0011   11001100   <Left Shift
0000 0000 0111   10011000  < Left Shift
add 3 to nibble with 7/111 result ...

I will start by creating 16bits register should i mask the original number's MSB and place it on LSB of the other register? and then lef shift original register?

And eventually get to his final BCD result

       BCD          (Binary)
100s Tens Ones    Original 
0010 0100 0011   11110011

I don't know how to drag every individual bit Also i know i'll have to add 3 when nibble is greater than 4, but maybe masking will do the job.I'll be displaying four digits in 7 segment display from 0000 to 3000 i'll be getting from multiplying 16bit resgiter for a constant to get a maximum of 3000 when register is 1111 1111 1111 1111.

thanks in advice

Here is a simple solution. The main() displays the result in hexadecimal (which must correspond to the initial decimal integer).

NB: you can replace all unsigned by any unsigned integer type. For instance by uint16_t for a 16 bits integer (don't forget #include <stdint.h> )

#include <stdio.h>

unsigned double_dabble(unsigned x) {
  unsigned r = 0, mask, d;
  int k = 0, nibbles, n, bit;

  for(mask = 1 << (sizeof(x) * 8 - 1); mask; mask >>= 1) {
    nibbles = (++k + 3) / 4;
    for(n = 0; n < nibbles; n++) {
      d = r & (0b1111 << (n * 4));
      if (d > (4 << (n * 4)))
        r += 3 << (n * 4);
    }
    bit = ((x & mask) != 0);
    r = (r << 1) | bit;

  }
  return r;
}

int main() {
  unsigned x = 0b11110011; // 423
  printf("x: %d -> BCD: %x\n", x, double_dabble(x));
}

Alternatively here is a simple way to convert an integer to BCD (not using the double dabble algorithm). It uses sprintf+strtod:

unsigned to_BCD(unsigned x) {
  char s[20]; // enough even for 64-bits integers !
  sprintf(s, "0x%u", x);
  return (unsigned) strtod(s, NULL); 
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM