简体   繁体   English

在8位寄存器的中间存储4位值

[英]Storing a 4-bit value in the middle of an 8-bit register

I need to count from 0 to 10 and store those values in binary format in ADCON0(5:2). 我需要从0到10进行计数,并将这些值以二进制格式存储在ADCON0(5:2)中。 How do I point at bit 5 of this register? 我如何指向该寄存器的第5位? Bit 5 is named ADCON0bits.CHS3. 位5名为ADCON0bits.CHS3。 If I store a 4 bit variable to ADCON0bits.CHS3, will bits 1 - 3 be written to bits 4 - 2 of the register? 如果我将4位变量存储到ADCON0bits.CHS3,是否会将位1-3写入寄存器的位4-2?

Also, are there any 4 bit data types that I could use? 另外,我可以使用任何4位数据类型吗?

This is all on a PIC microcontroller. 所有这些都在PIC微控制器上。

Edit: I need to store 4 bits in the register like so: 编辑:我需要在寄存器中存储4位,如下所示:

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

This is in line with what was assumed below, but I figured I would clear up my question a bit. 这与下面的假设一致,但我认为我会稍微澄清一下我的问题。

When you say you are writing bits 1-3 of your count into positions 4-2 of your register, do you explicitly mean you are reversing the order of the bits? 当您说要将计数的1-3位写入寄存器的位置4-2时,您是否明确表示要反转这些位的顺序? In this answer I will presume that that was not what you meant. 在这个答案中,我认为那不是您的意思。

You can express a bit field explicitly as a struct . 您可以将位字段明确表示为struct Presuming that you are dealing with a 16 bit register, your struct could look something like this: 假设您要处理一个16位寄存器,则您的结构可能看起来像这样:

struct adcon {
    unsigned char someflag    : 2;
    unsigned char count       : 4;
    unsigned char other_bits  : 2;
}; 
With each struct member, you specify the number of bits. 对于每个结构成员,您可以指定位数。 Then you can operate on the appropriate bits in the register by casting the register to the struct type, and operating on the members of the struct. 然后,您可以通过将寄存器强制转换为结构类型并在结构的成员上进行操作来对寄存器中的相应位进行操作。

 (adcon) ADCON0.count = count; 

Edit: fixed up the code based on feedback, thanks. 编辑:修正了基于反馈的代码,谢谢。

Writing to a bit variable stores the truth value of that variable to the bit. 写入位变量会将变量的真值存储到位。 For example, writing: 例如,编写:

ADCON0bits.CHS3 = 3;

will set that bit to 1. 将该位设置为1。

If bit5 refers to the bit masked by 0x20 (00100000) and you need to store the 4 bit number in bits masked 0x3c (00111100) then you can use bit shifts and bitwise operations: 如果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

update : As mentioned by Ian in the comments. 更新 :正如伊恩在评论中提到的。 This sets ADCON0 to an intermediate value before updating. 这会将ADCON0设置为更新前的中间值。 In this case it is OK since it is only selecting the A/D channel and not actually executing the conversion. 在这种情况下可以,因为它只是选择A / D通道,而不实际执行转换。 But in general it's better to do: 但总的来说,最好这样做:

unsigned char temp_adcon;

temp_adcon = ADCON0 & ~0x3c;
ADCON0 = temp_adcon | (count << 2);

See the answers for this SO question . 请参阅此SO问题的答案。

Note that you are doing a read-modify-write operation. 请注意,您正在执行读-修改-写操作。 You have to be careful of race conditions when doing this. 在执行此操作时,必须注意比赛条件。 Race conditions may be caused by: 比赛条件可能是由于以下原因引起的:

  • The hardware itself changing bits in the register (eg A/D converter operation completes and sets flags). 硬件本身更改寄存器中的位(例如,A / D转换器操作完成并设置标志)。 The design of the hardware should provide a means for you to avoid this problem—there are several possible solutions—read the manual for the micro/peripheral to find out. 硬件的设计应为您提供一种避免此问题的方法(有几种可能的解决方案),请阅读微控制器/外围设备的手册以进行查找。
  • Your own interrupt routine(s) also writing to the register. 您自己的中断例程也会写入寄存器。 If so, when your main (non-interrupt) code writes to the register, it should be done within an "interrupts disabled" context. 如果是这样,当您的主要(非中断)代码写入寄存器时,应在“禁止中断”上下文中完成。

I'm not sure about the exact register ADCON0, but often you can read the register, mask the 4 bits and insert your count and then use that value to write back to the register. 我不确定确切的寄存器ADCON0,但是通常您可以读取该寄存器,屏蔽这4位并插入计数,然后使用该值写回该寄存器。

Just in case, masking is performed with an AND operation and inserting is an OR operation with the count shift over 2 bits in your case. 以防万一,屏蔽是通过AND操作执行的,而插入操作是OR操作,您的情况需要将计数移位2位。

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

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