可変抵抗のツマミを回してLEDの明るさを可変します

〔PICの動かせ方入門に戻る〕


半固定抵抗とLEDを配線し、半固定抵抗の値からLEDの明るさを可変させます。
LEDはPIC12F1501のPWM機能を利用して明るさを可変させます。
12F1822ではCCP1のPWM機能を利用していましたが、このPWMは1個のみの出力でした。
12F1501では4個のPWM出力(PWM1/2/3/4)が出来る様になっています。
今回はPWM1を使います(レジスター名が異なるだけで12F1822の場合と操作は同じです)。

こちらのHPサイト「合同会社パレットソフト」さんのページにLEDとPWM制御について 解りやすく書いて有ります、”LEDの輝度調整”の項を参考にして下さい。

VRtoLED1

今回使用するピン番号は1番(VDD)と8番(VSS)と5番(PWM1)と3番(AN3)です。
3番ピンがアナログ入力で5番ピンがアナログ出力(PWM)です。

@まずは、下記図画面の様に配線しましょう。
 図は、12F675ですが12F1501も同じ配線になります。
 PICの1番ピンに電源+5V、8番ピンに電源GND(-)側、5番ピンにLEDの足が長い方を接続します。
 また、3番ピンに半固定抵抗の中央の足を接続します。

VRtoLED2 VRtoLED3

AMPLAB X(v2.15)を起動させます。

B下記がプログラムソースです、
MPLAB(R) XC8 C Compiler Version 1.32コンパイラを使用しています。
 プロジェクトを作成して新規ファイルにコピーペーストして貼り付けて下さい。
 プログラムソースをダウンロードしてプロジェクトに取込む事も出来ます。 *1)
---------------------------------------------------------------------
#include <xc.h>

#define _XTAL_FREQ 8000000    //  delay用に必要(クロック8MHzを指定)

// コンフィギュレーション1の設定
#pragma config FOSC     = INTOSC   // 内部クロック使用する(INTOSC)
#pragma config WDTE     = OFF      // ウオッチドッグタイマー無し(OFF)
#pragma config PWRTE    = ON       // 電源ONから64ms後にプログラムを開始する(ON)
#pragma config MCLRE    = OFF      // 外部リセット信号は使用せずにデジタル入力(RA3)ピンとする(OFF)
#pragma config CP       = OFF      // プログラムメモリーを保護しない(OFF)
#pragma config BOREN    = ON       // 電源電圧降下常時監視機能ON(ON)
#pragma config CLKOUTEN = OFF      // CLKOUTピンをRA4ピンで使用する(OFF)

// コンフィギュレーション2の設定
#pragma config LPBOR  = OFF        // 低消費電力ブラウンアウトリセット(OFF)
#pragma config WRT    = OFF        // Flashメモリーを保護しない(OFF)
#pragma config STVREN = ON         // スタックがオーバフローやアンダーフローしたらリセットをする(ON)
#pragma config BORV   = HI         // 電源電圧降下常時監視電圧(2.5V)設定(HI)
#pragma config LVP    = OFF        // 低電圧プログラミング機能使用しない(OFF)

// アナログ値の入力処理
unsigned int adconv()
{
     unsigned int temp;

     GO_nDONE = 1 ;         // PICにアナログ値読取り開始を指示
     while(GO_nDONE) ;      // PICが読取り完了するまで待つ
     temp = ADRESH ;        // PICは読取った値をADRESHとADRESLのレジスターにセットする
     temp = ( temp << 8 ) | ADRESL ;  // 10ビットの分解能力です

     return temp ;
}
// メインの処理
void main()
{
     unsigned int num ;

     OSCCON = 0b01110000 ;  // 内部クロックは8MHzとする
     ANSELA = 0b00010000 ;  // アナログはAN3を使用し、残りをすべてデジタルI/Oに割当
     TRISA  = 0b00010000 ;  // AN3(RA4)だけ入力その他のピンは出力に割当てる(RA3は入力専用)
     PORTA  = 0b00000000 ;  // 出力ピンの初期化(全てLOWにする)

     // A/Dの設定
     ADCON1 = 0b10010000 ;  // 読取値は右寄せ、A/D変換クロックはFOSC/8、VDDをリファレンスに
     ADCON0 = 0b00001101 ;  // アナログ変換情報設定(AN3から読込む)
     __delay_us(5) ;        // アナログ変換情報が設定されるまでとりあえず待つ

     // PWM1の設定
     PWM1CON = 0b11000000 ; // PWM1機能を使用する(output is active-high)
     PWM1DCH = 0 ;          // デューティ値は0で初期化
     PWM1DCL = 0 ;
     T2CON   = 0b00000010 ; // TMR2プリスケーラ値を16倍に設定
     TMR2    = 0 ;          // タイマー2カウンターを初期化
     PR2     = 124 ;        // PWMの周期を設定(1000Hzで設定)
     TMR2ON  = 1 ;          // TMR2(PWM)スタート

     while(1) {
          num = adconv() ;  // 3番ピン(AN3)から半固定抵抗の値を読み込む
          PWM1DCH = num/4 ; // アナログ値からのデータでデューティ値を設定
     }
}
---------------------------------------------------------------------

CコンパイルPIC書き込みを実行して下さい。

DPICをブレッドボードに取付けて、抵抗のツマミを回して下さいLEDの明るさが変わると思います。

《やさしく解説》

LEDについて

VRtoLED4

