可変抵抗のツマミを回してLEDの明るさを可変します(1/2)

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


半固定抵抗とLEDを配線し、半固定抵抗の値からLEDの明るさを可変させます。
LEDはPICのCCP機能(PWM)を利用して明るさを可変させます。

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

16F1827の標準CCP機能は、CCP3とCCP4の2個が有り、ここではCCP3からPWMを出力させます。
また、拡張型CCP機能でECCP(ECCP1/ECCP2)を使った方法は次頁のこちらを参照下さい。

VRtoLED1

今回使用するピン番号は14番(VDD)と5番(VSS)と2番(CCP3)と9番(AN9)です。
9番ピンがアナログ入力で2番ピンがアナログ出力(PWM)です。

@まずは、下記図画面の様に配線しましょう。
 PICの14番ピンに電源+5V、5番ピンに電源GND(-)側、2番ピンにLEDの足が長い方を接続します。
 また、9番ピンに半固定抵抗の中央の足を接続します。

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      // 外部リセット信号は使用せずにデジタル入力(RA5)ピンとする(OFF)
#pragma config CP = OFF         // プログラムメモリーを保護しない(OFF)
#pragma config CPD = OFF        // データメモリーを保護しない(OFF)
#pragma config BOREN = ON       // 電源電圧降下常時監視機能ON(ON)
#pragma config CLKOUTEN = OFF   // CLKOUTピンをRA6ピンで使用する(OFF)
#pragma config IESO = OFF       // 外部・内部クロックの切替えでの起動はなし(OFF)
#pragma config FCMEN = OFF      // 外部クロック監視しない(FCMEN_OFF)

// コンフィギュレーション2の設定
#pragma config WRT = OFF        // Flashメモリーを保護しない(OFF)
#pragma config PLLEN = OFF      // 動作クロックを32MHzでは動作させない(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 ;	      // アナログ値読取り開始指示
     while(GO_nDONE) ;        // 読取り完了まで待つ
     temp = ADRESH ;
     temp = ( temp << 8 ) | ADRESL ;

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

     OSCCON = 0b01110010 ;    // 内部クロックは8MHzとする
     ANSELA = 0b00000000 ;    // AN0-AN4は使用しない全てデジタルI/Oとする
     ANSELB = 0b00001000 ;    // AN5-AN11はAN9のみアナログで使用し他はデジタルI/Oとする
     TRISA  = 0b00000000 ;    // ピン(RA)は全て出力に割当てる(RA5は入力のみとなる)
     TRISB  = 0b00001000 ;    // ピン(RB)はRB3(AN9)のみ入力で他は出力に割当てる
     PORTA  = 0b00000000 ;    // RA出力ピンの初期化(全てLOWにする)
     PORTB  = 0b00000000 ;    // RB出力ピンの初期化(全てLOWにする)

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

     CCPTMRS = 0b00010000 ;   // CCP3機能はTimer4を使用する
     CCP3CON = 0b00001100 ;   // PWM機能(モジュール)を使用する
     T4CON   = 0b00000010 ;   // TMR4プリスケーラ値を16倍に設定
     CCPR3L  = 0 ;            // デューティ値は0で初期化
     CCPR3H  = 0 ;
     TMR4    = 0 ;            // タイマー4カウンターを初期化
     PR4     = 124 ;          // PWMの周期を設定(1000Hzで設定)
     TMR4ON  = 1 ;            // TMR4(PWM)スタート

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

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

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

《やさしく解説》

LEDについて

VRtoLED4

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

電流制限抵抗
 LEDの順方向電流(IF)と順方向電圧(VF)がデータシート等に書いてあると思います、
 例えばIFが10mAで、VFが2.5Vで、picのアナログ出力が5Vとすると、
 (pic出力−順方向電圧)÷ 順方向電流 = 電流制限抵抗値
 よって、(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の明るさは明るくなり逆になります。
半固定抵抗の20kΩ辺りを取付ければもっとハッキリ変化が解るでしょう。

プログラムについて

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

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

__delay_us(value)
 プログラムを指定した時間だけ一時停止します。
 value:停止したい時間を指定します、単位はマイクロ秒です。
 クロック8MHz動作では98560us25231232usまでしか指定出来ません。
 __delay_msなら98ms25231msまでです。 *1)

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

