私は学校のプロジェクトに取り組んでおり、AVR atmegaコントローラーでCの基本を学ぶ必要があります。
すべてがどのように設定されているかわかりません。たとえば、PORTB、PORTD、DDRB。 DDRD、PINB、PINDなど。そして、ifステートメント、whileループなどですべてがどのように機能するかわかりません。
誰か簡単な説明をお願いできますか?
私はいくつかのコード行があります...
_DDRB = 0b00000011; // I know that here DDRB is set to input/output
_
そしてifステートメント:
_if (PINB & (1 << PINB0)){
A = true;
}
_
誰かがこの「ifステートメント」の仕組みを説明できますか?なぜPINB & (1<< PINB0))
?
ありがとう
If-condition PINB & (1<< PINB0))
とは何ですか?
PINB0 + 1
numberビット(rhsから)がPINB
でON(1)かOFF(0)かをチェックします。
例えば。 (a & (1 << 2))
は、a
の3番目のビットがオンかオフかをチェックします。式では、<<
ビット単位の左シフトと&
ビット単位以下の2つの演算子が使用されます。1バイトの例について説明しました。
1
は0000 0001
です1 << 2
左シフト後の0000 0100
a
ビット単位で0000 0100
を使用すると、すべてゼロになります0000 0000
または0000 0100
3a。すべてゼロの場合、条件が偽の場合(a
の3番目のビットがゼロの場合)。
3b。ビット単位の結果が0000 0100
の場合、条件がtrueと評価される場合(a
の3番目のビットが1の場合)。
マイクロプロセッサはメモリマップを使用して、ハードウェア機能とソフトウェアをインターフェイスします。
基本的に、ハードウェアがその機能を決定するために使用する静的アドレスがメモリ内にあります。これらは、製造業者、部品、および場合によっては部品の構成方法に固有です。
部品のデータシートには、さまざまな機能を制御するための正確なメモリ位置が記載されています。ただし、これは通常非常に面倒です。その結果、データシートは、(ほとんど)常に、その機能を説明するメモリ内の特定の場所に名前を付けます。繰り返しますが、これらの名前はメーカーと部品固有です。
プログラマーがこのインターフェースを簡単にするために、多くの場合、人々(製造業者またはコミュニティー)はこれらのメモリー位置にマクロを作成します。たとえば、あなたは見つけることができます
// Clock Prescalar Register for ATMega328p
#define CLKPR *0x61
パーツに関連付けられたヘッダーファイル(AVR libcなど)。
さて、OSCCAL = 0b10000000
(またはデータシートの仕様で許可されているその他の記述)この部分のクロックプリスカラーモジュールに直接アクセスして変更できます。
しかし、多くの場合、バイト全体ではなく、単一ビットの値に関心があります。結果として、ビットごとの演算子(&
、|
、~
、<<
>>
)操作したいビットを「マスク」します。
これにより、トグルするつもりのないビットを誤って変更することなく、関心のあるビットからのみ値を読み取ることができるという利点が同時に得られます。
多くのビット位置もマクロによって与えられます。たとえば、OSCCAL
のビット7の名前はCLKPCE
です(データシートから)。
CLKPCEは(少なくともAVR libcで-標準は異なります)以下によって定義される可能性が高いです。
#define CLKPCE 7
OSCCAL
内の目的のビットに到達するために必要なビットシフトを定義するためです。
ここで少し話をするために、いくつかのことができます。
ビットを設定するには、他のビットに影響を与えずに1にします。これを行うには、次のようにORマスクを使用します。
OSCCAL = (OSCCAL | (1 << CLKPCE));
ビット演算子を確認し、これがどのように機能するかを確認するのはあなたにお任せします。
ここでは、他のビットに影響を与えることなく、0にしたいのです。次のようになります。
OSCCAL = (OSCCAL & ~(1 << CLKPCE));
クエリを実行するとき、ビットが設定されている場合は非ゼロ(1)を返し、ビットがクリアされている場合はゼロ(0)を返す式が必要です。次のようになります。
(OSCCAL & (1 << CLKPCE));
事前定義されたマクロでこれらのさまざまなビット演算を使用することにより、この静的メモリマップを使用してハードウェアの状態を直接制御および照会できます。
ただし、これらすべてのマクロを理解するには、パーツのデータシートを参照(および読み取り、再読み取り、再再読み取り)する必要があります。幸いなことに、検索可能なPDFは、パーツのページでAtmelから無料で入手できます!
レジスタの意味については、相談することをお勧めします
つまり、最後の文字(B
、D
)は、アクセスしているポートを意味します。GPIOピンは、各ポートが8ピンになるように8方向にグループ化されます。
DDRx
は、各ポートピンの方向を設定する手段です。
PORTx
とPINx
は入力と出力に使用されますが、私はPORTA.IN
、PORTB.DDR
、PORTD.OUT
等、私はそれらのどれが何をするかを心で伝えることができません。
言語の基本については、この言語を学習できる書籍とチュートリアルがあります。
_if (PINB & (1 << PINB0)){
A = true;
}
_
このコードは、_PIN 0 in PORTB
_が_HIGH or LOW
_であるかどうかをチェックします。高い場合、_A = true;
_を割り当てます。ここで、PINB
-> PORTB, (1<<PINB0)
からデータを読み取ります-> 0番目のビットを1にし、AND
の両方の値をPORTB
のPIN 0が高いかどうかを知る。