1

我需要从 0 数到 10 并将这些值以二进制格式存储在 ADCON0(5:2) 中。我如何指向该寄存器的第 5 位?位 5 命名为 ADCON0bits.CHS3。如果我将一个 4 位变量存储到 ADCON0bits.CHS3,位 1 - 3 是否会写入寄存器的位 4 - 2?

另外,我可以使用任何 4 位数据类型吗?

这一切都在 PIC 微控制器上。

编辑:我需要在寄存器中存储 4 位,如下所示:

unsigned char count = 10 //max value
[X][X][1][0][1][0][X][X]

这与下面的假设一致,但我想我会稍微澄清一下我的问题。

4

4 回答 4

4

当您说您将计数的第 1-3 位写入寄存器的第 4-2 位时,您是否明确表示您正在颠倒这些位的顺序?在这个答案中,我假设那不是你的意思。

您可以将位字段显式表示为 struct。假设您正在处理一个 16 位寄存器,您的结构可能看起来像这样:

struct adcon {
    unsigned char someflag    : 2;
    unsigned char count       : 4;
    unsigned char other_bits  : 2;
}; 
对于每个结构成员,您可以指定位数。然后,您可以通过将寄存器转换为结构类型来对寄存器中的适当位进行操作,并对结构的成员进行操作。

(adcon) ADCON0.count = count;

编辑:根据反馈修复代码,谢谢。

于 2010-01-18T03:51:31.437 回答
3

写入位变量将该变量的真值存储到该位。例如,写作:

ADCON0bits.CHS3 = 3;

将该位设置为 1。

如果 bit5 指的是被 0x20 (00100000) 掩码的位,并且您需要将 4 位数存储在掩码为 0x3c (00111100) 的位中,那么您可以使用位移位和按位运算:

// First clear bits 1-5:
ADCON0 &= ~0x3c;

// Now set the bits to correct value:
ADCON0 |= (count << 2); // <-- remember to shift 2 bits to the left

更新:正如 Ian 在评论中提到的那样。这会将 ADCON0 设置为更新前的中间值。在这种情况下是可以的,因为它只是选择 A/D 通道而不实际执行转换。但总的来说,最好这样做:

unsigned char temp_adcon;

temp_adcon = ADCON0 & ~0x3c;
ADCON0 = temp_adcon | (count << 2);
于 2010-01-18T03:10:26.253 回答
2

请参阅此 SO question的答案。

请注意,您正在执行读取-修改-写入操作。执行此操作时必须小心竞争条件。竞态条件可能由以下原因引起:

  • 硬件本身改变寄存器中的位(例如,A/D 转换器操作完成并设置标志)。硬件的设计应该为您提供一种避免这个问题的方法——有几种可能的解决方案——阅读微/外围设备的手册来找出答案。
  • 您自己的中断例程也写入寄存器。如果是这样,当您的主(非中断)代码写入寄存器时,应该在“中断禁用”上下文中完成。
于 2010-01-18T03:21:23.497 回答
1

我不确定确切的寄存器 ADCON0,但通常您可以读取寄存器,屏蔽 4 位并插入您的计数,然后使用该值写回寄存器。

以防万一,屏蔽是使用 AND 操作执行的,插入是 OR 操作,在您的情况下计数移位超过 2 位。

于 2010-01-18T03:04:37.607 回答