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

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


半固定抵抗とLEDを配線し、半固定抵抗の値からLEDの明るさを可変させます。
LEDはPICのCCP機能(PWM)を利用して明るさを可変させます。
PIC18F14K50には拡張型CCP機能が1個あり、PWMモードには、シングルPWM・ハーフブリッジPWM・フルブリッジPWMが有り、ハーフブリッジやフルブリッジはモータ等を回すのに使います、
ここではシングルPWMを利用して、LEDの明るさを可変させてみたいと思います。

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

この頁での記事では18F14K50のDIPタイプで記述しますが、 私が購入したのは秋月電子のUSB対応超小型マイコンボード(18F14K50のSOPタイプ)ですので実験はこれで行っています。
また、18F14K50はMPLAB IDE V8.84とMPLAB(R) XC8 C Compiler Version 1.00を使用しての内容となっています。

VRtoLED4
シングルPWM機能とは、
PICの内部で生成されたPWM(CCP1)信号はピンのP1A/P1B/P1C/P1Dにそれぞれ接続されています、
なので、同じPWMを同時に4つのピンに出力が出来ますが、
PSTRCONレジスターにてそれぞれのピン出力をON/OFF出来ます。
これをPWMステアリング制御と言います


この記事ではCCP1からPWM信号を作りP1C(RC3)の7番ピンから出力をしてみます。
(P1AとP1BとP1Dからは出力しません、OFFです、デジタル端子として使用可能です。)

VRtoLED1

今回使用するピン番号は1番(VDD)と20番(VSS)と7番(CCP1)と12番(AN11)です。
12番ピンがアナログ入力で7番ピンがアナログ出力(PWM)です。

VRtoLED2
 @まずは、左図画面の様に配線しましょう。
  PICの1番ピンに電源+5V、20番ピンに電源GND(-)側、
  12番ピンに半固定抵抗の中央の足を接続します。
  7番ピンにLEDの足が短い方(-側)を接続します。
  (抵抗はLEDのどっち側の足でもかまいません)

 AMPLAB X IDE(V3.40)を起動させます。 *2)


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

