目次>8章.機能が豊富なPICを使う(PIC16F88)>汎用PWMコントローラ
汎用PWMコントローラ
更新日2009.6.27
ここではPIC16F88のPWM(Pulse Width Modulation)機能を使った実験を行います。
PIC16F88には、CCP(CAPTURE/COMPARE/PWM)と言うモジュールが内蔵されていて、この中のPWM機能を使うとPWM信号を容易に出力できます。
PWMとは
|
・ |
下図ように、周期は一定にしてパルスの幅を変える方式を、PWM(Pulse Width Modulation:パルス幅変調)と言います。
-
パルス幅(ONの割合)が大きいほど出力の総量が大きくなるので、DCモータのスピード制御やLEDの明るさ制御などに使用されます。
-
PWM信号 | 制御対象 例
| LED | DCモータ
|
| 明るい | 高速
|
| 暗い | 低速
|
また、パルス幅に意味を持たせて制御するものとしてサーボモータなどがあります。
|
CCPモジュールとPWMモード
|
|
PIC16F88にはCCPモジュールが内蔵されています。
- CCPモジュールは、レジスタの設定で以下の3種類の動作を選択できます。
キャプチャモード | CCP1ピンの変化によりTMR1(TMR1H:TMR1L)レジスタの内容をCCPR1(CCPR1H:CCPR1L)レジスタにコピーし、キャプチャ割込みを発生する
| コンペアモード | TMR1(TMR1H:TMR1L)レジスタとCCPR1(CCPR1H:CCPR1L)レジスタの値が一致した時、CCP1ピンを変化させたりCCP1割込みを発生させる
| PWMモード | PR2レジスタで指定する周期と、CCPR1Lレジスタで指定するパルス幅により、CCP1ピンからパルス(矩形波)を出力する
|
今回は、PWMモードを使用します。
PIC16F88では、以下のようにPWMを実現しています。
PR2レジスタでPWMの周期を指定し、CCPR1Lレジスタでパルス幅を指定します。
それぞれのレジスタで指定する値は、TMR2のカウント数です。
従って、TMR2の周波数(または周期)を決定すると、PWMの周期とパルス幅の範囲が決まります。
TMR2は1命令サイクル毎に+1され、PR2レジスタの値と等しくなったらリセットされます。
- 具体例を以下に示します。
-
クロック周波数 | :4MHz
| PR2 | :239
| CCPR1L | :50
| TMR2プリスケーラ | :1
|
命令サイクル | :(1秒/4MHz)×4クロック=1uS(マイクロ秒)
| PWM周期 | :1uS(マイクロ秒)×(239+1)=240uS
実際の周期は、PR2レジスタの値+1となります。
| PWM周波数 | :1秒/240uS=4167Hz
| PWMパルス幅 | :1uS(マイクロ秒)×50=50uS
|
下の図は、PWM関連のレジスタを表しています。(データシートからの抜粋)
| | |
設定するレジスタは、一番上のCCPR1Lレジスタ(パルス幅)と一番下のPR2レジスタ(周期)です。
コンパレータが2つありますが、下のコンパレータはTMR2とPR2レジスタを比較し、周期のタイミングを作っています。
上のコンパレータは、TMR2とCCPR1H(間接的にCCPR1L)レジスタを比較し、パルス幅のタイミングを作っています。
|
- 補足1
-
TMR2は、プリスケーラを使用できます。
プリスケーラを使う場合、倍率は4倍/16倍の2種類で、T2CONレジスタで指定します。
- 補足2 (良く分からない場合は読み飛ばしても大丈夫です)
-
実際のパルス幅指定は、CCPR1Lレジスタ8ビットの下位にCCP1CONレジスタのビット5:4(CCP1X,CCP1Y)の2ビットを付加した10ビットでの指定になります。
また、TMR2がパルス幅と比較される場合は、TMR2レジスタ8ビットの下位に2ビットが付加され10ビットで使用されます。この10ビットは、1クロック毎にカウントアップされます。
従って、パルス幅の分解能は10ビットになります。
|
実験回路
|
・ |
今回の実験回路です。
RB3をCCP1ピンとして使い、PWM信号を出力します。
- RA3,RA4はA/D変換で使います。可変抵抗を接続し、電圧に対応してPWMの周期とパルス幅を決定します。
- RA3(AN3)A/D変換結果 → PWMの周期
RA4(AN4)A/D変換結果 → PWMのパルス幅
RA2のスイッチは、クロック切り替え用です。今回は内部クロック動作とし、1,2,4,8MHzをスイッチで選択します。
2つのA/D変換結果やクロックの状態をLCDに表示します。
-
上の回路のRB3からPWM信号を出力します。
ここに接続するものを変える事で色々な事ができます。下はその例です。
LEDの 明るさ制御 | 高輝度LEDの 明るさ制御 | DCモータの スピード制御 | サーボモータの 制御 | 音を出す | 音を出す
| | | | | |
|
- ブレッドボードに組んだ状態。
RB3にはLEDを接続しています。(上の例の一番左の回路) -
| 左上の6ピンのヘッダピン周りはICSP用回路です。
|
|
プログラムの仕様
|
|
AN3(RA3)とAN4(RA4)の電圧をA/D変換し、その結果でPWMの周期とパルス幅を決定します。
A/D変換結果は10ビットになりますが、上位8ビットを使います。
-
AN3 A/D変換結果 | → PR2レジスタ
| AN4 A/D変換結果 | → CCPR1Lレジスタ
|
また、RA2のスイッチを押す毎にクロックの周波数を8→4→2→1MHzと変化させます。
- クロック周波数変更に合わせて、以下の時間に関する定数を再設定します。
- ・A/D変換の基準時間(TAD)
・ウェイトルーチン(時間待ち)のループカウント値
- クロック周波数とPWMの周期(周波数)の関係は以下のようになります。
-
TMR2プリスケーラ=16
PR2=10の場合
クロック周波数 (MHz) | PWM
| 周期(uS) | 周波数(Hz)
| 8 | 88 | 11,364
| 4 | 176 | 5,682
| 2 | 352 | 2,841
| 1 | 704 | 1,420
|
|
TMR2プリスケーラ=16
PR2=255の場合
クロック周波数 (MHz) | PWM
| 周期(uS) | 周波数(Hz)
| 8 | 2,048 | 488
| 4 | 4,096 | 244
| 2 | 8,192 | 122
| 1 | 16,384 | 61
|
|
出力できる周波数は、約60〜11000Hzであり、スピーカをつなげた実験に使えます。
また、周期の最大は約16mSであり、サーボモータの実験も可能です。
周波数を可変にした理由はこのあたりから来ています。
|
プログラムの作成
|
|
A/D変換については、A/D変換を使うを参照して下さい。
また、LCDの使い方は、液晶ディスプレイを使うを参考にして下さい。
ここでは主に、PWM機能で使うレジスタの設定について説明します。
- PWM機能で使う基本的なレジスタは以下の4つです。
-
レジスタ | 設定内容
| CCP1CON | CCP1CONレジスタでは、CCPモジュールの動作を指定します。
| T2CON | T2CONレジスタでは、TMR2の動作を設定します。
| PR2 | PR2レジスタでは、PWMの周期を指定します。
| CCPR1L | CCPR1Lレジスタでは、PWMのパルス幅を指定します。
|
TMR2割込みを使う場合は、INTCON,PIR1,PIE1レジスタも使います。(今回は使いません)
- <CCP1CONレジスタ>
-
ビット | Bit7 | Bit6 | Bit5 | Bit4 | Bit3 | Bit2 | Bit1 | Bit0
| 記号 | - | - | CCP1X | CCP1Y | CCP1M3 | CCP1M2 | CCP1M1 | CCP1M0
| 設定値 | 0 | 0 | 0 | 0 | 1 | 1 | 0 | 0
|
CCP1CONレジスタでは、CCPモジュールの動作を指定します。
- CCP1X,CCP1Y
-
CCPR1Lレジスタの下位に連結されるビットで、合計10ビットでパルス幅を設定します。
今回は00固定としました。
- CCP1M3-0
-
CCPモジュールの動作を指定します。
CCP1M3-0 | 動 作
| 0000 | CCPモジュール未使用
| 0100 | キャプチャモード(立下りエッジ)
| 0101 | キャプチャモード(立ち上がりエッジ)
| 0110 | キャプチャモード(立ち上がりエッジ4回毎)
| 0111 | キャプチャモード(立ち上がりエッジ16回毎)
| 1000 | コンペアモード(出力セット,CCP1IFセット)
| 1001 | コンペアモード(出力クリア,CCP1IFセット)
| 1010 | コンペアモード(出力変化無し,CCP1IFセット)
| 1011 | コンペアモード(出力変化無し,CCP1IFセット,TMR1リセット,A/Dモジュールが有効ならA/D変換開始)
| 11xx | PWMモード
|
今回は、PWMモードで使用しますので、CCP1M3-0に1100を設定します。
- <T2CONレジスタ>
-
ビット | Bit7 | Bit6 | Bit5 | Bit4 | Bit3 | Bit2 | Bit1 | Bit0
| 記号 | - | TOUTPS3 | TOUTPS2 | TOUTPS1 | TOUTPS0 | TMR2ON | T2CKPS1 | T2CKPS0
| 設定値 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 1
|
T2CONレジスタでは、TMR2の動作を設定します。
- TOUTPS3-0
-
TMR2の出力ポストスケーラで1〜16倍の範囲が設定できます。(TMR2のリセット何回でTMR2割込みを発生させるか)
今回はTMR2割込みを使いませんので何をセットしてもかまいません。
- TMR2ON
-
このビットをセット(1)することでTMR2が動作します。
- T2CKPS1-0
-
TMR2のプリスケーラで1,4,16倍の範囲が設定できます。
今回は16倍で使います。(16命令サイクル毎にTMR2を+1する)
T2CKPS1-0 | プリスケーラ
| 00 | 1
| 01 | 4
| 1x | 16
|
- <PR2レジスタ>
-
ビット | Bit7 | Bit6 | Bit5 | Bit4 | Bit3 | Bit2 | Bit1 | Bit0
| 記号 | PWM周期
| 設定値 | AN3のA/D変換結果(上位8ビット)
|
PR2レジスタでは、PWMの周期を指定します。
- <CCPR1Lレジスタ>
-
ビット | Bit7 | Bit6 | Bit5 | Bit4 | Bit3 | Bit2 | Bit1 | Bit0
| 記号 | PWMパルス幅
| 設定値 | AN4のA/D変換結果(上位8ビット)
|
CCPR1Lレジスタでは、PWMのパルス幅を指定します。
__CONFIG命令では以下の記述をします。
__CONFIG _CONFIG1, _WDT_OFF & _BODEN_ON & _PWRTE_ON & _INTRC_IO & _CCP1_RB3 & _LVP_OFF
|
-
_WDT_OFF | ウォッチドックタイマ使用しない
| _BODEN_ON | 電源電圧低下監視を有効にする
| _PWRTE_ON | パワーアップタイマを有効にする
| _INTRC_IO | オシレータは内部クロック使用(15番ピン:RA6,16番ピン:RA7)
| _CCP1_RB3 | CCPの出力ピンはRB3を使用(省略するとRB0になる)
| _LVP_OFF | 低電圧プログラミング無効
|
|
プログラム全体
|
|
概略処理フローを以下に載せておきます。
-
|
実験風景
|
|
LEDを接続し、明るさ制御の確認をしているところ。
-
| | Pは周期、Wはパルス幅です。表示は両方とも16進数です。 商品化するのであればミリ秒単位とかで表示させる所です。
|
圧電スピーカ(圧電サウンダ)も同時に接続すれば、音でも動作が確認できます。
LEDだけだとクロックを切り替えても変化が見えませんが、圧電スピーカを接続すると周波数の変化が良く分かります。
サーボモータを使う場合は、周期とパルス幅を特定の値にする必要があります。
サーボモータの制御を参考にして下さい。
|