ポートを設定するのになぜ人々は(1 << PA0)を使うのですか?

AVRチュートリアルで私はよく見ます:

DDRA |= (1 << PA0);
PORTA |= (1 << PA0);

代わりに使用されます。

DDRA |= PA0;
PORTA |= PA0;

これの目的は何ですか?

6
nl ru de
PA0がビット番号(0から31など)を指定している場合、(1 << PA0)はそのビットが設定されているビットマスクまたはビットフィールドを表します。
追加された 著者 Bevan,
AVRについてはあまり知りませんが、(1 << 2)は2と同じではありません。
追加された 著者 Cameron,
アセンブラではビット設定命令を直接使用しますが、Adaではいくつかの選択肢があります。1つは、ブール値の配列の1つのメンバにTrueまたはFalseを割り当てることです。 PortA( PAO):= True;
追加された 著者 jumojer,
余談ですが、AVR Cでは、通常は _BV()マクロを使用して「ビット値」を取得することもできます(例: PORTA | = _BV(PA0); 。個人的にはコードが読みやすくなると思いますが、コミュニティでは意見がかなり異なります。
追加された 著者 Vicente Adolfo Bolea Sánchez,
Ada再:Cにもビットフィールドがあります。
追加された 著者 Drake Clarris,
あなたはビット演算子を理解していないようです。これが私が使ったものです:ビット操作それは基本から始まり、必要とされる限り行きます。
追加された 著者 Robert Calhoun,

4 答え

PA0 will be defined as 0 so the following line:

DDRA |= (1 << PA0);

最初のビットを設定するために値1とORを残して、1を0だけ左にシフトすることと同じです。次の行は:

 DDRA |= PA0;

ゼロでORを実行しているので、レジスタはまったく変更されません。

16
追加された
@ corsiKa:読みやすく、理解しやすいものです。 (1 << PA3);
追加された 著者 Oluwatoni,
@corsiKaは1ビットしか設定していなくても、 | =(1 << 7)よりも | = 128 のほうが意味があります。 128のような値を見たときに7番目のビットが設定されることをどのようにして知っていますか?
追加された 著者 Michael Wehar,
それはなぜ彼らが DDRA | = 1 を使わないのか不思議に思います。彼らは PA0 が異なる環境で変わることを期待していますか?
追加された 著者 ohlemacher,
ああ、パターンに他のビットがあります。ゴッチャいや、私はそれが好きです。
追加された 著者 ohlemacher,
@ LưuVµnhPhúcもちろん違います。しかし、そのフレームワークを使用しない人にとって、一見して「ちょっとした設定」を気にかけているのかどうかは明らかではないので、私が尋ねたのはなぜですか。 PA0 は、実際に何をしているのかを説明するものではありません。
追加された 著者 ohlemacher,

なぜ彼らはこれをするのですか?おそらく、他の誰もが助けを求めたり学んだりしたからです。そして、標準の定義が奇妙に行われているからです。

Shifting by a number, typically a decimal number, will move that value over by that many binary positions. 1 << PA0 will shift 1 by PA0 to the left. Since PA0 is 0, there is no shift. But given 1 << 6 1 will become 0b1000000. Given13 << 6, it will shift 13, in binary which is 0b1101, over by 6 to become 0b1101000000 or 832.

それでは、PA0 - PA7が何として定義されているのかを確認する必要があります。これらは通常、io.hまたはportpins.hに含まれる、特定のマイクロコントローラ用の特定のヘッダーで定義されています。

#define     PA7   7
#define     PA6   6
~
#define     PA1   1
#define     PA0   0

それらは、10進数で、それらの数値位置として定義されています。

これらはシングルビットではないため、ビットとして直接割り当てることはできません。

PORTAが0b00000000(すべてオフ)であると仮定して PORTA | = PA7; を実行すると、

PORTA = PORTA | PA7; または PORTA = 0 | 7; または PORTA = 0 | 0b111

See the problem? You just turned on PA0, PA1, PA2, instead of PA7.

But PORTA |= (1 << PA7); works as you expect.

PORTA = PORTA | (1 << PA7); or PORTA = 0 | (1 << 7); or PORTA = 0 | 0b10000000;


よりスマートな方法

もう1つの優れたマイクロコントローラであるMSP430は、次のように標準のビットを定義しています。

#define BIT0                (0x0001)
#define BIT1                (0x0002)
~
#define BIT6                (0x0040)
#define BIT7                (0x0080)

これらは16進数でそれらの2進位置として定義されています。 BIT0は0であるPA0とは異なり、0b0001です。BIT7は0b111であるPA7とは異なり、0b10000000です。

So direct assignments like P1OUT |= BIT7; will work the same as P1OUT |= (1 << 7); would.

7
追加された

あなたの質問はすでに答えられていますが、私はもう少しコメントのための代替案を提示したいと思います。埋め込みプロジェクトを開始するときに最初にすることの1つは、ビットセットを定義してマクロをクリアすることです。

#define bitset(var,bitno) ((var) |= 1 << (bitno))
#define bitclr(var,bitno) ((var) &= ~(1 << (bitno)))

マクロを使用すると、コードは次のようになります。

bitset(DDRA,0);
bitset(PORTA,0);

最終結果は、アセンブリ内のビットセット命令です。

3
追加された
2番目の例ではなく、2番目の#defineです。
追加された 著者 Tom Deloford,
あなたはタイプミスをしました、2行​​目は例えばであるべきです「bitclear」
追加された 著者 jms,

Have a look here: http://nongnu.org/avr-libc/user-manual/FAQ.html#faq_use_bv

これらのマクロは、レジスタ内の特定のビットを設定するときに使用されます。 たとえば、PORTAが8ビット幅の場合、PA0が最下位ビット、PA7が最上位ビットになります。 PA0を1に設定するには、レジスタに0x01を書き込む( "または書き込む")必要があります。 あなたがPA2を設定したいならば、あなたはバイナリで正しい場所に1を持つことになる値を必要とします、PA2のためにそれは0x04になるでしょう。

人々はどのビットが特定の位置を持っているか(例えばCS12、CS10、ADSCなど他のレジスタは異なるビット名を持っているかもしれないので)覚えたくないので より抽象的な名前を使用してください。 PORTA = 0x04と入力する代わりに、PORTA = _BV(PA2)と入力すると、PA2ピンがHIGHになることがすぐにわかります。

0
追加された