Arduinoボード上でポートレジスタを操作することで制御

3109 ワード

ポートレジスタは、Arduinoボード上でマイクロコントローラのi/oピンをより低級かつより速く操作することを可能にする.Arduinoボードで使用されるチップ(ATmega 8とATmega 168)には、3つのポートがあります.
B(デジタルピン8~13)C(アナログ入力ピン)D(デジタルピン0~7)各ポートは3つのレジスタによって制御され、この3つのレジスタはarduino言語で定義された変数でもある.DDRレジスタはピンがINPUTかOUTPUTかを決定する.PORTレジスタはピンがハイレベルかローレベルかを制御し、PINレジスタはpinModeを介して()入力に設定されたINPUTピンの状態を読み取る.ATmega 8とATmega 168チップの地図にはポートが表示されている.新しいAtmega 328 pチップはAtmega 168のピン配列に完全に従っている.
DDRおよびPORTレジスタは、書き込みおよび読み出しが可能である.PINレジスタは入力状態に対応しており、読み取りのみ可能である.
PORTDをArduinoディジタルピン0~7にマッピング
  • DDRD-ポートDデータ方向レジスタ-読み書き
  • PORTD-ポートDデータレジスタ-読み取り/書き込み
  • PIND-ポートD入力ピンレジスタ-読取り専用
  • PORTBをArduinoディジタルピン8〜13にマッピングした2つの高位(6および7)を結晶ピンにマッピングしたが,利用できなかった.
  • DDRB-ポートBデータ方向レジスタ-読み書き
  • PORTB-ポートBデータレジスタ-読み取り/書き込み
  • PINB-ポートB入力ピンレジスタ-読み取り専用
  • PORTCはArduinoシミュレーションピン0~5にマッピングする.ピン6と7はArduino Miniでしかアクセスできません
  • DDRC-ポートCデータ方向レジスタ-読み書き
  • PORTC-ポートCデータレジスタ-読み取り/書き込み
  • PINC-ポートC入力ピンレジスタ-読取り専用
  • これらのレジスタの各ビットは1つのピンに対応する.たとえば、DDRB、PORTBおよびPINBの下位は、ピンPB 0(デジタルピン8)を指す.Arduinoピン番号のポートおよびビットへの完全なマッピングについては、チップマップ:ATmega 8、ATmega 168を参照してください.(ポートの一部のビットは、i/o以外のビットに使用できます.それらに対応するレジスタビットの値を変更しないように注意してください.)
    例は上のピン図を参照し、PortDレジスタはArduinoディジタルピン0〜7を制御する.
    ただし、Arduinoをプログラミングおよびデバッグするためにピン0および1はシリアル通信に使用されるため、シリアル入力または出力機能が必要でない限り、ピンの変更は通常回避されます.プログラムのダウンロードやデバッグに干渉する可能性があります.
    DDRDは、ポートDの方向レジスタ(Arduinoディジタルピン0-7)である.このレジスタのビット制御PORTDのピンが入力または出力として構成されているかどうか、例えば、
    DDRD = B11111110; // Arduino  1 7     ,   0     
    DDRD = DDRD | B11111100; //     ,      2 7     
    	                  //     0 1  , RX TX 
    

    PORTDは出力状態のレジスタです.たとえば、
    PORTD = B10101000; // sets digital pins 7,5,3 HIGH
    

    DDRDレジスタまたはpinMode()を使用してピンを出力に設定すると、これらのピンに5ボルトの電圧しか見えません.
    PINDは入力レジスタ変数であり、すべてのデジタル入力ピンを同時に読み出す.
    ポート操作の使用方法(Bitmathチュートリアルより)
    一般的に、このようなことをするのはいい考えではありません.どうして?理由は次のとおりです.
    コードはデバッグとメンテナンスにとってより困難であり、他の人にとってより困難である.プロセッサがコードを実行するのに数マイクロ秒しかかかりませんが、なぜ正常に動作して修復できないのかを明らかにするには数時間かかる場合があります.あなたの時間は貴重ですね.しかし、コンピュータの時間はとても安いので、電気代をあげて測ります.通常、コードを最も明らかな方法で記述するのはずっと良いです.コードはあまり携帯できません.digitalRead()とdigitalWriteを使用する場合()は、すべてのAtmelマイクロコントローラ上で実行されるコードを記述することがより容易であり、制御ポートレジスタとポートレジスタは、それぞれのマイクロコントローラ上で異なっていてもよい.直接ポートアクセスによって、予期せぬ障害をより容易に引き起こすことができる.注意線DDRD=B 1111111110.前述したように、入力ピンとしてピン0を使用する必要がある.ピン0はシリアルポート上の受信線である(RX).ピン0を出力ピンに変更することで、意外にもシリアルポートが停止しやすくなります!シリアルデータを突然受信できなくなると混乱するのではないでしょうか.だから、なぜ私がこれらのものを使いたいのか、自分に言うかもしれません.以下は直接ポートアクセスの積極的な面です.
    ピンを非常に迅速に開閉する必要がある場合があります.これは、数マイクロ秒以内であることを意味します.lib/targets/arduino/wiringを見てください.cのソースコード、digitalRead()とdigitalWriteが見えます()は、多くのマシン命令にコンパイルされた約10行のコードです.各マシン命令には、時間に敏感なアプリケーションに蓄積される16 MHzのクロックサイクルが必要です.ダイレクトポートアクセスは、より少ないクロックサイクルで同じ作業を完了できます.同じ時間に複数の出力ピンを設定する必要がある場合があります.digitalWriteを呼び出します.(10,HIGH);続いてdigitalWrite(11,HIGH);これにより、ピン10がピン11の数マイクロ秒前にハイレベルになり、接続されている時間に敏感な外部デジタル回路の一部が混同される可能性があります.または、PORTB|=B 1100を使用して2つのピンを完全に同じ時刻に設定できます.プログラムメモリが不足している場合は、これらのテクニックを使用してコードをより小さくすることができます.コードバイトのコンパイルをより少なくする必要がありますを使用して、forループを使用して各ピンを個別に設定するのではなく、ポートレジスタを介してハードウェアピンの山を同時に書き込むことができます.場合によっては、プログラムがフラッシュメモリに適しているか、互換性がない可能性があります.