前のチュートリアルでは、PICマイクロコントローラーを使用してLEDを点滅させる方法を学び、Perfボード上に同じ回路を構築しました。次に、PICkit 3、ICSP、MPLABIPEを使用してプログラムをPerfボードにダンプしました。ここで、このチュートリアルでは、PICマイクロコントローラーでより多くのピンを使用するように自分自身を進めます。 7つの出力(LED)と1つの入力を使用します。このチュートリアルでは、古いPerfボード(以下に表示)を使用し、2番目のLEDボードに必要なピンを引き出すためにバーグスティックを追加します。このチュートリアルの最後に、PICマイクロコントローラーPIC16F877Aを使用して点滅するLEDのシーケンスを生成し、複数の入力と出力の使用方法、「for」ループと関数呼び出しの基本を学習します。
LEDボードは、LEDを電流制限抵抗(以下に表示)ではんだ付けする別のパフォーマンスボードに他なりません。また、シーケンスLEDの点滅を開始するための押しボタンを追加します。
回路図:
PICマイクロコントローラーPIC16F877ALEDの点滅シーケンスコードと動作説明:
完全なコードを以下に示します(最後に確認してください)。ここでは、1行ずつ説明します。このコードは、押しボタンが押されると、LEDを順番に点灯させ始めます。シーケンスを理解するには、チュートリアルの最後にあるビデオをご覧ください。ビデオに示されている出力を以下のコードと比較して、プログラムを理解することをお勧めします。
コードを1行ずつ見ていきましょう。最初の数行は、前のチュートリアルで説明した構成ビットを設定するためのものなので、ここではスキップします。プログラムを理解する最良の方法は、main( void main() )関数から始めることです。それでは、それを実行しましょう。
TRISB0 = 1; // PORTBピン0がボタンの入力として使用されることをMCUに指示します。TRISD = 0x00; //すべてのピンが出力されるようにMCUに指示しますPORTD = 0x00; //すべてのピンを0に初期化します
TRISという単語は、ピンが入力/出力として使用されているかどうかを定義するために使用され、PORTという単語は、ピンをHigh / Lowにするために使用されます。ライン TRISB0 = 1 は、ポートBの0番目のピンを入力にします。これがプッシュボタンになります。行 TRISD = 0x00; PORTD = 0x00; ポートDのすべてのピンを出力として作成し、それらのピンにLOWの初期値を割り当てます。
B0を入力として使用すると述べたので、押しボタンの一方の端をピンB0に接続し、もう一方の端をアースに接続します。それまでに、ボタンを押すたびに、上の接続図に示すように、ピンがグランドに保持されます。ただし、これを実現するには、ボタンが押されていないときにピンがハイに保持されるように、プルアップ抵抗を使用する必要があります。プルアップ抵抗はこんな感じです。
しかし、私たちのPIC MCUには、ソフトウェアによってアクティブ化できる弱いプルアップ抵抗が内部にあり、多くの手間を省くことができます(より多くのボタンを接続する場合)。
弱いプルアップ抵抗とは何ですか?
プルアップ抵抗には、弱いプルアップと強いプルアップの2種類があります。弱いプルアップ抵抗は値が大きいため、弱い電流が流れることができ、強いプルアップ抵抗は値が小さいため、強い電流が流れることができます。すべてのMCUは主に弱いプルアップ抵抗を使用します。 PIC MCUでこれをアクティブにするには、以下のスナップショットに示すように、OPTION_REG(オプションレジスタ)のデータシートを調べる必要があります。
示されているように、ビット7は弱いプルアップ抵抗を扱います。それをアクティブにするには、ゼロにする必要があります。これは、 OPTION_REG <7> = 0 によって実行され ます 。これは特にビット7を扱い、他のビットをデフォルト値のままにします。これでwhileループに入り、if (RB0 == 0) を使用してボタンが押されたかどうかをチェックします 。 条件が満たされた場合、パラメーター1、3、7、および15を使用して関数を呼び出します。
sblink(1); //パラメータ1のFUNCTIONCALL 1 sblink(3); //パラメータ3のFUNCTIONCALL 3 sblink(7); //パラメータ7を指定したFUNCTIONCALL 7 sblink(15); //パラメータ15のFUNCTIONCALL 4
なぜ関数を使うのですか?
関数は、コードの行数を減らすために使用されます。これは私たちのほとんどが知っていたであろうことです。しかし、特にMCUプログラミングに関しては、なぜ行数を減らす必要があるのでしょうか。その理由は、プログラムメモリのスペースが限られているためです。コードを適切に最適化しないと、メモリスペースが不足する可能性があります。これは、長いページのコードを書くときに便利です。
すべての関数には、関数定義( この場合は sblink(int get) )と関数呼び出し( この場合は sblink(1)) があります。関数宣言を使用することはオプションです。これを回避するために、関数をメイン関数に呼び出す前に関数定義を配置しました。
関数パラメーターは、関数呼び出しから関数定義に渡される値です。この場合、整数値(1、3、7、15)は関数呼び出しから渡されるパラメーターであり、変数 「get」 はパラメーターの値を関数定義に取得して処理します。関数は複数のパラメーターを持つことができます。
関数が呼び出されると、関数定義の以下の行が実行されます。
for(int i = 0; i <= 7 && RB0 == 0; i ++){PORTD = get << i; // LEDは左シーケンスを移動します__delay_ms(50); } for(int i = 7; i> = 0 && RB0 == 0; i-){PORTD = get << i; // LEDは左シーケンスを移動します__delay_ms(50); }
今、この行は奇妙に見えます: PORTD = get << i 。ここで実際に何が起こっているのかを説明します。
「<<」は、すべてのビットを左の位置にシフトする左シフト演算子です。ここで、パラメーター「1」を sblink(1) として sblink(int get) 関数を呼び出すと、 「get」の 値 が 1になります。これはバイナリでは0b00000001です。したがって、この行は PORTD = 0b00000001 << iの ようになります。
'for loop' for(int i = 0; i <= 7 && RB0 == 0; i ++) を使用したため、「i」の値は0から7まで変化します 。 'i'の値が0から7の場合、結果は次のように変わります。
ご覧のとおり、残りのLEDをオフのままにして、一度に1つのLEDを(左から右に)オンにしました。次の「 forloop 」 for(int i = 7; i> = 0 && RB0 == 0; i--) も同じように動作しますが、今回はLEDが右から左に順番にオンになります。 7から開始して0に下がったとき。LEDのオンとオフを視覚化できるように、200ミリ秒の遅延を使用しました。
ここで、 sblink(int get) 関数に値3を渡すと、関数 sblink(3) が実行され、 'get'の値が0b00000011になります。したがって、PORTDの結果は次のようになります。
そのため、今回は sblink(3) を使用して、いつでも2つのLEDがオンになります 。 同様に、 sblink(7) と sblink(15)の場合、 3つと4つのLEDが順番に点灯します。これが完了したら、 PORTD = 0xFFの 行を使用してすべてのLEDをオンにします。完全なデモンストレーションについては、以下のビデオを確認してください。
コードを理解し、関数、「for」および「while」ループを使用して目的の出力を取得する方法を学習したことを願っています。これで、コードを微調整して、さまざまなLEDの点滅シーケンスを取得できます。コードをコンパイルしてMCUにダンプし、出力を楽しんでください。どこかで行き詰まった場合は、コメントセクションを使用できます。シミュレーションファイルとプログラムファイルもここに添付しました。
これで、次のチュートリアルでは、遅延関数を使用する代わりにPIC16F877Aタイマーを使用する方法を学習します。ここですべてのPICマイクロコントローラーチュートリアルを閲覧できます。