18F14K50覚書
〔PICの動かせ方入門に戻る〕
忘れないうちにメモします。
ここでの記載はMPLAB X V2.15と
MPLAB(R) XC8 C Compiler Version 1.32を使用しての内容です。
データシートはこちらです。日本語でーすぅ v(・_・)
18F13K50も同じ内容です。
PICの内部に付いているクロック周波数回路は4MHz/8MHz/16MHz/32MHzを利用できる。
また、32MHZにする場合は、内部・外部クロックとも8MHzにして内蔵PLL回路を通す必要がある。
外部クロックは48MHzまでOKの様で、4xPLL使用する場合は4-12MHzのみOKです。
内部クロックを利用する場合
コンフィギュレーションを
#pragma config PLLEN = OFF , FOSC = IRC
にして
OSCCONレジスターにて使用する周波数を設定します。
OSCCON = 0b01110010 ;
赤い数字部分を変更する事により周波数を変更できます。
赤い数字部分以外はそのまま使用する。
111 |
16MHz |
110 |
8MHz |
101 |
4MHz |
100 |
2MHz |
011 |
1MHz |
その他 |
500KHz/250KHz/31KHz |
内部クロック32MHzを利用する場合(4xPLLで動作)
コンフィギュレーションを PLLEN = ON にして
OSCCON = 0b01100000 として 8MHz x 4倍 で動作させます。
外部クロック(プライマリ外部オシレータ)を利用する場合
コンフィギュレーションを FOSC = HS にして
OSCCON = 0b00000000 として動作させます。
(コンフィギュレーションのPCLKEN=ONでOSCCON2レジスタのPRI_SD=1となっていないとだめですよ)
また、プライマリとは別にセカンダリ外部オシレータとして、
外付けの32.768 kHz 水晶振動子を駆動出来ます、って事はRTC(リアルタイムクロック)が実現出来そうですね。
#pragma config キーワード1 = 設定値 , キーワード2 = 設定値 の様に記述する。
#pragma config BOREN = NOSLP , BORV = 30 , PWRTEN = ON // 記述の例
オレンジ色の文字(設定値)がデフォルト値です。
CONFIG1L
CPUDIV:システムクロックの分周を設定する(外部クロックと4xPLL回路のみ有効)
CLKDIV2=Fosc/2 CLKDIV2=Fosc/3 CLKDIV2=Fosc/4 NOCLKDIV=分周しない
USBDIV:ロースピードUSB動作時のクロック源を選択
ON = OSC1/OSC2を2分周したUSBクロックを供給
OFF = 分周なしでUSBクロックを直接供給
CONFIG1H
IESO :内部オシレータで起動しその後外部オシレータで起動する2段階起動モードの使用許可
ON = 有効にする OFF = 無効にする
FCMEN :外部オシレータに障害が発生した場合に内部オシレータに切り替えるかモニターする
ON = 有効にする OFF = 無効にする
PCLKEN:外部オシレータをソフト(OSCCON2レジスタのPRI_SD)で有効無効を切替える場合に使用
ON = 有効にする OFF = 無効にする
内部クロック時はこれをOFFで、OSCCON2(PRI_SD=0)にした方が消費電力がへるらしい。
PLLEN :オシレータの周波数を4倍で使用するしないの設定
ON = 使用する OFF = 使用しない(ソフトで制御可能)
FOSC :オシレータ選択ビット
IRC=内部でCLKOUT使用しない HS=外部で高い振動子を使用する
ほかにRCオシレータや外部クロック利用等有るが詳しくはデータシート(P-296)参照
CONFIG2L
BOREN :電源電圧が下がったらリセットを行うかの設定
OFF = 無効 ON = 有効(ソフトでも制御可能) SBORDIS=有効(ソフトで制御不可)
NOSLP=有効だがスリープ時は無効になる(ソフトで制御不可)
BORV :どの電圧まで電源が下がったらリセットするの
19(1.9V)、27(2.7V)、22(2.2V)、30(3.0V)
PWRTEN:パワーアップ タイマ有効無効(電源ONから後65.6msにプログラムを開始する)
ON(0) = 有効にする OFF(1) = 無効にする
CONFIG2H
WDTEN:ウォッチドッグタイマ使用許可
ON = 有効 OFF = WDTCONレジスタで制御する(レジスタは無効がデフォルト)
WDTPS:ウォッチドッグタイマ有効時のタイマ値を設定する(設定値はデータシート参照)
CONFIG3H
MCLRE :MCLR ピンの有効無効を設定
ON = 有効にする OFF = 無効にする(RA3入力ピンを有効にする)
HFOFST:内部オシレータの高速起動有無を設定
ON = オシレータが安定するのを待たずにCPUへのクロック供給を開始する
OFF = オシレータが安定してからシステムクロックを供給する
CONFIG4L
BKBUG :バックグラウンド デバッガの有効無効を設定(ICD デバイスでのみ使用)
XINST:拡張CPUの有効無効を設定
BBSIZ :ブート用メモリブロックのサイズを指定する(1kWがデフォルト)
LVP :低電圧ICSPプログラミングを使用するかの設定
ON = 使用する OFF = 使用しない(RC3のピンが利用可能になる)
STVREN:スタックのアンダー・フルのオーバが発生した時にリセットを行うかの設定
ON = リセットする OFF = リセットしない
CONFIG5L/CONFIG5H/CONFIG6L/CONFIG6H/CONFIG7L
メモリエリアの読み書き保護を設定するビット群だがデフォルトは全て保護しないとなっている
その他の詳しい内容は [ C:\Program Files\Microchip\xc8\v1.00\docs\pic18_chipinfo.html ] のファイルを参照。
delay関数を使用する場合は、
#define _XTAL_FREQ 4000000の行を追加するただしこれはクロックが4MHzの場合
__delay_us(197120) __delay_ms(197) クロック4MHzならこの値まで設定可能
ただし、( )の中は変数使用不可です、直接数値を入力、うんん...ちょっとぉいまいち!
197ms以上待たせたいなら、
for (i=0 ; i < 100 ; i++) __delay_ms(10) ; // 1秒待つ
という感じにします。
クロック 8MHz __delay_us(98560) __delay_ms(98)
クロック16MHz __delay_us(49280) __delay_ms(49)
クロック32MHz __delay_us(24640) __delay_ms(24)
クロック48MHz __delay_us(16426) __delay_ms(16)
Vpp
PICチップにプログラムを書込む時の、書込み電圧を負荷するピンという意味なので、
動作時には気にしなくて良い。
MCLR
外部リセット信号を入力する場合のピンとして使用。
リセット信号はLOW(0V:GND接続)でリセットが掛かります。
リセットスイッチを付けない場合は、内部でプルアップされているので端子はオープンでも構わない。
RA3
MCLRをDisable(禁止)にしI/OのRA3の入力端子とした方が良いでしょう。
__CONFIG(MCLRE_OFF)、__CONFIG(LVP_OFF) を記述すればDisableに出来ます。
但し、プルアップが無効になるので利用する場合は別途プルアップをONさせる必要が有ります。
ECCP1の機能としてキャプチャ・コンペア機能とPWM機能が有ります、
PWM機能には更に、フルブリッジPWM機能・ハーフブリッジPWM機能・シングルPWM機能が有りますが、
ここではシングルPWM機能の使い方について説明します。
尚、この機能についてのサンプルプログラムは
「可変抵抗のツマミを回してLEDの明るさを可変します」を参照して下さい。
シングルPWM機能とは、
PICの内部で生成されたPWM(CCP1)信号はピンのP1A/P1B/P1C/P1Dにそれぞれ接続されています、
なので、同じPWMを同時に4つのピンに出力が出来ますが、
PSTRCONレジスターにてそれぞれのピン出力をON/OFF出来ます。
これをPWMステアリング制御と言います
また、PWM(CCP1)信号はTIMER2を使います。
@ PWM機能(シングルPWMモード)を使用する事の宣言を行います。
CCP1CON = 0b00001100 ;
A PWM信号を出力するピンを設定します。
PSTRCON = 0b00010100 ; // P1CのRC3ピンのみPWM出力する、P1A/B/DはOFF
赤い数字部分にて設定、右からP1A(RC5)・P1B(RC4)・P1C(RC3)・P1D(RC2)の順です
出力しないピンはデジタルI/Oで使用可能です。
B TMR2プリスケーラ値の設定を行います。
T2CON = 0b00000011 ; この設定は16倍に設定
赤い数字部分にて設定します、1倍=00 4倍=01 16倍=10/11
C PWMの周期を設定します。
PR2 = 124 ; この設定はPWM周波数1000Hz(1KHz)で設定
D カウンターなどのレジスターを初期化します
CCPR1L = 0 ; // デューティ値は0で初期化
CCPR1H = 0 ;
TMR2 = 0 ; // タイマー2カウンターを初期化
E TMR2(PWM機能)のスタート要求を行います。
TMR2ON = 1 ;
F あとはデューティ値を(CCPR1L/CCP1CON)に設定します。
(PR2が255設定でないので、デューティ値解像度は10ビットの内8ビットのみ使用される)
※PR2の値を計算する(PWM周波数=1KHz)
PR2 = ( クロック周波数 / (PWM周波数 × 4 × TMR2プリスケール値) ) - 1
・PICのクロック周波数が8MHzとします。
PR2 = ( 8,000,000 / (PWM周波数 × 4 × TMR2プリスケール値) ) - 1
・PWM周波数を1000Hz(1KHz)にしたい場合です。
PR2 = ( 8,000,000 / (1000 × 4 × TMR2プリスケール値) ) - 1
・TMR2プリスケール値を1倍・4倍・16倍で計算します。
PR2 = 1999 = ( 8,000,000 / (1000 × 4 × 1) ) - 1
PR2 = 499 = ( 8,000,000 / (1000 × 4 × 4) ) - 1
PR2 = 124 = ( 8,000,000 / (1000 × 4 × 16) ) - 1
結果PR2の最大値は255までですので、16倍での124を選択します。
TMR2プリスケール値を16倍にしてPR2を124に設定します。
※デューティ値の設定方法
デューティ値は10ビット(0-1023)で
指定します。
CCPR1Lレジスターは8ビットなので、
CCPR1Lを上位8ビットとして、
下位2ビットをCCP1CONレジスター
の4-5ビット目を使用しセットします。
この様にセットするのは面倒なので、CCP1CONレジスターの4-5ビット目は0でセットして置き、
設定したいデューティ値を4で割り、その値をCCPR1Lレジスターにセットします。
※PWM周波数(1KHz)とデューティ値のPWM波形概要
但し、デューティ値10ビット(0-1023)はPR2が255の場合で、それ以外は10ビット以下になります。
(PWM制御についてのもう少し詳しい話はこちらのページを参考にして下さい。)
PIC12F/16Fシリーズでは8ビットタイマーでしたが、
このタイマは8/16 ビットの切り替えが出来るタイマです。
外部クロックと内部クロック(Fosc/4)が選択できます。
16 ビット動作時に、TMR0L/TMR0Hへ書込む場合はTMR0HをセットしてからTMR0Lをセットする。
また、読込み時はTMR0Lを読込んでからTMR0Hを読み込む必要がある。
起動時設定はRC5ピンからの8ビットカウンタモードになっています。
T0CONの設定
T0CON = 0b11000110 ;
水色数字部分 1 = TIMER0を動作させる 0 = TIMER0を動作させない
赤色数字部分が8/16 ビット切替え、1 = 8ビット 0 = 16ビット
緑色数字部分 0=システムクロック周波数(Fosc/4)でカウントする 1=6番ピン入力でカウントする
青色数字部分でプリスケール値の設定を行う
000 |
001 |
010 |
011 |
100 |
101 |
110 |
111 |
1:2 |
1:4 |
1:8 |
1:16 |
1:32 |
1:64 |
1:128 |
1:256 |
TIMER0のサンプルプログラムはこちらからダウンロードして下さい。
また、詳しい設定や概要は18F25K22での記事ですが、こちらを参考にして下さい。
Timer1 モジュールは 16 ビットのタイマ/カウンタで、
外部からクロックを入力するか、外部のオシレータから入力するか、
それとも内部のシステム周波数クロック(Fosc/4)を利用するのか選択できます、
タイマー動作の他に、CCP1モジュールのキャプチャ/コンペア機能のクロック源でも使用されます。
タイマ1を動作させる場合
// 内部クロック(Fosc/4)で使用する、プリスケーラカウント値 1:8
T1CON=0b10110001 ; // 内部クロック(Fosc/4)で動作、1:8 のプリスケール値を選択
緑色で 1 = TMR1レジスタを16bitで読書きする 0 = TMR1レジスタを8bitで読書きする
青色がプリスケール値です、 11 = 1:8 10 = 1:4 01 = 1:2 00 = 1:1
赤色がT1OSCENビット、0=外部クロックを使用する(RC6がデジタル利用不可となる)
1=外部オシレータを使用する(RC6/RC7がデジタル利用不可となる)
(外部オシレータを使わない時は0にする方が消費電力は少ないらしい)
水色がクロック源選択ビット、1=外部を利用する
0=内部(Fosc/4)を利用する(T1OSCENビットは無効)
タイマ3を動作させる場合
// 内部クロック(Fosc/4)で使用する、プリスケーラカウント値 1:8
T3CON=0b10110001 ; // 内部クロック(Fosc/4)で動作、1:8 のプリスケール値を選択
赤色がCCP1モジュールのコンペア/キャプチャのクロック源選択、1=Timer3を使う 0=Timer1を使う
TIMER1/3のサンプルプログラムはこちらからダウンロードして下さい。
また、詳しい設定や概要は18F25K22での記事ですが、こちらを参考にして下さい。
Timer2 モジュールは 8 ビットのタイマ/カウンタで、タイマー動作の他に、CCP1モジュールの、PWMモード時の動作のタイム ベースとして使用されます。
タイマー動作機能は設定した時間毎に割込み処理を行うものです。
割込みとは?
たとえば、Aさんと電話していて、Bさんから割込みキャッチホンがはいれば、
Bさんと話して終わったらAさんと続きを話しますよね、これと同じ事です。
プログラムのmain()を処理中にTIMER2割込みがはいれば、main()を一時中断後
interrupt InterTimer()を処理して再びmain()を再開します。
(InterTimerの関数名は変更できます)
割込み発生タイミング
TIMER2 はTMR2(8ビット)のレジスターを0からカウントアップして行きます、
PR2 のレジスター値と比較して一致したら、次のカウントでTMR2 のレジスター値は
0に戻り、ポストスケーラを駆動させます。
ポストスケーラは指定した回数(1〜16)だけカウントしたら割込みを発生させます。
例えば、ポストスケーラの設定値が1:1であれば、レジスター値を比較して一致したその都度割込みが
発生し、1:10 なら、レジスター値を比較して一致した回数が10 回したら割込みを発生させます。
ワンカウントの時間は?
PICのクロック周波数とプリスケーラ設定値できまります。
・ 例えばクロック周波数8MHzでプリスケーラ設定値が 16 なら
((1/システムクロック周波数) x 4) x プリスケーラ設定値
((1 / 8MHz) x 4) x 16 = 8μs → これがワンカウントの時間です。
これを256回カウントアップさせると 8x256=2048us(2.048ms)が、プリスケーラ値16 での
最大割込み時間ですが、ポストスケーラが1:16倍なら16x2048us=32768usで割込みが発生する。
なら1秒は1000000/32768us=30.517回割り込みを数えればよさそう。
・ 1秒ピッタリは?
クロック周波数8MHz プリスケーラ 1:16 ポストスケーラ 1:10 カウントアップは250回
にして割込みを50回数える、PR2の周期レジスター設定値は250-1=249をセットする。
・プリスケーラ設定方法は下記参照。
使い方は次の順番で行います(TIMER2での例です)
@ タイマー制御レジスターの設定を行う
T2CON = 0b00000111 ;
青色数字部分でプリスケーラの設定を行います。
00 = 1:1 01 = 1:4 10/11 = 1:16
緑色数字部分 1 = TIMER2を動作させる 0 = TIMER2を動作させない
赤色数字部分でポストスケーラの設定を行います。
1:1 |
1:2 |
1:3 |
1:4 |
1:5 |
1:6 |
1:7 |
1:8 |
1:9 |
1:10 |
1:11 |
1:12 |
1:13 |
1:14 |
1:15 |
1:16 |
0000 |
0001 |
0010 |
0011 |
0100 |
0101 |
0110 |
0111 |
1000 |
1001 |
1010 |
1011 |
1100 |
1101 |
1110 |
1111 |
A 周期レジスター(PR2)の設定を行う
TMR2を何カウントアップさせるかの設定です、
PR2=249 とした場合は、TMR2は0から249までカウントアップし250カウントめで割込み発生です
B TMR2カウントアップレジスターの初期化を行う
TMR2 = 0 ;
C TMR2IFのタイマー2割込みフラグを初期化します
TMR2IF = 0 ;
D 割込み機能を許可します
TMR2IE = 1 ; // TIMER2の割込みを許可する
PEIE = 1 ; // 周辺装置割り込み有効
GIE = 1 ; // 全体の割込み処理を許可する
割込み関数の書き方
void interrupt 割込み関数名( void )
{
if (TMR2IF == 1) { // タイマー0の割込み発生か?
TMR2IF = 0 ; // タイマー0割込フラグをリセット(再カウントアップ開始)
}
}
TIMER2のサンプルプログラムはこちらからダウンロードして下さい。
SPIについては、12F1822での記事ですがレジスタの使い方等は同じ様に利用出来ます、こちらを参考にして下さい。
18F14K50のSPIピンは以下の様に利用します。
SCK:11番ピン(RB6) SDI:13番ピン(RB4) SDO:9番ピン(RC7)を使用します。
TRISB = 0b00010000 ; // ピン(RB4)を入力に割当てる(マスター設定時)
TRISB = 0b01010000 ; // ピン(RB4/RB6)を入力に割当てる(スレーブ設定時)
また、スレーブ時のSSピンは8番ピン(RC6)を使用します。
注意)12F1822とレジスター名が少し異なるので以下の様にプログラムを変更しないとだめです。
12F1822 |
SSP1STAT |
SSP1CON1 |
SSP1BUF |
SSP1IE |
SSP1IF |
18F14K50 |
SSPSTAT |
SSPCON1 |
SSPBUF |
SSPIE |
SSPIF |
I2Cについては、12F1822での記事ですがレジスタの使い方等は同じ様に利用出来ます、こちらを参考にして下さい。
18F14K50のI2Cピンは以下の様に利用します。
SCL:11番ピン(RB6) SDA:13番ピン(RB4)を使用します。
TRISB = 0b01010000 ; // ピン(RB4/RB6)を入力に割当てる
注意)12F1822とレジスター名が少し異なるので以下の様にプログラムを変更しないとだめです。
(但し、下表の16F1938を18F14K50に読替えます)
USARTについては、12F1822/16F628Aでの記事ですがレジスタの使い方等は同じ様に利用出来ます、こちらを参考にして下さい。
18F14K50のUSARTピンは以下の様に利用します。
TX[送信]:10番ピン(RB7) RX[受信]:12番ピン(RB5)を使用します。
TRISB = 0b00100000 ; // ピン(RB5)を入力に割当てる
SPBRGレジスタの設定値とボーレートの関係はデータシートを参照して下さい。
18F14K50のデータシートはこちらの196-197ページを見て下さい。
SYNC=0、BRGH=1、BRG16=0で8MHzのクロック周波数で速度が9600ボーレートならSPBRG=51です。
RA0(D+)とRA1(D-)ピンはUSBで使用するピンです、デジタルで使用するには下記の様に記述します。
但し、デジタル入力しかだめです。
UCONbits.USBEN = 0 ; // USBは使用しない
IOCAbits.IOCA0 = 1 ; // USBピン(D+)をRA0のデジタル入力として使用する
IOCAbits.IOCA1 = 1 ; // USBピン(D-)をRA1のデジタル入力として使用する
Microchipが出しているUSB用のライブラリでUSBフレームワークはC18コンパイラで利用する見たい
ですね、試しにサンプルコードをXC8でコンパイルしたがエラー続出でダメでした。
どうするかな?、XC8対応まで待つかな?、それともぉ移植するかな......
USBフレームワークを利用したサンプル(CDCクラス)の記事はこちらを参照下さい。
(XC8でもコンパイル出来る様に変更しちゃいましたぁ)
- 電源電圧は1.8〜5.5Vで駆動可能、ピンにつなげられる電流は最大25mA(通常20mA以下)まで
20MHz以下(1.8V-5.5V) 20MHz以上(2.7V-5.5V/3.6V(18LF14K50)) 2.7V以上なら2%の周波数
精度(3.0Vから使用した方が良いみたい)
- 初期値のピン割り当てがアナログ入力となっています
デジタル入力として使うときは ANSEL/ANSELH レジスタで指定します。
ANSEL/ANSELHの使い方はこちらを参照して下さい。
記事変更(*2) 2015/06/30
一部見直し 2013/03/06
【きむ茶工房ガレージハウス】
Copyright (C) 2006-2020 Shigehiro Kimura All Rights Reserved.