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

(2/2) 〔PICの動かせ方入門に戻る〕


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

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

18F25K22(18F2xK22)の標準CCP機能は、CCP4とCCP5の2個が有り、ここではCCP4からPWMを出力させます。
また、拡張型CCP機能でECCP(ECCP1/ECCP2/ECCP3)を使った方法は次頁のこちらを参照下さい。
VRtoLED1
 左図はPIC18F25K22のピン構成です。

 今回使用するピン番号は20番(VDD)と8/19番(VSS)を
 電源に配線します。
 CCP出力は6番(CCP5)と21番(CCP4)でが今回はCCP4
 を使用します。
 それと14番(AN15)ピンがアナログ入力です。

VRtoLED2  左図は18F25K22での配線図ですが、
 18F23K22/18F24K2218F26K22も同じです。

 LEDは足が長い方をPIC側に配線です。
 半固定抵抗は10KΩでもOKです。


(サンプルプログラム1)

LEDを約1秒毎に点滅させるプログラムです、このプログラムでは半固定抵抗は使用しません。

@下記がプログラムソースです、
  MPLAB(R) XC8 C Compiler Version 1.38コンパイラを使用しています。
  MPLAB X IDEでプロジェクトを作成して新規ファイルにコピーペーストして貼り付けて下さい。 *1)
---------------------------------------------------------------------
#include <xc.h>

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

// コンフィギュレーションの設定(ここの記述に無い設定はデフォルト値での動作)
// 外部クロックは使用しない(PRICLKEN_OFF)
// 動作クロックを4倍では動作させない(PLLCFG_OFF):内部部クロックを使用する(INTIO67)
#pragma config PRICLKEN=OFF,PLLCFG=OFF,FOSC=INTIO67    // CONFIG1H
// 電源電圧降下常時監視機能ON(BOREN_NOSLP):監視電圧は(2.85V)に設定
// 電源ONから後65.6msにプログラムを開始する(PWRTEN_ON)
#pragma config BOREN=NOSLP,BORV=285,PWRTEN=ON          // CONFIG2L
// ウオッチドッグタイマー無し(WDTEN_OFF)
#pragma config WDTEN=OFF                               // CONFIG2H
// 外部リセット信号は使用せずにデジタル入力(RE3)ピンとする(MCLRE_INTMCLR)
// オシレータが安定するのを待ってシステムクロックを供給する(HFOFST_OFF)
#pragma config MCLRE=INTMCLR,HFOFST=OFF                // CONFIG3H
// 低電圧プログラミング機能使用しない(LVP_OFF)
#pragma config LVP=OFF                                 // CONFIG4L

// 指定した時間(num x 10ms)だけウエイトを行う処理関数
void Wait(unsigned int num)
{
     int i ;

     // numで指定した回数だけ繰り返す
     for (i=0 ; i < num ; i++) {
          __delay_ms(10) ;    // 10msプログラムの一時停止
     }
}
// メインの処理
void main()
{
     OSCCON = 0b01110010 ;    // 内部クロックとする(16MHz)
     ANSELA = 0b00000000 ;    // AN0-4 アナログは使用しない、デジタルI/Oに割当
     ANSELB = 0b00000000 ;    // AN8-13アナログは使用しない、デジタルI/Oに割当
     ANSELC = 0b00000000 ;    // AN14-19アナログは使用しない、デジタルI/Oに割当
     TRISA  = 0b00000000 ;    // RA0-RA7全て出力に設定、1で入力 0で出力
     TRISB  = 0b00000000 ;    // RB0-RB7全て出力に設定
     TRISC  = 0b00000000 ;    // RC0-RC7全て出力に設定 
     PORTA  = 0b00000000 ;    // 出力ピンの初期化(全てLOWにする)
     PORTB  = 0b00000000 ;    // 出力ピンの初期化(全てLOWにする)
     PORTC  = 0b00000000 ;    // 出力ピンの初期化(全てLOWにする)

     while(1) {
          LATB0 = 1 ;         // 21番ピン(RB0)にHIGH(5V)を出力する(LED ON)
          Wait(100) ;         // 1秒ウエイト
          LATB0 = 0 ;         // 21番ピン(RB0)にLOW(0V)を出力する(LED OFF)
          Wait(100) ;         // 1秒ウエイト
     }
}
---------------------------------------------------------------------
AコンパイルPIC書き込みを実行して下さい。 *1)