LEDには極性が有ります、
足の長いアノード側を5番ピンの方に、足の短いカソード側を電流制限抵抗の方に接続します。
また、LEDには流せる電圧と電流が決まっています、必ず電流制限抵抗を付けましょう。

電流制限抵抗
 LEDの順方向電流(IF)と順方向電圧(VF)がデータシート等に書いてあると思います、
 例えばIFが10mAで、VFが2.5Vで、arduinoのアナログ出力が5Vとすると、
 (arduino出力−順方向電圧)÷ 順方向電流 = 電流制限抵抗値
 よって、(5V - 2.5V) ÷ 0.010A = 250Ω(250Ωは無いので240Ωか270Ωを使います)
 10mAは0.010AというふうにAに変換して計算します。

 だいたい120Ω〜680Ωのあたりだと思います。
 LEDは5mAくらいで使った方が目に優しいでしょう、で470Ω?
 また、抵抗はLEDのアノード側とカソード側のどちら側に接続してもOKです。

 注意) PICの出力は20mA程しか流せません、これ以上のLED電流を流す場合は
     PICの出力をトランジスタで一旦受けてからLEDをつながないといけません。
     マイコン出力をトランジスタで一旦受ける場合はこちらを参考にして下さい。

半固定抵抗について

アナログ入力は電圧の0〜5Vを0〜1023の値に変換して読み込みます。
半固定抵抗は今回10kΩを使用で、だいたい60〜530位で読み込まれます。

ツマミを右に回せばLEDの明るさは暗くなり、左に回せば明るくなります。
また、半固定抵抗の配線を5V(赤線)とGND(黒線)で入れ替えると、
右に回しでLEDの明るさは明るくなり逆になります。

プログラムについて

プログラムソースのコメントを読んでもらえば大体何をしているのか分かると思います。

while(1)
 main()の中の処理は1回実行すると終了します、
 だからwhile(1)の、{ }の中に処理を書き込めば無限に繰り返します。
 もしwhile(1)を記述しないとプログラムはすぐ終了し、ツマミを回してもLEDは点滅しません。

__delay_us(value)
 プログラムを指定した時間だけ一時停止します。
 value:停止したい時間を指定します、単位はマイクロ秒です。
 クロック8MHz動作では25231232usまでしか指定できません。
 __delay_msなら25msまでです。

adconv()
 アナログの値を読み取ります、値は0〜1023(60-530)の範囲です。

アナログI/O
 アナログピンの設定は下記のレジスターにて設定します。
 ANSELA = 0b00010000 ; アナログ入力を行うピンの指定をします
               赤数字右からAN0(7ピン),AN1(6ピン),AN2(5ピン),AN3(3ピン)の順
               1でアナログ、0でデジタル、この設定例はAN3をアナログで使用するです。

 指定したAN3のアナログピンを入力に指定するには下記のレジスターにて設定します。
 TRISA = 0b00010000 ; この設定はAN3のみ入力に設定するです。
               1で入力、0で出力、右からAN0,AN1,AN2,x,AN3

アナログ変換情報設定
 ADCON0 = 0b00001101 ; この設定でAN3から読込めと指示しています
               他のAN3以外から読込みたい場合は、赤数字の部分を変更します。
               AN0=00000,AN1=00001,AN2=00010,AN3=00011 と変更して下さい。
               赤数字の部分以外の設定は今回このまま使用して下さい。
               また、ADCON0の設定には5usほどかかります、delayを入れておきましょう。

 ADCON1 = 0b10010000 ;
               緑数字部分でA/D変換時のリファレンス電圧をどうするかの設定です。
               00:VDDのPIC電圧を使用する 10:6番ピン接続の外部VREFを使用する。
               11:PIC内蔵の固定電圧をしようする。
               赤数字部分でA/D変換を行う速度のクロックを設定します。
               000:FOSC/2 001:FOSC/8  010:FOSC/32
               100:FOSC/4 101:FOSC/16 110:FOSC/64
               また、それ以外の数字部分の設定は今回このまま使用して下さい。

PWM機能設定
 PWMを使用する為には以下の設定が必要です、
 この設定は1KHzの周波数で、PWM制御する設定です。
 少し詳しい説明はこちらを参照して下さい。
 PWM1以外を使用する場合はレジスター名(PWM1/PWM2/PWM3/PWM4)を変更して下さい。
 PWM1CON = 0b11000000 ;    // PWM1機能を使用する(output is active-high)
 T2CON   = 0b00000010 ;    // TMR2プリスケーラ値を16倍に設定
 PWM1DCL = 0 ;             // デューティ値は0で初期化
 PWM1DCH = 0 ;
 TMR2    = 0 ;             // タイマー2カウンターを初期化
 PR2     = 124 ;           // PWMの周期を設定(1000Hzで設定)
 TMR2ON  = 1 ;             // TMR2(PWM)スタート

 PWM1DCH = num/4 ; この行でPWMのデューティ値を変更しています。

《その他》

今回は3番・5番ピンを使用しましたが他のピンを使用する場合は下記の表を参照して下さい。
ピン番号
デジタル入出力ビット名 RA0 RA1 RA2 RA3 RA4 RA5
アナログ入力ピン名 AN0 AN1 AN2 AN3
アナログ出力ピン名 PWM2 PWM1 PWM3 PWM4




MPLAB X用に記事変更(*1) 2015/10/02


【きむ茶工房ガレージハウス】
Copyright (C) 2006-2015 Shigehiro Kimura All Rights Reserved.