0

マイクロコントローラから 2 つのレジスタを読み取っています。1 つは 4 ビットの MSB (最初の 4 ビットには他のものがあります) と別の 8 ビットの LSB があります。それを1つの12ビット単位(正確には16ビット)に変換したい。これまでのところ、私はそのようにしました:

UINT16 x;
UINT8 RegValue = 0;
UINT8 RegValue1 = 0;

ReadRegister(Register01, &RegValue1);
ReadRegister(Register02, &RegValue2);

x = RegValue1 & 0x000F;
x  = x << 8;
x = x | RegValue2 & 0x00FF;

それを行うより良い方法はありますか?

/ *より正確には、ReadRegister は別の ADC への I2C 通信です。Register01 と Register02 は異なるアドレスです。RegValue1 は 8 ビットですが、4 つの LSB だけが必要で、RegValue に連結されます (RegValue1 の 4-LSB と RegValue のすべての 8 ビット)。*/

4

3 に答える 3

2

マシンのエンディアンがわかっている場合は、次のxようにバイトを直接読み取ることができます。

ReadRegister(Register01, (UINT8*)&x + 1);
ReadRegister(Register02, (UINT8*)&x);
x &= 0xfff;

これは移植性がなく、パフォーマンスの向上 (あるとしても) はおそらく小さいことに注意してください。

于 2012-06-04T09:06:49.843 に答える
0

RegValue & 0x00FFRegValue はすでに 8 ビットであるため、マスクは不要です。

3 つのステートメントに分割するとわかりやすくなりますが、この式はおそらく 1 つのステートメントで実装できるほど単純です。

x = ((RegValue1 & 0x0Fu) << 8u) | RegValue ;

符号なしリテラル (0x0Fu) を使用してもほとんど違いはありませんが、符号なし 8 ビット データを扱っていることが強調されます。これは実際にはunsigned int2 桁しかない偶数ですが、これはおそらく 8 ビットしか扱っておらず、セマンティックではなく純粋に文体的なものであることを読者に強調しています。C には 8 ビットのリテラル定数型はありません (ただし、C++'\x0f'には type がありcharます)。次のように、より良い型一致を強制できます。

#define LS4BITMASK ((UINT8)0x0fu)

x = ((RegValue1 & LS4BITMASK) << 8u) | RegValue ;

マクロは、式の繰り返しや混乱を避けるだけです。

上記のいずれも、パフォーマンスまたは実際に生成されたコードの点で、必ずしも元のコードよりも「優れている」とは限りません。これは、主に好みの問題、またはローカルのコーディング標準または慣行の問題です。

于 2012-06-04T10:04:16.483 に答える
0

レジスタが互いに隣接している場合、ターゲットのエンディアンに関して正しい順序になっている可能性が最も高くなります。その場合、それらは単一の 16 ビット レジスタとして読み取られ、それに応じてマスクされRegister01ます。これが下位アドレス値であると仮定します。

ReadRegister16(Register01, &x ) ;
x &= 0x0fffu ;

もちろん、私はここでReadRegister16()関数を発明しましたが、レジスタがメモリにマップされていて、Register01単なるアドレスである場合、これは単純に次のようになります。

UINT16 x = *Register01 ;
x &= 0x0fffu ;
于 2012-06-04T10:12:03.687 に答える