BPICをブレッドボードに取付けて下さい、LEDが1秒毎に点滅すると思います。

(サンプルプログラム2)

今度が本番のプログラムで、半固定抵抗の値でLEDの明るさを可変させます。
CCP機能のCCP4でPWM信号(1KH)を生成し21番端子から出力してLEDの明るさを可変します。
CCP4のPWM生成にはタイマー2を使用し、PWMのデューティ比は半固定抵抗の値を使用します。

@下記がプログラムソースです、
  MPLAB X IDEでプロジェクトを作成して新規ファイルにコピーペーストして貼り付けて下さい。 *1)
---------------------------------------------------------------------
#include <xc.h>

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

// コンフィギュレーションの設定(ここの記述に無い設定はデフォルト値での動作)
// 外部クロックは使用しない(PRICLKEN_OFF)
// 動作クロックを4倍では動作させない(PLLCFG_OFF):内部部クロックを使用する(INTIO67)
#pragma config PRICLKEN=OFF,PLLCFG=OFF,FOSC=INTIO67    // CONFIG1H
// 電源電圧降下常時監視機能ON(BOREN_NOSLP):監視電圧は(2.85V)に設定
// 電源ONから後65.6msにプログラムを開始する(PWRTEN_ON)
#pragma config BOREN=NOSLP,BORV=285,PWRTEN=ON          // CONFIG2L
// ウオッチドッグタイマー無し(WDTEN_OFF)
#pragma config WDTEN=OFF                               // CONFIG2H
// 外部リセット信号は使用せずにデジタル入力(RE3)ピンとする(MCLRE_INTMCLR)
// オシレータが安定するのを待ってシステムクロックを供給する(HFOFST_OFF)
#pragma config MCLRE=INTMCLR,HFOFST=OFF                // CONFIG3H
// 低電圧プログラミング機能使用しない(LVP_OFF)
#pragma config LVP=OFF                                 // CONFIG4L

// アナログ値の変換と読込み処理
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 ;    // 内部クロックとする(16MHz)
     ANSELA = 0b00000000 ;    // AN0-4 アナログは使用しない、デジタルI/Oに割当
     ANSELB = 0b00000000 ;    // AN8-13アナログは使用しない、デジタルI/Oに割当
     ANSELC = 0b00001000 ;    // AN14-19アナログは使用しない、AN15のみアナログで使用
     TRISA  = 0b00000000 ;    // RA0-RA7全て出力に設定、1で入力 0で出力
     TRISB  = 0b00000000 ;    // RB0-RB7全て出力に設定
     TRISC  = 0b00001000 ;    // RC3のみ入力、それ以外RC0-RC7は出力に設定 
     PORTA  = 0b00000000 ;    // 出力ピンの初期化(全てLOWにする)
     PORTB  = 0b00000000 ;    // 出力ピンの初期化(全てLOWにする)
     PORTC  = 0b00000000 ;    // 出力ピンの初期化(全てLOWにする)
     // アナログ入力の設定
     ADCON1 = 0b00000000 ;    // VDDをリファレンスとする
     ADCON2 = 0b10010101 ;    // 読取値は右寄せ、A/D変換クロックはFOSC/16、4TAD後に変換開始
     ADCON0 = 0b00111101 ;    // アナログ変換情報設定(AN15から読込む)
     __delay_us(8) ;          // アナログ変換情報が設定されるまでとりあえず待つ
     // CCP4(PWM)の設定
     CCPTMRS1 = 0b00000000 ;  // CCP4機能はTimer2を使用する
     CCP4CON  = 0b00001100 ;  // PWM機能(モジュール)を使用する
     T2CON    = 0b00000010 ;  // TMR2プリスケーラ値を16倍に設定
     CCPR4L   = 0 ;           // デューティ値は0で初期化
     CCPR4H   = 0 ;
     TMR2     = 0 ;           // タイマー2カウンターを初期化
     PR2      = 249 ;         // PWMの周期を設定(1000Hzで設定)
     TMR2ON   = 1 ;           // TMR2(PWM)スタート

     while(1) {
          num = adconv() ;    // 14番ピン(AN15)から半固定抵抗の値を読み込む
          CCPR4L = num/4 ;    // アナログ値からのデータでデューティ値を設定
     }
}
---------------------------------------------------------------------
AコンパイルPIC書き込みを実行して下さい。 *1)

