これは、MPLABとXC8を使用してPICマイクロコントローラを学習する9番目のチュートリアルです 。これまで、MPLABXの使用開始、PICでのLEDの点滅、PICのタイマー、LCDのインターフェース、7セグメントのインターフェースなど、多くの基本的なチュートリアルについて説明してきました。初心者の方は、PICチュートリアルの完全なリストをご覧ください。学習を開始します。
このチュートリアルでは、PICマイクロコントローラーPICF877AでADCを使用する方法を学習します。。ほとんどのマイクロコントローラープロジェクトには、ADC(アナログ-デジタルコンバーター)が含まれます。これは、実世界からデータを読み取るために最もよく使用される方法の1つだからです。温度センサー、フラックスセンサー、圧力センサー、電流センサー、電圧センサー、ジャイロスコープ、加速度計、距離センサーなどのほぼすべてのセンサー、およびほぼすべての既知のセンサーまたはトランスデューサーは、センサーの読み取り値に基づいて0V〜5Vのアナログ電圧を生成します。たとえば、温度センサーは、温度が25°Cのときに2.1Vを出力し、温度が60°Cのときに4.7まで上昇する場合があります。実世界の温度を知るために、MCUはこの温度センサーの出力電圧を読み取り、それを実世界の温度に関連付ける必要があります。したがって、ADCはMCUプロジェクトにとって重要な作業ツールであり、PIC16F877AでADCを使用する方法を学ぶことができます。
他のマイクロコントローラーでのADCの使用に関する以前の記事も確認してください。
- Arduino UnoでADCを使用する方法は?
- Raspberry PiADCチュートリアル
- ADC0808と8051マイクロコントローラーのインターフェース
PICマイクロコントローラーPIC16F877AのADC:
利用可能なADCには多くの種類があり、それぞれに独自の速度と分解能があります。最も一般的なタイプのADCは、フラッシュ、逐次比較、およびシグマデルタです。PIC16F877Aで使用されるADCのタイプは、略して逐次比較ADCまたはSARと呼ばれます。それでは、SAR ADCを使い始める前に、SARADCについて少し学びましょう。
逐次比較ADC: SAR ADCは、コンパレータといくつかの論理会話の助けを借りて動作します。このタイプのADCは、基準電圧(可変)を使用し、コンパレータを使用して入力電圧を基準電圧と比較し、デジタル出力となる差を最上位ビット(MSB)から保存します。比較の速度は、PICが動作しているクロック周波数(Fosc)によって異なります。
ADCの基本を理解したところで、データシートを開いて、PIC16F877AMCUでADCを使用する方法を学びましょう。使用しているPICには10ビットの8チャンネルADCがあります。これは、ADCの出力値が0〜1024(2 ^ 10)であり、アナログ電圧を読み取ることができる8つのピン(チャネル)がMCUにあることを意味します。ADCは10ビットであるため、値1024は2 ^ 10によって取得されます。アナログ電圧を読み取ることができる8つのピンはデータシートに記載されています。下の写真を見てみましょう。
アナログチャンネルAN0からAN7が強調表示されています。これらのピンのみがアナログ電圧を読み取ることができます。したがって、入力電圧を読み取る前に、入力電圧を読み取るためにどのチャネルを使用する必要があるかをコードで指定する必要があります。このチュートリアルでは、ポテンショメータを備えたチャネル4を使用して、このチャネルのアナログ電圧を読み取ります。
A / Dモジュールには4つのレジスタがあり、入力ピンからデータを読み取るように構成する必要があります。これらのレジスタは次のとおりです。
•A / D結果高レジスタ(ADRESH)
•A / D結果低レジスタ(ADRESL)
•A / D制御レジスタ0(ADCON0)
•A / D制御レジスタ1(ADCON1)
ADCのプログラミング:
PICマイクロコントローラーでADCを使用するためのプログラムは非常に単純です。これらの4つのレジスターを理解するだけで、アナログ電圧の読み取りが簡単になります。いつものように、構成ビットを初期化し、 void main() から始めましょう 。
void main() 内で、ADCON1レジスタとADCON0レジスタを使用してADCを初期化する必要があります。ADCON0レジスタには次のビットがあります。
このレジスタでは、ADON = 1にしてADCモジュールをオンにし、ADCS1ビットとADCS0ビットを使用してA / D変換クロックをオンにする必要があります。残りは、今のところ設定されません。私たちのプログラムでは、A / D変換クロックがFosc / 16として選択されており、独自の周波数を試して、結果がどのように変化するかを確認できます。詳細については、データシートの127ページをご覧ください。したがって、ADCON0は次のように初期化されます。
ADCON0 = 0b01000001;
これで、ADCON1レジスタには次のビットがあります。
このレジスタでは、ADFM = 1でA / D結果フォーマット選択ビットをハイにし、ADCS2 = 1にしてFosc / 16を再度選択する必要があります。内部基準電圧を使用することを計画しているため、他のビットはゼロのままです。詳細については、128ページのデータシートを参照してください。したがって、ADCON1は次のように設定します。
ADCON1 = 0x11000000;
main関数内でADCモジュールを初期化した後、whileループに入り、ADC値の読み取りを開始します。ADC値を読み取るには、次の手順に従う必要があります。
- ADCモジュールを初期化します
- アナログチャンネルを選択します
- Go / DoneをビットハイにしてADCを開始します
- Go / DONEビットが低くなるのを待ちます
- ADRESHおよびADRESLレジスタからADC結果を取得します
1. ADCモジュールの初期化:ADCを初期化する方法をすでに学習しているので、以下の関数を呼び出してADCを初期化します。
空ADC_Initialize() 関数は次のようです。
void ADC_Initialize(){ADCON0 = 0b01000001; // ADCがオンでFosc / 16が選択されているADCON1 = 0b11000000; //内部基準電圧が選択されています}
2.アナログチャネルを選択します。次に、ADC値の読み取りに使用するチャネルを選択する必要があります。このための関数を作成して、 while ループ内の各チャネル間を簡単に移動できるように し ます。
unsigned int ADC_Read(unsigned char channel){// ****チャネルの選択** /// ADCON0&= 0x11000101; //チャネル選択ビットをクリアするADCON0- = channel << 3; //必要なビットの設定// **チャネル選択の完了*** ///}
次に、選択するチャネルが可変チャネル内で受信されます。行で
ADCON0&= 0x1100101;
前のチャネル選択(存在する場合)はクリアされます。これは、ビットごとの演算子「&」を使用して行われます。ビット3、4、および5は強制的に0になり、他のビットは以前の値のままになります。
次に、チャネル番号を3回左シフトし、ビット単位または演算子「-」を使用してビットを設定することにより、目的のチャネルを選択します。
ADCON0- =チャネル<< 3; //必要なビットを設定する
3. Go / DoneビットをハイにしてADCを開始します。チャネルを選択したら、 GO_nDONE ビットをハイにするだけでADC変換を開始する 必要があり ます。
GO_nDONE = 1; // A / D変換を初期化します
4. Go / DONEビットがローに なるのを待ちます。ADC変換が完了するまでGO / DONEビットはハイのままなので、このビットが再びローになるまで待つ必要があります。これは、 while ループを使用して実行できます。
while(GO_nDONE); // A / D変換が完了するのを待ちます
5. ADRESHおよびADRESLレジスタからADC結果を取得します。Go/ DONEビットが再びローになると、ADC変換が完了したことを意味します。ADCの結果は10ビット値になります。私たちのMCUは8ビットMCUであるため、結果は上位8ビットと下位2ビットに分割されます。上位8ビットの結果はレジスタADRESHに格納され、下位2ビットはレジスタADRESLに格納されます。したがって、10ビットのADC値を取得するには、これらをレジスタに合計する必要があります。この結果は、次のように関数によって返されます。
戻り値((ADRESH << 8)+ ADRESL); //結果を返します
ADCチャネルを選択し、ADCをトリガーし、結果を返すために使用される完全な関数をここに示します。
unsigned int ADC_Read(unsigned char channel){ADCON0&= 0x11000101; //チャネル選択ビットをクリアするADCON0- = channel << 3; //必要なビットを設定する__delay_ms(2); //ホールドコンデンサを充電するための取得時間GO_nDONE = 1; // A / D変換を初期化しますwhile(GO_nDONE); // A / D変換が完了するのを待ちますreturn((ADRESH << 8)+ ADRESL); //結果を返します}
これで、チャネル選択を入力として受け取り、ADC値を返す関数ができました。したがって、このチュートリアルではチャネル4からアナログ電圧を読み取っているため、 while ループ内でこの関数を直接呼び出すことができます。関数の呼び出しは次のようになります。
i =(ADC_Read(4)); // adcの結果を「i」に保存します。
ADCの出力を視覚化するには、LCDや7セグメントなどの何らかのディスプレイモジュールが必要になります。このチュートリアルでは、7セグメントディスプレイを使用して出力を確認しています。picで7セグメントを使用する方法を知りたい場合は、こちらのチュートリアルに従ってください。
完全なコードは、 以下に示され、プロセスはまた、説明されている ビデオの 終わりに。
ハードウェアのセットアップとテスト:
通常、ハードウェアを実際に使用する前に、Proteusを使用してコードをシミュレートします。プロジェクトの回路図を以下に示します。
4桁の7セグメントディスプレイモジュールとPICマイクロコントローラの接続は前のプロジェクトと同じです。アナログチャネル4であるピン7にポテンショメータを追加しました。ポットを変えることにより、可変電圧がMCUに送信されます。これはADCモジュールによって読み取られ、7セグメントディスプレイモジュールに表示されます。前のチュートリアルを確認して、4桁の7セグメントディスプレイとPICMCUとのインターフェースについて詳しく学んでください。
ここでは 、LED点滅チュートリアルで作成したものと同じPICマイクロコントローラーボードを使用しました 。接続を確認した後、プログラムをPICにアップロードすると、次のような出力が表示されます。
ここでは、ポットからADC値を読み取り、0〜1024の出力を0〜5ボルトとしてマッピングすることによって実際の電圧に変換しました(プログラムに示されているように)。次に、値が7セグメントに表示され、マルチメータを使用して検証されます。
これで、市場で入手可能なすべてのアナログセンサーを使用する準備が整いました。これを試してみてください。いつものように問題が発生した場合は、コメントセクションを使用してサポートさせていただきます。