简体   繁体   English

通过左移将 16 位模式转移到另一个寄存器

[英]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.我打算在 C 中实现双 dabble 算法以执行二进制到 BCD 表示法。 I'm using a pic16f876a.我正在使用 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?我将从创建 16 位寄存器开始,我应该屏蔽原始数字的 MSB 并将其放在另一个寄存器的 LSB 上吗? and then lef shift original register?然后左移原始寄存器?

And eventually get to his final BCD result并最终得到他最终的 BCD 结果

       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.我不知道如何拖动每个单独的位我也知道当半字节大于 4 时我必须添加 3,但也许掩码可以完成这项工作。我将在 7 段显示中显示从 0000 到的四位数字当寄存器为 1111 1111 1111 1111 时,我将通过将 16 位 resgiter 乘以一个常数来获得 3000 的最大值,从而获得 3000。

thanks in advice感谢您的建议

Here is a simple solution.这是一个简单的解决方案。 The main() displays the result in hexadecimal (which must correspond to the initial decimal integer). main()以十六进制显示结果(必须对应于初始十进制整数)。

NB: you can replace all unsigned by any unsigned integer type.注意:您可以用任何未签名的 integer 类型替换所有unsigned的。 For instance by uint16_t for a 16 bits integer (don't forget #include <stdint.h> )例如uint16_t用于 16 位 integer (不要忘记#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).或者,这里是将 integer 转换为 BCD 的简单方法(不使用双涉算法)。 It uses sprintf+strtod:它使用 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); 
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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