// コンフィギュレーションの設定(ここの記述に無い設定はデフォルト値での動作)
// 外部・内部クロックの切替えでの起動はなし(IESO_OFF)
// 動作クロックを4倍では動作させない(PLLEN_OFF):内部部クロックを使用する(IRC)
#pragma config IESO=OFF,PLLEN=OFF,FOSC=IRC          // CONFIG1H
// 電源電圧降下常時監視機能ON(BOREN_ON):監視電圧は(3.0V)に設定
// 電源ONから後65.6msにプログラムを開始する(PWRTEN_ON)
#pragma config BOREN=NOSLP,BORV=30,PWRTEN=ON       // CONFIG2L
// ウオッチドッグタイマー無し(WDTE_OFF)
#pragma config WDTEN=OFF                           // CONFIG2H
// 外部リセット信号は使用せずにデジタル入力(RA3)ピンとする(MCLRE_OFF)
// オシレータが安定するのを待ってシステムクロックを供給する(HFOFST_OFF)
#pragma config MCLRE=OFF,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 ;            // 読み込んだアナログ値を返す(0-1023の範囲)
}
// メインの処理
void main()
{
     unsigned int num ;

     OSCCON = 0b01100010 ;    // 内部クロックとする(8MHz)
     ANSEL  = 0b00000000 ;    // ANS3-7 アナログは使用しない、デジタルI/Oに割当
     ANSELH = 0b00001000 ;    // ANS8-10アナログは使用しない、ANS11のみアナログで使用
     TRISA  = 0b00000000 ;    // 1で入力 0で出力 RA4-RA5全て出力に設定(RA3は入力専用)
     TRISB  = 0b00100000 ;    // RB4-RB7は出力に設定 、RB5のみ入力にする
     TRISC  = 0b00000000 ;    // RC0-RC7全て出力に設定 
     UCONbits.USBEN = 0 ;     // USBは使用しない
     IOCAbits.IOCA0 = 1 ;     // USBピン(D+)をRA0のデジタル入力として使用する
     IOCAbits.IOCA1 = 1 ;     // USBピン(D-)をRA1のデジタル入力として使用する
     PORTA  = 0b00000000 ;    // 出力ピンの初期化(全てLOWにする)
     PORTB  = 0b00000000 ;    // 出力ピンの初期化(全てLOWにする)
     PORTC  = 0b00000000 ;    // 出力ピンの初期化(全てLOWにする)

     // A/Dの設定
     ADCON2 = 0b10010001 ;    // 読取値は右寄せ、変換開始待ち時間は4TAD、A/DクロックはFOSC/8
     ADCON1 = 0b00000000 ;    // VDD/VSSの内部電圧をリファレンスとする
     ADCON0 = 0b00101101 ;    // アナログ変換情報設定(AN11から読込む)
     // ECCP1の設定(拡張型CCP機能)
     CCP1CON = 0b00001100 ;   // PWM機能(シングル出力)を使用する
     PSTRCON = 0b00010100 ;   // P1CのRC3ピンのみPWM出力する、P1A/B/DはOFF
     T2CON   = 0b00000011 ;   // TMR2プリスケーラ値を16倍に設定
     CCPR1L  = 0 ;            // デューティ値は0で初期化
     CCPR1H  = 0 ;
     TMR2    = 0 ;            // タイマー2カウンターを初期化
     PR2     = 124 ;          // PWMの周期を設定(1000Hzで設定)
     TMR2ON  = 1 ;            // TMR2(PWM)スタート

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

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

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

《やさしく解説》

LEDについて

VRtoLED4

LEDには極性が有ります、
足の長いアノード側を電源+5Vの方に、足の短いカソード側を電流制限抵抗の方に接続します。
また、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の明るさは暗くなり逆になります。

プログラムについて

プログラムソースのコメントを読んでもらえば大体何をしているのか分かると思います。
コンフィギュレーションの設定に付いてはこちらも参考にして下さい。

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

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

アナログI/O
 アナログピンの設定は下記のレジスターにて設定します。
 ANSEL = 0b00000000 ;
     アナログ入力を行うピン(RA4,RC0-RC3)の指定をします。
     赤字右からANS3(RA4),ANS4(RC0),ANS5(RC1),ANS6(RC2),ANS7(RC3)の順
     1でアナログ、0でデジタル、この設定は全てデジタルI/Oに割当
 ANSELH = 0b00001000 ;
     アナログ入力を行うピン(RC6-7,RB4-5)の指定をします。
     赤数字右からANS8(RC6),ANS9(RC7),ANS10(RB4),ANS11(RB5)の順
     1でアナログ、0でデジタル、この設定はANS11をアナログにするです

 アナログの入力を行う該当ピンを入力設定にします。
 TRIS(A-C)の該当ビットを1にすれば入力設定です。
 TRISA = 0b00000000 ; ANS3の設定する場所です
 TRISB = 0b00100000 ; ANS10-11の設定する場所です(ANS11/RB5を入力にしています)
                赤数字右からANS10,ANS11です。
 TRISC = 0b00000000 ; ANS4-9の設定する場所です
                赤数字右からANS4,ANS5,ANS6,ANS7,ANS8,ANS9です。

アナログ変換情報設定
 ADCON0 = 0b00101101 ;
     この設定でAN11から読込めと指示しています。
     他のAN9以外から読込みたい場合は、赤数字の部分を変更します。
     0011=AN3,0100=AN4,0101=AN5, 0110=AN6, 0111=AN7,
     1000=AN8,1001=AN9,1010=AN10,1011=AN11 と変更して下さい。
     緑数字の部分は、1=アナログ変換有効 0=アナログ変換無効

 ADCON1 = 0b00000000 ;
     緑数字部分でA/D変換時の負電圧(GND)リファレンスをどうするかの設定です。
     00=VSSのPIC電圧を使用  01=15番(RC1)ピン接続の外部VREF-を使用
     赤数字部分でA/D変換時の正電圧(+)リファレンスをどうするかの設定です。
     00=VDDのPIC電圧を使用  01=16番(RC0)ピン接続の外部VREF+を使用
     10=PIC内蔵の固定電圧(FVR)を使用

 ADCON2 = 0b10010001 ;
     緑数字部分でA/D変換を行う速度のクロックを設定します。
     000=FOSC/2 001=FOSC/8  010=FOSC/32
     100=FOSC/4 101=FOSC/16 110=FOSC/64
     赤数字部分で変換開始までの待ち時間を設定します。
     000=0  001=2TAD  010=4TAD  011=6TAD  100=8TAD
     101=12TAD 110=16TAD 111=20TAD
     また、それ以外の数字部分の設定は今回このまま使用して下さい。

PWM機能設定
 ここでの設定は1KHzの周波数で、PWM制御する設定です。
 LEDならこの位で良かろうと、適当なんですが、
 設定につての詳しい説明はこちらを参照して下さい。


相補PWM出力制御 *1)
memo3  左図の様にP1CピンがHIGH時はP1DピンはLOWを
 出力する様に反転させます(差動出力)、これを
 相補PWM出力制御と言います。

 下がP1CからPWMを出力する場合でしたが、
 CCP1CON = 0b00001100 ;   // PWM機能(シングル出力)を使用する
 PSTRCON = 0b00010100 ;   // P1CのRC3ピンのみPWM出力する、P1A/B/DはOFF

 P1C(アクティブHIGH)とP1D(アクティブLOW)から相補PWMを出力する場合は、
 CCP1CON = 0b00001101 ;   // PWM機能(シングル出力:相補を行う)を使用する
 PSTRCON = 0b00011100 ;   // P1CをPWM出力する、P1Dは反転出力、P1A/BはOFF
 CCP1CON = 0b00001101;
      赤色部分でPWMの出力パターンを設定します。
      1100:P1A、P1C をアクティブHigh、P1B、P1D をアクティブHigh
      1101:P1A、P1C をアクティブHigh、P1B、P1D をアクティブLow
      1110:P1A、P1C をアクティブLow、P1B、P1D をアクティブHigh
      1111:P1A、P1C をアクティブLow、P1B、P1D をアクティブLow

 PSTRCON = 0b00011100;
      赤い数字部分にてPWM出力を設定、1:出力 0:出力しない(デジタルで使用)
      右からP1A(RC5)・P1B(RC4)・P1C(RC3)・P1D(RC2)の順です