BPICをブレッドボードに取付けて、半固定抵抗を回して見て下さいLEDの明るさが変わると思います。

《やさしく解説》

LEDについて

VRtoLED4

LEDには極性が有ります、
足の長いアノード側を21番ピンの方に、足の短いカソード側を電流制限抵抗の方に接続します。
また、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:停止したい時間を指定します、単位はマイクロ秒です。
 クロック16MHz動作では49280usまでしか指定できません。
 __delay_msなら49msまでです。

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

アナログI/O
 アナログピンの設定は下記のレジスターにて設定します。(デフォルトはアナログ入力です)
 ANSELA = 0b00000000 ; アナログ入力を行うピンA(RA0-RA3/RA5)の指定をします
               赤数字右からAN0(2ピン),AN1(3ピン),AN2(4ピン),AN3(5ピン),AN4(7ピン)の順
               1でアナログ、0でデジタル、この設定はAN0-AN4を全てデジタルI/Oに割当
 ANSELB = 0b00000000 ; アナログ入力を行うピンB(RB0-RB5)の指定をします
               赤数字右からAN12(21ピン),AN10(22ピン),AN8(23ピン),AN9(24ピン),AN11(25ピン),
               AN13(26ピン)の順
               1でアナログ、0でデジタル、この設定はAN8-AN13を全てデジタルI/Oに割当
 ANSELC = 0b00001000 ; アナログ入力を行うピンB(RC2-RC7)の指定をします
               赤数字右からAN14(13ピン),AN15(14ピン),AN16(15ピン),AN17(16ピン),
               AN18(17ピン),AN19(18ピン)の順
               1でアナログ、0でデジタル、この設定はAN15をアナログにするです

 次にピンの入出力を設定します。(デフォルトは入力です)
 TRISA = 0b00000000 ; この設定はAN0-AN4全て出力に設定するです
               1で入力、0で出力、右からAN0,AN1,AN2,AN3,AN4、残りはデジタルです。
 TRISB = 0b00000000 ; この設定はAN8-AN13全て出力に設定するですす
               右からAN12,AN10,AN8,AN9,AN11,AN13、残りはデジタルです。
 TRISC = 0b00001000 ; この設定はAN15のみ入力に設定するです
               右からAN14,AN15,AN16,AN17,AN18,AN19、残りはデジタルです。

