TOP>MPLAB XC8編(PIC12F675)> (04)可変抵抗でLEDの明るさを制御(A/D変換,PIC12F675,XC8)
可変抵抗でLEDの明るさを制御 − A/D変換とPWM制御 −
(PIC12F675 XC8)
更新日2012.5.20
|
作成日2008.10.19
|
可変抵抗によりLEDの明るさを変える実験を行います。
可変抵抗の状態はA/D変換により読み込み、LEDの明るさ制御はPWM方式を使用します。
実験回路
|
・ |
|
|
今回の実験回路です。
クロックは内部クロックを使い4MHzとしました。
-
-
| | LEDと直列の抵抗は、300〜800Ω程度の範囲であれば明るさが変わるだけで点灯は確認できます。
|
- ブレッドボードに組んだ状態
-
| | 右下の6ピンヘッダ周りは、回路図には有りませんがICSP(In-Circuit Serial Programming)用です。秋月のPICライタなどを使う場合は不要です。
|
|
仕様
|
|
可変抵抗の出力電圧をGP0でA/D変換し、その結果でGP5のLEDの明るさを変えます。
LEDの明るさ制御はPWM方式を使いますが、PIC12F675には機能がありませんのでプログラムで制御します。
PWM制御のための基準時間はTMR0割込みを使いました。
また、GP4のLEDはパイロットランプ代わりに1秒毎に点滅させます。
|
A/D変換について
|
|
A/D変換とは、アナログ信号(電圧)をデジタルデータに変換することです。
PIC12F675では、アナログポート(AN0〜AN3)の電圧を10ビットの数値に変換する事ができます。
変換は、基準電圧を1024として測定電圧を表現します。
| |
ただし、ADresの最大値は1023です。(16進表現で、'3FF'まで)
|
例えば、基準電圧が5Vで測定電圧が2.5Vの場合、AD変換の結果(ADres)は512になります。
|
ADres | =Vin/(Vref/1024)
| | =2.5/(5/1024)
| | =512
|
|
A/D変換を行う手順は以下の通りです。
|
(1) | A/D変換機能の初期設定
以下の3つのレジスタ設定を行います。
ANSEL | A/D変換のクロック設定と、A/D変換の入力ピンを指定
| TRISIO | A/D変換で使うピンを入力モードに設定
| ADCON0 | 基準電圧の選択,A/D変換結果の格納方法指定,A/D変換の入力ピン選択を行い、A/D変換を有効に設定
|
| (2) | A/D変換準備完了を待つ
PIC内蔵のコンデンサ充電完了を待ちます。
この時間をアクィジション時間と言い、入力抵抗が10KΩの時、約20μ秒です。
| (3) | A/D変換を開始する
ADCON0レジスタのGOビットをONにしてA/D変換を開始します。
| (4) | A/D変換完了を待つ
ADCON0レジスタのGOビットがOFF(A/D変換完了)になるのを待ちます。
| (5) | A/D変換結果を使う
A/D変換結果が、ADRESH,ADRESLレジスタに格納されていますので、目的に応じて使用します。
| (6) | 繰り返す
繰り返す場合は、(2)に戻ります。
|
|
【参考】
A/D変換完了を待つ方法として、上ではADCON0レジスタのGOビットがOFFになるのを待っていますが、A/D変換完了割込みを使う方法もあります。
A/D変換完了割込みを使う場合、以下のレジスタ操作が必要です。
INTCON,PIR1,PIE1
|
基準電圧は、以下のいずれかを選択します。
| ・電源電圧Vdd
| | ・GP1/Vref(6番ピンに与える電圧)
|
どちらにするかは、ADCON0レジスタのVCFGビットで設定します。
今回は、精度は要求されませんので、電源電圧を基準電圧にしました。
A/D変換で使えるポートは、AN0〜AN3の4ポートがあります。1つだけをA/D変換で使い、他はデジタルI/Oにすることもできますし、4つ共A/D変換で使うこともできます。
この選択は、ANSELレジスタのANS0〜ANS3で指定します。
ただし、1回のA/D変換動作では、1つのポートだけを対象とする必要があり、このポート選択は、ADCON0レジスタのCHS0,CHS1で設定します。
A/D変換のクロックは、下の表の水色の範囲を指定します。
これは、PICを動作させるオシレータ(クロック)の周波数により、ANSELレジスタのADCS2〜0の設定値で選択します。
今回は、オシレータを4MHzにしましたので、8Toscを選択し2.0μ秒にしました。(下表の赤字)
-
A/Dクロック設定 | オシレータ周波数
| 動作 | ADCS2-0 | 20MHz | 5MHz | 4MHz | 1.25MHz
| 2Tosc | 000 | 100nS | 400nS | 500nS | 1.6μS
| 4Tosc | 100 | 200nS | 800nS | 1.0μS | 3.2μS
| 8Tosc | 001 | 400nS | 1.6μS | 2.0μS | 6.4μS
| 16Tosc | 101 | 800nS | 3.2μS | 4.0μS | 12.8μS
| 32Tosc | 010 | 1.6μS | 6.4μS | 8.0μS | 25.6μS
| 64Tosc | 110 | 3.2μS | 12.8μS | 16.0μS | 51.2μS
| A/D RC | x11 | 2-6μS | 2-6μS | 2-6μS | 2-6μS
|
表の水色の範囲を使用します。
A/D変換のクロックは、最低が1.6μSですので、表の青の部分は使用できません。
また、赤の部分は変換時間が必要以上に長くなります。
【ToscとFosc】
Toscはオシレータの1クロック(1サイクル)の時間であり、8Toscは1クロックの時間の8倍という意味です。
Foscはオシレータの周波数で、Fosc/8はオシレータの周波数の1/8という意味です。
|
A/D変換結果は10ビットです。一方、PICのレジスタは8ビットです。
そのままでは格納できませんので、ADRESHレジスタとADRESLレジスタの2つを連結した16ビットに格納されます。
16ビット幅に10ビットを格納しますが、以下の2パターンから選択できます。
・左詰めで下位の6ビットを0にする
・右詰めで上位の6ビットを0にする
この選択は、ADCON0レジスタのADFMビットで指定します。
今回は左詰めとし、ADRESHレジスタだけを使いました。
今までの説明を元に作った、今回のプログラムでのレジスタ初期化例です。
-
CMCON | = | 0x07; | | // コンパレータ未使用
| ANSEL | = | 0x11; | | // 8Tosc,AN0
| ADCON0 | = | 0x01; | | // Left,Vdd,AN0,ADON
| TRISIO | = | 0x0F; | | // GP0-4:in,GP4,5:out
| GPIO | = | 0;
|
|
PWM方式(LEDの明るさ制御)
|
|
PWM方式によるLEDの明るさ制御については、こちらを参考にして下さい。
今回のプログラムでは、以下のように制御します。
-
PWM周期 | : | TMR0割込み32回をPWMの周期とします。
| PWMパルス幅 | : | A/D変換結果の上位5ビットの値(0〜31)だけ、TMR0割込みをカウントしパルス幅とします。
|
TMR0割込みは、0.256mS毎に発生するよう設定します。
-
|
プログラム
|
|
プログラムの各ブロックで行っている処理は以下通りです。
- CONFIG設定
- CONFIGは以下のように設定しています。
__CONFIG(FOSC_INTRCIO & WDTE_OFF & PWRTE_ON & MCLRE_OFF);
|
クロック | : | 内部クロックでGP4,5はデジタルI/Oで使用
| WDT | : | 未使用
| パワーアップタイマ | : | 有効
| MCLRピン | : | MCLRは無効で、GP3をデジタル入力で使用
|
- main
- まずPICの初期化(pic_init)を行います。
その後、ループの中でA/D変換を行い上位5ビットをPWMのパルス幅として保存します。保存した値はTMR0割込みの中で使用します。
また、GPIO4のLEDを0.5秒毎に点滅させます。
0.5秒の時間は、TMR0割込み処理で設定する500mSフラグにより判断します。
- pic_init
- PICの初期化処理を行います。
使わないコンパレータを無効にして、GPIO4,5を出力に設定し、A/D変換とTMR0割込みの初期設定を行います。
- intr(割込み処理)
- TMR0割込みの処理を行います。
割込みをカウントし、PWMのパルス幅に達したらGPIO5に0をセットします。カウントが32になったらGPIO5に1をセットします。
割込み毎に500mSカウンタを+1し、61になったら500mSフラグを立てます。
- wait_50uS
- プログラムループにより50μ秒待ちます。
この時間は、A/D変換のアクィジション時間として使います。
電源を投入すると、緑のLEDが0.5秒間隔で点滅します。
ボリュームを回すと、赤のLEDの明るさが変わります。
正しく動作しましたか?
|