《その他》

今回は7番・12番ピンを使用しましたが他のピンを使用する場合は下記の表を参照して下さい。
また、4番ピンRA3は入力しか出来ません、出力不可です。
ポートA
ピン番号 18 19
デジタル入出力ビット名 RA5 RA4 RA3 RA1 RA0
アナログ入力ピン名 AN3
MCLR
RA0とRA1ピンはUSBで使用するピンです、デジタルで使用するには下記の様に記述します。
但し、デジタル入力しかだめです。
UCONbits.USBEN = 0 ; // USBは使用しない
IOCAbits.IOCA0 = 1 ;  // USBピン(D+)をRA0のデジタル入力として使用する
IOCAbits.IOCA1 = 1 ;  // USBピン(D-)をRA1のデジタル入力として使用する

ポートB
ピン番号 10 11 12 13
デジタル入出力ビット名 RB7 RB6 RB5 RB4
アナログ入力ピン名 AN11 AN10

ポートC
ピン番号 14 15 16
デジタル入出力ビット名 RC7 RC6 RC5 RC4 RC3 RC2 RC1 RC0
アナログ入力ピン名 AN9 AN8 AN7 AN6 AN5 AN4
PWM 出力ピン名 P1A P1B P1C P1D


こちらの写真は秋月電子のUSB対応超小型マイコンボードでの実験風景です。
VRtoLED5




リンクの見直し(*2) 2017/01/13
一部追記(*1) 2014/11/24


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