アナログI/O
 アナログピンの設定は下記のレジスターにて設定します。
 ANSELA = 0b00000000 ;
     アナログ入力を行うピンA(RA0-RA4)の指定をします。
     赤数字右からAN0(17ピン),AN1(18ピン),AN2(1ピン),AN3(2ピン),AN4(3ピン)の順
     1でアナログ、0でデジタル、この設定はAN0-AN4を全てデジタルI/Oに割当
 ANSELB = 0b00001000 ;
     アナログ入力を行うピンB(RB1-RB7)の指定をします
     赤数字右からAN11(7ピン),AN10(8ピン),AN9(9ピン),AN8(10ピン),AN7(11ピン),
     AN5(12ピン),AN6(13ピン)の順
     1でアナログ、0でデジタル、この設定はAN9をアナログにするです

 次にピンの入出力を設定します。
 TRISA = 0b00000000 ;
     この設定はAN0-AN4全て出力に設定するです。
     1で入力、0で出力、右からAN0,AN1,AN2,AN3,AN4、残りはデジタルです。
 TRISB = 0b00001000 ;
     この設定はAN9のみ入力に設定するです
     右からAN11,AN10,AN9,AN8,AN7,AN5,AN6、残りはデジタルです。

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

 ADCON1 = 0b10010000 ;
     緑数字部分でA/D変換時のリファレンス電圧をどうするかの設定です。
     00:VDDのPIC電圧を使用する 10:2番ピン接続の外部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制御する設定です。
 LEDならこの位で良かろうと、適当なんですが、
 少し詳しい説明はこちらを参照して下さい。

 16F1827の標準CCPは、CCP3とCCP4の2個が有りそれぞれにTimer2/4/6の何れかを使用します。
 その設定はCCPTMRSレジスターにて行います。
 CCPTMRS = 0b00010000 ;
      赤数字部分がCCP4用設定で緑数字部分がCCP3用設定の場所です。
      Timer2=00 , Timer4=01 , Timer6=10 この設定でCCP3はTimer4を使用です。

 次の記述はCCP3はTimer4を使用する場合です。
 CCP3CON = 0b00001100 ;    // PWM機能を使用する
 T4CON   = 0b00000010 ;    // TMR4プリスケーラ値を16倍に設定
 CCPR3L  = 0 ;             // デューティ値は0で初期化
 CCPR3H  = 0 ;
 TMR4    = 0 ;             // タイマー4カウンターを初期化
 PR4     = 124 ;           // PWMの周期を設定(1000Hzで設定)
 TMR4ON  = 1 ;             // TMR4(PWM)スタート

  CCPR3L = num/4 ;   // アナログ値からのデータでデューティ値を設定
 尚、CCP4でTimer2を使用する場合は
 CCPTMRS = 0b00000000 ;    // CCP4機能はTimer2を使用する
 CCP4CON = 0b00001100 ;    // PWM機能を使用する
 T2CON   = 0b00000010 ;    // TMR2プリスケーラ値を16倍に設定
 CCPR4L  = 0 ;             // デューティ値は0で初期化
 CCPR4H  = 0 ;
 TMR2    = 0 ;             // タイマー2カウンターを初期化
 PR2     = 124 ;           // PWMの周期を設定(1000Hzで設定)
 TMR2ON  = 1 ;             // TMR2(PWM)スタート

  CCPR4L = num/4 ;   // アナログ値からのデータでデューティ値を設定
 なのでぇ、CCP3とCCP4を2個同時に使用可能ですね。

《その他》

今回は9番・2番ピンを使用しましたが他のピンを使用する場合は下記の表を参照して下さい。
また、4番ピンRA5は入力しか出来ません、出力不可です。
ポートA
ピン番号 16 15 18 17
デジタル入出力ビット名 RA7 RA6 RA5 RA4 RA3 RA2 RA1 RA0
アナログ入力ピン名 AN4 AN3 AN2 AN1 AN0
PWM 出力ピン名 CCP4 CCP3

ポートB
ピン番号 13 12 11 10
デジタル入出力ビット名 RB7 RB6 RB5 RB4 RB3 RB2 RB1 RB0
アナログ入力ピン名 AN6 AN5 AN7 AN8 AN9 AN10 AN11



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


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