アナログ変換情報設定
 ADCON0 = 0b00111101 ; この設定でAN15から読込めと指示しています
               他のAN15以外から読込みたい場合は、赤数字の部分を変更します。
               AN0=00000,AN1=00001,AN2=00010,AN3=00011,AN4=00100,
               AN8=01000,AN9=01001,AN10=01010,AN11=01011,AN12=01100,AN13=01101,
               AN14=01110,AN15=01111,AN16=10000,AN17=10001,AN18=10010,
               AN19=10011 と変更して下さい。
               緑数字の部分は、1=アナログ変換有効 0=アナログ変換無効
               また、ADCON0の設定には8usほどかかります、delayを入れておきましょう。

 ADCON1 = 0b00000000 ;
               赤数字部分でA/D変換時の+側リファレンス電圧をどうするかの設定です。
               00:VDDのPIC電圧を使用する 01:5番ピン接続の外部VREF+を使用する。
               10:PIC内蔵の固定電圧を使用する。
               緑数字部分でA/D変換時の−側リファレンス電圧をどうするかの設定です。
               00:VDDのPIC電圧を使用する 01:4番ピン接続の外部VREF-を使用する。
               また、それ以外の数字部分の設定は今回このまま使用して下さい。

 ADCON2 = 0b10010101 ;
               赤数字部分で変換開始までの待ち時間(A/Dアクイジション時間)を設定する。
               とり合えずぅ4TAD(010)辺りで良いでしょう。
               緑数字部分で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ならこの位で良かろうと、適当なんですが、
 少し詳しい設定の説明はこちらを参照して下さい。

 18F25K22の標準CCPは、CCP4とCCP5の2個が有りそれぞれにTimer2/4/6の何れかを使用します。
 その設定はCCPTMRS1レジスターにて行います。
 CCPTMRS1 = 0b00000000 ;
               赤数字部分がCCP5用設定で緑数字部分がCCP4用設定の場所です。
               Timer2=00 , Timer4=01 , Timer6=10 (デフォルトはTimer2)

 次の記述例はCCP4はTimer2を使用する場合です。
 CCPTMRS1 = 0b00000000 ;  // CCP4機能はTimer2を使用する
 CCP4CON  = 0b00001100 ;  // PWM機能(モジュール)を使用する
 T2CON    = 0b00000010 ;  // TMR2プリスケーラ値を16倍に設定
 CCPR4L   = 0 ;           // デューティ値は0で初期化
 CCPR4H   = 0 ;
 TMR2     = 0 ;           // タイマー2カウンターを初期化
 PR2      = 249 ;         // PWMの周期を設定(1000Hzで設定)
 TMR2ON   = 1 ;           // TMR2(PWM)スタート

  CCPR4L = num/4 ;       // アナログ値からのデータでデューティ値を設定
 尚、CCP5でTimer4を使用する場合は
 CCPTMRS1 = 0b00000100 ;   // CCP5機能はTimer4を使用する
 CCP5CON  = 0b00001100 ;   // PWM機能を使用する
 T4CON    = 0b00000010 ;   // TMR4プリスケーラ値を16倍に設定
 CCPR5L   = 0 ;            // デューティ値は0で初期化
 CCPR5H   = 0 ;
 TMR4     = 0 ;            // タイマー4カウンターを初期化
 PR4      = 249 ;          // PWMの周期を設定(1000Hzで設定)
 TMR4ON   = 1 ;            // TMR4(PWM)スタート

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

《その他》

今回は14番・21番ピンを使用しましたが他のピンを使用する場合は下記の表を参照して下さい。
また、1番ピンは外部からのリセット端子ですが、コンフィグで MCLRE = INTMCLR を記述すれば
RE3のデジタル入力端子として利用できます。
ポートA
ピン番号 10
デジタル入出力ビット名 RA7 RA6 RA5 RA4 RA3 RA2 RA1 RA0
アナログ入力ピン名 AN4 AN3 AN2 AN1 AN0
PWM 出力ピン名 CCP5

ポートB
ピン番号 28 27 26 25 24 23 22 21
デジタル入出力ビット名 RB7 RB6 RB5 RB4 RB3 RB2 RB1 RB0
アナログ入力ピン名 AN13 AN11 AN9 AN8 AN10 AN12
PWM 出力ピン名 CCP4

ポートC
ピン番号 18 17 16 15 14 13 12 11
デジタル入出力ビット名 RC7 RC6 RC5 RC4 RC3 RC2 RC1 RC0
アナログ入力ピン名 AN19 AN18 AN17 AN16 AN15 AN14



リンクの見直し(*1) 2017/01/13


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