これは、MPLABとXC8を使用してPICマイクロコントローラを学習する10番目のチュートリアルです 。これまで、PICによるLEDの点滅、PICのタイマー、LCDのインターフェース、7セグメントのインターフェース、PICを使用したADCなど、多くの基本的なチュートリアルについて説明してきました。初心者の方は、こちらのPICチュートリアルの完全なリストをご覧ください。学習を開始します。
このチュートリアルでは、PICPIC16F877Aを使用してPWM信号を生成する方法を学習し ます。当社のPICMCUには、PWM信号の生成に使用できるCompare Captureモジュール(CCP)と呼ばれる特別なモジュールがあります。ここでは、0%から100%までの可変デューティサイクルで5kHzのPWMを生成します。デューティサイクルを変更するには、ポテンショメータを使用しているため、PWMを開始する前にADCチュートリアルを学習することをお勧めします。PWMモジュールもタイマーを使用して周波数を設定するため、ここで事前にタイマーの使用方法を学習します。さらに、このチュートリアルでは、RC回路とLEDを使用してPWM値をアナログ電圧に変換し、それを使用してLEDライトを調光します。
PWM信号とは何ですか?
パルス幅変調(PWM)は、制御回路で最も一般的に使用されるデジタル信号です。この信号は、事前定義された時間と速度でハイ(5v)とロー(0v)に設定されます。信号がハイのままである時間は「オン時間」と呼ばれ、信号がローのままである時間は「オフ時間」と呼ばれます。以下で説明するように、PWMには2つの重要なパラメータがあります。
PWMのデューティサイクル:
PWM信号がHIGH(オンタイム)のままである時間のパーセンテージは、デューティサイクルと呼ばれます。信号が常にオンの場合は100%のデューティサイクルであり、常にオフの場合は0%のデューティサイクルです。
デューティサイクル=ターンオン時間/(ターンオン時間+ターンオフ時間)
PWMの周波数:
PWM信号の周波数は、PWMが1周期を完了する速度を決定します。上図に示すように、1周期でPWM信号のON / OFFが完了します。このチュートリアルでは、5KHzの周波数を設定します。
PIC16F877Aを使用したPWM:
PWM信号は、CCP (Compare Capture PWM)モジュールを使用してPICマイクロコントローラーで生成できます。PWM信号の分解能は10ビットです。つまり、値が0の場合は0%のデューティサイクルがあり、値が1024(2 ^ 10)の場合は100%のデューティサイクルがあります。PIC MCUには2つのCCPモジュール(CCP1とCCP2)があります。つまり、2つの異なるピン(ピン17と16)で2つのPWM信号を同時に生成できます。チュートリアルでは、CCP1を使用してピン17でPWM信号を生成しています。
以下のレジスタは、PICMCUを使用してPWM信号を生成するために使用されます。
- CCP1CON(CCP1制御レジスタ)
- T2CON(タイマ2制御レジスタ)
- PR2(タイマー2モジュール期間レジスタ)
- CCPR1L(CCPレジスター1ロー)
PWM信号を生成するためのPICのプログラミング:
このプログラムでは、ポテンショメータから0〜5vのアナログ電圧を読み取り、ADCモジュールを使用して0〜1024にマッピングします。次に、周波数5000HzのPWM信号を生成し、入力アナログ電圧に基づいてそのデューティサイクルを変化させます。つまり、0〜1024は0%〜100%のデューティサイクルに変換されます。このチュートリアルでは、PICでADCを使用する方法をすでに学習していることを前提としています。このチュートリアルでは詳細をスキップするため、ここから読んでください。
したがって、構成ビットが設定され、アナログ値を読み取るようにプログラムが書き込まれると、PWMを続行できます。
PWM動作用にCCPモジュールを構成する場合は、次の手順を実行する必要があります。
- PR2レジスタに書き込んでPWM周期を設定します。
- CCPR1LレジスタとCCP1CON <5:4>ビットに書き込むことにより、PWMデューティサイクルを設定します。
- TRISC <2>ビットをクリアして、CCP1ピンを出力にします。
- TMR2プリスケール値を設定し、T2CONに書き込んでTimer2を有効にします。
- PWM動作用にCCP1モジュールを構成します。
このプログラムには、PWM信号を生成するための2つの重要な機能があります。1つはPWMモジュールのセットアップに必要なレジスタを初期化してPWMが動作する周波数を設定するPWM_Initialize()関数で、もう1つはPWM信号のデューティサイクルを設定するPWM_Duty()関数です。必要なレジスタ。
PWM_Initialize(){PR2 =(_ XTAL_FREQ /(PWM_freq * 4 * TMR2PRESCALE))-1; //データシートを使用してPR2式を設定します// 5KHZでPWMを機能させますCCP1M3 = 1; CCP1M2 = 1; // CCP1モジュールを構成しますT2CKPS0 = 1; T2CKPS1 = 0; TMR2ON = 1; //タイマーモジュールを構成しますTRISC2 = 0; //出力としてCのポートピンを作成します}
上記の関数はPWM初期化関数です。この関数では、CCP1モジュールはビットCCP1M3とCCP1M2をハイにすることでPWMを使用するように設定されています。
タイマモジュールのプリスケーラは、ビットT2CKPS0をハイにし、T2CKPS1をローにすることによって設定され、ビットTMR2ONがタイマを開始するように設定されます。
ここで、PWM信号の周波数を設定する必要があります。周波数の値はPR2レジスタに書き込む必要があります。希望の周波数は以下の式で設定できます
PWM周期= * 4 * TOSC *(TMR2プリスケール値)
PR2を取得するためにこれらの式を再配置すると、
PR2 =(期間/(4 * Tosc * TMR2プレスケール))-1
Period =(1 / PWM_freq)およびTosc =(1 / _XTAL_FREQ)であることがわかっています。したがって…..
PR2 =(_ XTAL_FREQ /(PWM_freq * 4 * TMR2PRESCALE))– 1;
周波数が設定されると、周波数を再度変更する必要がない限り、この関数を再度呼び出す必要はありません。このチュートリアルでは、 PWM_freq = 5000 を割り当て ました。 これにより、PWM信号の5KHzの動作周波数を取得できます。
次に、以下の関数を使用してPWMのデューティサイクルを設定しましょう。
PWM_Duty(unsigned int Duty){if(duty <1023){duty =((float)duty / 1023)*(_ XTAL_FREQ /(PWM_freq * TMR2PRESCALE)); //削減時// duty =(((float)duty / 1023)*(1 / PWM_freq))/((1 / _XTAL_FREQ)* TMR2PRESCALE); CCP1X =義務&1; //最初のビットを格納しますCCP1Y = Duty&2; // 0番目のビットを保存CCPR1L = Duty >> 2; //リマイニング8ビットを保存}}
PWM信号の分解能は10ビットであるため、PICには8ビットのデータラインしかないため、この値を単一のレジスタに格納することはできません。したがって、CCP1CON <5:4>の他の2ビット(CCP1XおよびCCP1Y)を使用して、最後の2つのLSBを格納し、残りの8ビットをCCPR1Lレジスタに格納します。
PWMデューティサイクル時間は、次の式を使用して計算できます。
PWMデューティサイクル=(CCPRIL:CCP1CON <5:4>)* Tosc *(TMR2プリスケール値)
これらの式を並べ替えてCCPR1LとCCP1CONの値を取得すると、次のようになります。
CCPRIL:CCP1Con <5:4> = PWMデューティサイクル/(Tosc * TMR2プリスケール値)
ADCの値は0〜1024であり、0%〜100%である必要があるため、PWMデューティサイクル=デューティ/ 1023です。さらに、このデューティサイクルを期間に変換するには、周期(1 / PWM_freq)を掛ける必要があります。
Tosc =(1 / PWM_freq)であることがわかっているため、..
デューティ=(((float)duty / 1023)*(1 / PWM_freq))/((1 / _XTAL_FREQ)* TMR2PRESCALE);
上記の方程式を解くと、次のようになります。
デューティ=((float)duty / 1023)*(_ XTAL_FREQ /(PWM_freq * TMR2PRESCALE));
詳細なビデオとともに、以下のコードセクションでプログラム全体を確認できます。
回路図とテスト:
いつものように、Proteusシミュレーションを使用して出力を確認しましょう。回路図を以下に示します。
ポテンショメータを7番目のピンに接続して、0〜5の電圧を供給します。CCP1モジュールにはピン17(RC2)があり、ここでPWMが生成されます。これは、デジタルオシロスコープを使用して確認できます。さらに、これを可変電圧に変換するために、RCフィルターとLEDを使用して、スコープなしで出力を検証しました。
RCフィルターとは何ですか?
AN RCフィルタやローパスフィルタは、 2つの受動素子、すなわち抵抗とコンデンサとの単純な回路です。これらの2つのコンポーネントは、PWM信号の周波数をフィルタリングし、それを可変DC電圧にするために使用されます。
回路を調べると、Rの入力に可変電圧が印加されると、コンデンサCが充電を開始します。コンデンサの値に基づいて、コンデンサが完全に充電されるまでに時間がかかります。充電されると、DC電流がブロックされます(コンデンサはDCをブロックしますが、ACは許可します)。したがって、入力DC電圧が出力の両端に現れます。高周波PWM(AC信号)はコンデンサを介して接地されます。したがって、コンデンサの両端に純粋なDCが得られます。このプロジェクトには、1000Ohmと1ufの値が適切であることがわかりました。 RとCの値の計算には、伝達関数を使用した回路解析が含まれますが、これはこのチュートリアルの範囲外です。
プログラムの出力は、以下に示すようにデジタルオシロスコープを使用して確認でき、ポテンショメータを変更すると、PWMのデューティサイクルが変更されます。電圧計を使用して、RC回路の出力電圧を確認することもできます。すべてが期待どおりに機能している場合は、ハードウェアを続行できます。完全なプロセスについては、最後にあるビデオをさらに確認してください。
ハードウェアでの作業:
プロジェクトのハードウェア設定は非常に簡単です。以下に示すPICPerfボードを再利用します。
アナログ電圧を供給するためのポテンショメータも必要になります。PICPerfボードに直接接続できるように、ポットにメスのエンドワイヤをいくつか取り付けました(以下を参照)。
最後に、出力を確認するために、 PWM信号がどのように機能するかを確認するためにRC回路とLEDが必要です。以下に示すように、小さなパフォーマンスボードを使用し、RC回路とLED(輝度を制御するため)をはんだ付けしました。
単純なメス間接続ワイヤを使用して、上記の回路図に従って接続できます。接続が完了したら、pickit3を使用してプログラムをPICにアップロードすると、ポテンショメータの入力に基づいて可変電圧を取得できるようになります。ここでは、可変出力を使用してLEDの輝度を制御します。
マルチメータを使用して可変出力を測定しました。また、さまざまな電圧レベルでLEDの明るさが変化することもわかります。
これで、POTからアナログ電圧を読み取り、PWM信号に変換し、RCフィルターを使用して可変電圧に変換するようにプログラムしました。結果はハードウェアを使用して検証されます。ご不明な点がある場合や、どこかで行き詰まった場合は、下のコメントセクションをご利用ください。喜んでお手伝いさせていただきます。完全な作業は、ビデオの中で働いています。
他のマイクロコントローラーに関する他のPWMチュートリアルも確認してください。
- Raspberry PiPWMチュートリアル
- ArduinoDueを使用したPWM
- PWMを使用したArduinoベースのLED調光器
- ATmega32マイクロコントローラーを使用した電源LED調光器