2

我正在为带有移位寄存器的 LED 矩阵项目编写 arduino,我必须旋转输出值(这是一个字节),但是当我使用“<<”运算符时,它不会正确旋转值,只是将零添加到 LSB。

byte ilk=0b01100001;
int latch=10;
int clock=8;
int data=9;
void setup(){
pinMode(latch,OUTPUT);
pinMode(data,OUTPUT);
pinMode(clock,OUTPUT);
}

void loop(){
  digitalWrite(latch,LOW);
  shiftOut(data,clock,MSBFIRST,ilk);
  digitalWrite(latch,HIGH);
  ilk=ilk<<1;
  delay(200);
}

我怎样才能以正确的方式做到这一点?有没有像 ROL 这样的操作员。

4

3 回答 3

4

因为<<不是“向左旋转”运算符。这是算术左移运算符。你可以使用类似的东西

uint32_t rotl(uint32_t n, uint32_n b)
{
    return (n << b) | (n >> (32 - b));
}

反而。如果您希望它与您使用的整数类型的大小无关,请写sizeof(n) * CHAR_BIT - b在按位 OR 运算符的右侧。

于 2013-05-28T19:06:49.577 回答
1

你也可以这样编码

uint16_t tmp = ilk << 1;
ilk = (uint8_t)tmp + *(((uint8_t *)(&tmp))+1);

这个想法是 &tmp 是一个指向 tmp 作为单词的指针。然后强制转换将其转换为字节指针。将此指针加 1 会将其向上移动一个字节。取消引用它会提供添加到 tmp 的 tmp 的高字节。然后将结果分配给 ilk 获取此操作的低字节。我没有仔细检查,但如果编译器足够聪明,它可以优化它以“将 tmp 的高字节添加到 tmp 并只取结果的低字节”。

或者您可以将其实现为

ilk = ilk << 1 + (ilk >= (1 << sizeof(ilk));

在你的情况下

ilk = ilk << 1 + (ilk >= 128);

请注意,我的两个解决方案都不需要编译器优化几位的移位。

于 2013-05-28T19:39:08.593 回答
-1

在我的脑海中,这应该可以工作,溢出位被丢弃

byte temp = ilk & 1;
ilk <<= 1;
ilk |= (temp >> sizeof(temp));
于 2013-05-28T19:07:58.953 回答