C中的位设置逻辑

时间:2016-07-28 17:47:45

标签: c arduino logic bit

我很难理解在32位寄存器中成功设置位的逻辑。这是函数的伪代码:

阅读主寄存器,
如果未设置第29位CREG_CLK_CTRL_I2C0,请将其设置为

uint32_t creg;

//read the CREG Master register   
creg = READ_ARC_REG((volatile uint32_t)AR_IO_CREG_MST0_CTRL);

if((creg & (1 << CREG_CLK_CTRL_I2C0)) == 0){
     creg |= ( 1 << CREG_CLK_CTRL_I2C0);
     WRITE_ARC_REG(creg, (volatile uint32_t)(AR_IO_CREG_MST0_CTRL));
}

如果CREG主寄存器最初为空,则逻辑不按预期工作。但是,如果我用全零填充它并且在第31位(1000 ... 0)中填充1,则逻辑确实有效。我不确定我的测试条件是否不正确或是否可能是其他原因。

有人可以帮忙吗?

3 个答案:

答案 0 :(得分:3)

就个人而言,我会使用给定的数据类型:uint32_t。无论上下文如何,这都将保证对齐。那是(为了清晰起见而考虑因素,假设转移不会产生不同的大小类型)

uint32_t mask = ((uint32_t)1) << CREG_CLK_CTRL_I2C0;
if((creg & mask) == 0){
     creg |= mask;
     WRITE_ARC_REG(creg, (volatile uint32_t)(AR_IO_CREG_MST0_CTRL));
}

答案 1 :(得分:1)

以下是调试问题的一些想法:

步骤1:确保您真正理解该寄存器的工作原理。请记住,微控制器寄存器的行为可能与内存不同。在满足某些其他条件之前,寄存器可能会忽略您尝试将1写入某个位。也许这就是为什么如果你先写一个1到第31位,它的工作原理。第31位有什么作用?

第2步:我在线搜索,发现定义READ_ARC_REG()WRITE_ARC_REG()的标题也可能包含SET_ARC_BIT()的定义。看看你是否能找到并使用它。

第3步:确保您尝试撰写的内容有意义。在调试器中逐步执行该功能和/或添加某种形式的打印输出,以显示您尝试写入寄存器的值。然后在执行此操作后读取寄存器并重复该过程。看看你是否尝试写入正确的值,然后查看该写入是否实际。如果您的代码试图将您想要的值写入寄存器,但随后的读取显示您的写入没有更改位,则返回上面的步骤1.

答案 2 :(得分:0)

只是一个猜测(我不做很多嵌入式编程),但根据C标准,数字1的类型为int。在嵌入式编程中,int可以是16位,在这种情况下,左移将具有未定义的行为,因为右操作数太大。

因此,请尝试使用1L来生成long类型。

另外,正如Olaf在评论中所提到的,除非您确定需要,否则不要使用(volatile uint32_t)演员表。一些谷歌搜索表明这是关于Arduino 101,source code我发现确实使用了READ_ARC_REGWRITE_ARC_REG而没有任何演员。

creg = READ_ARC_REG(AR_IO_CREG_MST0_CTRL);

if((creg & (1L << CREG_CLK_CTRL_I2C0)) == 0){
     creg |= (1L << CREG_CLK_CTRL_I2C0);
     WRITE_ARC_REG(creg, AR_IO_CREG_MST0_CTRL);
}
相关问题