パルス幅変調(PWM)は、周波数を一定に保つことによってパルスの幅を変更する強力な手法です。この手法は、今日多くの制御システムで使用されています。 PWMの用途は限定されず、モーター速度制御、測定、電力制御、通信などの幅広い用途で使用されます。PWM技術では、デジタル信号を使用してアナログ出力信号を簡単に生成できます。このチュートリアルは、PWM、その用語、およびマイクロコントローラーを使用してPWMを実装する方法を理解するのに役立ちます。このチュートリアルでは、LEDの強度を変化させることにより、AVRAtmega16マイクロコントローラーを使用したPWMのデモを行います。
PWMの基本を詳細に理解するには、さまざまなマイクロコントローラーを使用したPWMに関する以前のチュートリアルにアクセスしてください。
- ARM7-LPC2148 PWMチュートリアル:LEDの明るさの制御
- MSP430G2を使用したパルス幅変調(PWM):LEDの明るさの制御
- MPLABおよびXC8を搭載したPICマイクロコントローラを使用したPWMの生成
- STM32F103C8のパルス幅変調(PWM):DCファンの速度の制御
- PICマイクロコントローラーのGPIOピンでPWM信号を生成する
- Raspberry PiPWMチュートリアル
AVRマイクロコントローラーAtmega16のPWMピン
Atmega16には4つの専用PWMピンがあります。これらのピンは、PB3(OC0)、PD4(OC1B)、PD5(OC1A)、PD7(OC2)です。
また、Atmega16には2つの8ビットタイマーと1つの16ビットタイマーがあります。Timer0とTimer2は8ビットタイマーですが、Timer1は16ビットタイマーです。PWMを生成するには、タイマーを使用してPWMを生成するため、タイマーの概要を把握する必要があります。頻度は、タイマーが実行される1秒あたりのサイクル数であることがわかっています。したがって、周波数が高いほど、タイマーが速くなります。PWMの生成では、PWM周波数が速いほど、新しいPWMデューティサイクルに速く応答できるため、出力をより細かく制御できます。
このAtmega16PWMチュートリアルでは、Timer2を使用します。任意のデューティサイクルを選択できます。PWMのデューティサイクルがわからない場合は、簡単に説明しましょう。
PWM信号とは何ですか?
パルス幅変調 (PWM)は、制御回路で最も一般的に使用されるデジタル信号です。信号がハイのままである時間は「オン時間」と呼ばれ、信号がローのままである時間は「オフ時間」と呼ばれます。以下で説明するように、PWMには2つの重要なパラメータがあります。
PWMのデューティサイクル
PWM信号がHIGH(オンタイム)のままである時間のパーセンテージは、デューティサイクルと呼ばれます。
100msのパルス信号のように、信号が50msでHIGH、50msでLOWの場合、パルスが半分の時間HIGHと半分の時間LOWであったことを意味します。したがって、デューティサイクルは50%であると言えます。同様に、パルスが100msのうち25ms HIGH状態にあり、75msがLOW状態にある場合、デューティサイクルは25%になります。HIGH状態の期間のみを計算することに注意してください。下の写真を参考にして視覚的に理解してください。したがって、デューティサイクルの式は次のようになります。
デューティサイクル(%)=オン時間/(オン時間+オフ時間)
したがって、デューティサイクルを変更することにより、PWMの幅を変更して、LEDの輝度を変更することができます。LEDの輝度を制御する際に異なるデューティサイクルを使用するデモを行います。このチュートリアルの最後にあるデモビデオを確認してください。
デューティサイクルを選択した後、次のステップはPWMモードを選択することです。PWMモードは、PWMをどのように機能させるかを指定します。PWMモードには主に3種類あります。これらは次のとおりです。
- 高速PWM
- 位相補正PWM
- 位相と周波数が正しいPWM
高速PWMは、位相変化が問題にならない場合に使用されます。高速PWMを使用することにより、PWM値を迅速に出力できます。位相変化がモーター制御などの動作に影響を与える場合、高速PWMは使用できないため、このようなアプリケーションでは他のPWMモードが使用されます。位相変化があまり影響しないLEDの明るさを制御するので、高速PWMモードを使用します。
ここでPWMを生成するために、内部タイマーを制御してカウントアップし、特定のカウントでゼロに戻すので、タイマーはカウントアップしてから何度もゼロに戻ります。これにより期間が設定されます。パルスを制御するオプションがあり、タイマーが上がっている間、タイマーの特定のカウントでパルスをオンにします。カウンタが0に戻ったら、パルスをオフにします。いつでもタイマーのカウントにアクセスし、単一のタイマーで異なるパルスを提供できるため、これには多くの柔軟性があります。これは、一度に複数のLEDを制御したい場合に最適です。それでは、PWM用のAtmega16と1つのLEDのインターフェースを始めましょう。
ここですべてのPWM関連プロジェクトを確認してください。
必要なコンポーネント
- Atmega16AVRマイクロコントローラーIC
- 16Mhz水晶発振器
- 2つの100nFコンデンサ
- 2つの22pFコンデンサ
- ボタンを押す
- ジャンパー線
- ブレッドボード
- USBASP v2.0
- 2 LED(任意の色)
回路図
PWMにはOC2、つまりPin21(PD7)を使用しています。したがって、Atmega16のPD7ピンに1つのLEDを接続します。
PWM用のAtmega16のプログラミング
完全なプログラムを以下に示します。 JTAGとAtmelスタジオを使用してAtmega16でプログラムを書き込み、LEDのPWM効果を確認します。PWMのデューティサイクルが変化するため、その輝度はゆっくりと増減します。最後にあるビデオを確認してください。
Timer2レジスタを設定してAtmega16のプログラミングを開始します。Timer2のレジスタビットは次のとおりであり、それに応じてビットを設定またはリセットできます。
次に、Timer2のすべてのビットについて説明し、記述されたプログラムを使用して目的のPWMを取得できるようにします。
Timer2レジスタには主に4つの部分があります。
FOC2(Timer2の強制出力比較): WGMビットが非PWMモードを指定すると、FOC2ビットが設定されます。
WGM2(Timer2の波形生成モード):これらのビットは、カウンターのカウントシーケンス、最大(TOP)カウンター値のソース、および使用する波形生成のタイプを制御します。
COM2(Timer2の出力モードの比較):これらのビットは出力動作を制御します。完全なビットの説明を以下に説明します。
TCCR2-=(1 <
WGM20ビットとWGM21ビットをHIGHに設定して、PWM高速モードをアクティブにします。WGMは波形生成モードの略です。選択ビットは以下の通りです。
WGM00 |
WGM01 |
Timer2モードの動作 |
0 |
0 |
ノーマルモード |
0 |
1 |
CTC(比較マッチでタイマーをクリア) |
1 |
0 |
PWM、位相補正 |
1 |
1 |
高速PWMモード |
波形発生モードの詳細については、Atmega16の公式データシートを参照してください。
TCCR2-=(1 <
また、プリスケーリングを使用していないため、クロックソースレジスタを「001」に設定しました。
クロック選択ビットは次のとおりです。
CS22 |
CS21 |
CS20 |
説明 |
0 |
0 |
0 |
クロックソースなし(タイマー/カウンター停止) |
0 |
0 |
1 |
clk T2S /(プリスケーリングなし) |
0 |
1 |
0 |
Clk T2S / 8(プリスケーラーから) |
0 |
1 |
1 |
Clk T2S / 32(プリスケーラーから) |
1 |
0 |
0 |
Clk T2S / 64(プリスケーラーから) |
1 |
0 |
1 |
Clk T2S / 128(プリスケーラーから) |
1 |
1 |
0 |
Clk T2S / 256(プリスケーラーから) |
1 |
1 |
1 |
Clk T2S / 1024(プリスケーラーから) |
また、COM21ビットを「1」に設定し、COM20を「0」に設定することにより、比較一致時にOC2がクリアされます。
高速PWMモードの出力モード比較(COM)選択オプションを以下に示します。
COM21 |
COM21 |
説明 |
0 |
0 |
通常のポート操作、OC2は切断されています。 |
0 |
1 |
予約済み |
1 |
0 |
比較一致でOC2をクリアし、OC2をTOPに設定します |
1 |
1 |
比較一致でOC2を設定し、TOPでOC2をクリアします |
デューティサイクルを0%から100%に増やして、時間の経過とともに明るさが増加するようにします。0〜255の値を取り、OCR2ピンに送信します。
for(duty = 0; Duty <255; Duty ++)// 0から最大デューティサイクル { OCR2 = Duty; // LEDの明るさをゆっくりと上げ ます _delay_ms (10); }
同様に、デューティサイクルを100%から0%に減らして、LEDの輝度を徐々に下げます。
for(duty = 0; Duty> 255; Duty-)//最大から0のデューティサイクル { OCR2 = Duty; // LEDの明るさをゆっくりと下げ ます _delay_ms (10); }
これで、Atmega16 / 32でのPWMの使用に関するチュートリアルは終了です。