16F18313覚書

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


忘れないうちにメモします。
ここでの記載はMPLAB X IDE V3.40
MPLAB(R) XC8 C Compiler Version 1.38を使用しての内容です。
(但し、Revision ID for Silicon Revision 2004(A4) での記載となります)
(X V3.40 / XC8 V1.38 以下のバージョンは利用できません!!)
データシートはこちらです。

12F1822との違いは?

12F1822 12F1501 16F18313 16F1705
電源電圧 1.8-5.5V 2.3-5.5V 2.3-5.5V 2.3-5.5V
プログラムスピード 8MIPS 5MIPS 8MIPS 8MIPS
プログラムメモリ 2K ワード 1K ワード 2K ワード 8K ワード
データSRAM 128B 64B 256B 1024B
データEEPROM 256B 128W(HEF) 256B 128W(HEF)
I/O 6 6 6(PPS 機能) 12(PPS 機能)
10bite ADC 4 4 5 8
DAC 1(5bit) 1(5bit) 1(5bit) 1(8bit)
コンパレータ 1 1 1 2
SRラッチ 1
タイマー(8/16) 2/1 2/1 2/1 4/1
CCP CCP1(P1A/P1B) PWM(4) CCP1/CCP2
PWM5/PWM6
CCP1/CCP2
PWM3/PWM4
タッチモジュール 4
EUSART 1 1 1
MSSP(SPI/i2C) 1 1 1
DSM 1 1
NCO 1 1
CWG 1 1
CLC 1 1 3
COG 1
オペアンプ 2
ゼロクロス 1
※ まあ、12F1822と12F1501が合体した感じでしょうか?
※ 16F1705のみ14ピンPICとなります。
※ 16F18313では全ての周辺モジュールに対して"許可"と"禁止"が設定可能です、
  電源立ち上げ時は全て"許可"されていますが、使用しないモジュールを外せば低電力に
  貢献する様です。(データシート:13.0 PERIPHERAL MODULE DISABLE の章を参照)

内蔵発振回路
今まで私の扱ったPICと少し設定方法が異なる様です。
16F18313が発生可能な周波数は31KHzと1MHz/2/4/8/12/16/32MHzです。
この発生させた周波数を分周器(NDIV)で1/1〜1/512倍に変更出来ます。
外部クロックは8MHzまでで、内蔵4xPLL回路を通せば32MHzで起動可能。

内部クロック1MHzを利用する場合
コンフィギュレーションを
#pragma config RSTOSC = HFINT1
にする

内部クロック8MHz/16MHz/24MHz/32MHzを利用する場合
例えば、システムクロックを8MHzにする場合の例です。
コンフィギュレーションを
#pragma config RSTOSC = HFINT32  // x2のPLLで動作
にして
OSCFRQbits.HFFRQ = 0b0011 ;  // 4MHzをx2でFOSC=8MHzの周波数を生成

2xFOSC(MHz)  HFFRQ Nominal Freq (MHz) 
× 0b0000 1
× 0b0001 2
0b0010 Reserved
8 0b0011 4
16 0b0100 8
24 0b0101 12
32 0b0110 16
× 0b0111 32

内部クロック8MHz/16MHz/24MHz/32MHzを分周利用する場合
例えば、システムクロックを2MHzにする場合の例です。
コンフィギュレーションを
#pragma config RSTOSC = HFINT32
#pragma config CSWEN = ON
にして
OSCFRQbits.HFFRQ = 0b0011 ;  // 4MHzをx2で8MHzの周波数を生成
OSCCON1bits.NDIV = 0b0010 ;  // 分周比は1:4なのでFOSC=2MHzとなる

NDIV Clock divider
0b1001 512
0b1000 256
0b0111 128
0b0110 64
0b0101 32
0b0100 16
0b0011 8
0b0010 4
0b0001 2
0b0000 1

外部クロック(水晶振動子モード)を利用する場合
コンフィギュレーションを
#pragma config FEXTOSC = HS
#pragma config RSTOSC = EXT1X
にする

もし、外部クロックを4xPLLで使用する場合は
#pragma config RSTOSC = EXT4X
にする

※ もちろん、外部水晶発振器を使ったECモードも可能です。
※ 内蔵31KHz及びセカンダリ外部クロック(32.768KHz)も利用可能です。

コンフィギュレーション
#pragma config キーワード1 = 設定値 , キーワード2 = 設定値   の様に記述する。
#pragma config BOREN = ON , BORV = HI , FOSC = INTOSC  // 記述の例

CONFIG1
 FEXTOSC  :外部発振器モード選択ビット
          101−111=ECモード(ECL/ECM/ECH)
          100     =外部クロックは無効(OFF)
          000−010=水晶振動子モード(LP/XT/HS)
 RSTOSC   :電源ONやリセット時の初期発振器選択ビット
           (その後、NOSCビットでソフト変更可能)
          111=外部発信器を選択、"FEXTOSC"に従う(EXT1X)
          110=内部発信器の1MHzを選択(HFINT1)
          100=内部発信器の31KHzを選択(LFINT)
          011=セカンダリの外部発信器(32.768KHz)を選択(SOSC)
          001=外部発信器を4xPLLで動作させる(EXT4X)
          000=内部発信器を2xPLLで動作させる(HFINT32)
 CLKOUTEN :クロック出力の有無設定ビット
                    ON = CLKOUTピンは有効とする(Fosc/4を出力)
                    OFF= CLKOUTピンは無効、RA4ピンとして使用する
 CSWEN:       :ソフトによるクロック切換の有効無効選択ビット
                    ON = NOSCNDIVへ の書き込みは許可されています
                    OFF= 無効書き換え不可
 FCMEN       :外部クロックの監視ビット
                    ON = 外部オシレータに障害が発生した場合に内部オシレータに切替えるか監視する
                    OFF= 外部クロックの監視はしない
CONFIG2
 MCLRE       :MCLR/VPP ピン機能選択ビット
                    ON = ピンはMCLR(外部リセットピン)として機能する
                    OFF= ピンはデジタル入力ピン(RA3)として機能する
                    LVP= ONの場合はこのビットは無視される。
 PWRTE       :パワーアップタイマの有無設定ビット
                    ON = 電源ONから64ms後にプログラムを開始する
                    OFF= パワーアップタイマは無効とする
 WDTE         :ウォッチドッグタイマの有無設定ビット
                    ON       = ウォッチドッグタイマを有効にする
                    OFF       = ウォッチドッグタイマを無効にする
                    NSLEEP = 動作時に有効、スリープ中に無効にする
                    SWDTEN= WDTCONレジスタのSWDTENビットで制御する
 LPBOREN  :低消費電力ブラウンアウトリ セット
          (VDD端子を 監視し電圧低 すぎるか検出を行う)
          ON = 有効
          OFF= 無効
 BOREN       :電源電圧がBORVより下がったらリセットを行うかの設定ビット
                    ON = 電源電圧降下常時監視機能は有効とする
                    OFF= 電源電圧降下常時監視機能は無効とする
                    NSLEEP = 動作時に有効、スリープ中に無効にする
                    SBODEN=BORCONレジスタのSBORENビットで制御する
 BORV         :電源電圧降下常時監視の電圧設定ビット
                    HIGH= リセット電圧(VBOR)のトリップポイントを高(2.7V)に設定する
                    LOW = リセット電圧(VBOR)のトリップポイントを低(2.45V)に設定する
 PPS1WAY   :PPSLOCKビット単方向セット イネーブルビット
                    ON = PPSLOCK ビットは、ロック解除シーケンスを実行後に一度のみセットできる
                            一度PPSLOCK がセットされると、その後PPS は変更できない
                    OFF= ロック解除シーケンスを実行すれば何度でもPPSLOCKをセット/クリアできる
 STVREN      :スタックがオーバフローやアンダーフローしたらリセットを行うかの有無設定ビット
                    ON = リセットを行う
                    OFF= リセットを行なわない
CONFIG3
 WRT          :2KWのフラッシュメモリ自己書き込み保護ビット
                    OFF   = 保護しない
                    BOOT= 000h-1FFhを書込み保護にし、200h-7FFhをEECON制御によって変更可能
                    HALF = 000h-3FFhを書込み保護にし、400h-7FFhをEECON制御によって変更可能
                    ALL   = 000h-7FFhを書込み保護にし、NVM制御によるアドレス変更を不可にする
 LVP          :低電圧プログラミング機能の有無設定ビット
                    ON = 低電圧プログラミングを行う(RA3のI/Oピンは使用不可)
                    OFF= 低電圧プログラミングは行わない
CONFIG4
 CPD          :データ(EEPROM)メモリー保護の有無設定ビット
                    ON = データメモリーの保護を行う
                    OFF= データメモリーの保護はしない
 CP            :プログラムメモリー保護の有無設定ビット
                    ON = プログラムメモリーの保護を行う
                    OFF= プログラムメモリーの保護はしない

DEBUGはCONFIGで指定しない、IDEやデバッガから自動的にON/OFFされるらしい。

delay
delay関数を使用する場合は、
#define _XTAL_FREQ 4000000の行を追加するただしこれはクロックが4MHzの場合

__delay_us(50462464) __delay_ms(50462) クロック4MHzならこの値まで設定可能
ただし、( )の中は変数使用不可です、直接数値を入力、うんん...ちょっとぉいまいち!
例えば、50秒以上待たせたいなら、
for (i=0 ; i < 5000 ; i++) __delay_ms(10) ; // 50秒待つ
という感じにします。

クロック 4MHz __delay_us(50462464) __delay_ms(50462)
クロック 8MHz __delay_us(25231232) __delay_ms(25231)
クロック16MHz __delay_us(12615616) __delay_ms(12615)
クロック32MHz __delay_us(6307808) __delay_ms(6307)

4番ピンの使い方(MCLR)
Vpp
 PICチップにプログラムを書込む時の、書込み電圧を負荷するピンという意味なので、
 動作時には気にしなくて良い。

MCLR
 外部リセット信号を入力する場合のピンとして使用。
 リセット信号はLOW(0V:GND接続)でリセットが掛かります。
 リセットスイッチを付けない場合は、内部でプルアップされているので端子はオープンでも構わない。

RA3(入力専用)
 MCLRをDisable(禁止)にしI/OのRA3の入力端子とした方が良いでしょう。
 #pragma config MCLRE = OFF,LVP = OFF
 を記述すればDisableに出来ます。
 但し、プルアップが無効になるので利用する場合は別途プルアップをONさせる必要が有ります。

I/Oポート
16F18313には新たなI/Oポートを制御するレジスタが追加されています。

オープンドレイン制御
 通常ポート出力ピンは電流のソースとシンクが可能な標準のプッシュプルドライバですが、
 ODCONAレジスタの各ピン(RA3以外)に該当するビットをONにすると、その対応するポート出力は
 電流のシンクのみ可能なオープンドレインドライバとなります。

スルーレート制御
 SLRCONAレジスタの各ピン(RA3以外)に該当するビットをONにする事により、その対応するポート
 ピンの駆動スルーレートを変更できます。
 立ち上がり時間の速い矩形波をオペアンプに入力し増幅すると出力波形は変化速度が追いつかず
 傾いた波形になる事が有るのでこのような時にスルーレートを変更出来る様になっている様です。
 デフォルトは制限が掛かっているので早い立ち上がりが欲しい場合は変更しないとダメかもね。
 1 = ポートピンのスルーレートを制限する(デフォルト値)
    (波形エッジの立上り/立下りが緩やかになります)
 0 = ポートピンのスルーレートを最大にする

入力しきい値制御
 INLVLAレジスタは入力ピンのON/OFF判断電圧値のしきい値を制御します。
 1 = ポートの読み出しと状態変化割り込みに使うST(ショットトリガ)入力(デフォルト値)
 0 = ポートの読み出しと状態変化割り込みに使うTTL入力


・ I/Oポートに入出力を行う際の注意点
  I/Oポートへ高速クロックで連続的に入出力を繰り返した場合に上手く入出力が出来ない場合が
  有ります、そんな時はPORTAレジスタで入力し、LATAレジスタで出力します。

・ 初期値のピン割り当てがアナログ入力となっています。
  ANSELA レジスタの各ピンに該当するビットをクリアすればデジタル入力として使う事が
  出来ます。

・ PIC内部プルアップ抵抗の使い方は?
  16F18313では全てのピンで内蔵プルアップが使用出来ます。
  使用する場合は、下記のレジスターにて設定する必要があります。
  WPUA = 0b00000001 ; この設定でRA0のみ内部プルアップ抵抗を使うです
                右のビットから左へ RA0〜RA5 の順番です。
                (MCLR=ONにするとRA3はプルアップされます)

ピン概要
他の周辺機器用ピンは下記のPPS機能で割り当てます。
又、外部割込み用ピン(IOC)はRA0〜RA5ピン全て可能です。


PPS機能(PERIPHERAL PIN SELECT MODULE)
周辺モジュールの入出力を好きなピンに割り当てる事が出来る機能です、
割り当てを変更できるのはデジタル信号のみで、アナログ入出力の割り当ては変更できません。
また、不用意に割り当てが変更出来ない様にロックする事が可能な様だが....試していません。

周辺モジュールの入力側設定レジスタ名
周辺機能ピン INT T0CKI T1CKI T1G CCP1 CCP2
デフォルトピン RA2 RA2 RA5 RA4 RA5 RA5
設定レジスタ名 INTPPS T0CKIPPS T1CKIPPS T1GPPS CCP1PPS CCP2PPS
周辺機能ピン CWG1N MDCIN1 MDCIN2 MDMIN UART-RX    
デフォルトピン RA2 RA0 RA5 RA1 RA1  
設定レジスタ名 CWG1PPS MDCIN1PPS MDCIN2PPS MDMINPPS RXPPS
周辺機能ピン SCK/SCL SDA/SDI SS CLCIN0 CLCIN1
デフォルトピン RA1 RA2 RA3 RA3 RA5
設定レジスタ名 SSP1CLKPPS SSP1DATPPS SSP1SSPPS CLCIN0PPS CLCIN1PPS
周辺機能ピン CLCIN2 CLCIN3    
デフォルトピン RA1 RA0  
設定レジスタ名 CLCIN2PPS CLCIN3PPS
尚、デフォルトピンは幾つかの機能でダブっているので注意が必要でしょう。
例) USARTのRXをRA5ピンから入力する場合は、 RXPPS=5 ; とする。

周辺モジュールの出力側設定レジスタ名
周辺機能
ピン名称
PWM5 PWM6 CLC1OUT CLC2OUT CWG1A CWG1B CWG1C CWG1D CCP1 CCP2
UART-TX
UART-DT C1OUT C2OUT SCK/SCL SDO/SDA TMR0 NCO CLKR DSM
尚、デフォルト設定は無い様なので必ずピンの割り付けを行う必要が有ります。
設定レジスタ名は RxxPPS  xxにはピン名のA0-A5を適用
例) RA5ピンからCPP1を出力する場合は、 RA5PPS=12 ; とする。

入力と出力の双方向ピン時の注意点
I2C-SDAとUSART-RX/DT(同期モード時)の信号を利用する場合は、入力PPSと出力PPSのピンを
同じ番号に合わせる必要が有ります。
I2C-SDAで例えば、SSP1DATPPS=RC1、RC1PPS=SDAと言うあんばいにです。

詳しい設定値はデータシートのP144-P147を参照下さい。

CLKR(REFERENCE CLOCK OUTPUT MODULE) *3)
CLKOUTは"CLKOUTEN"のコンフィグレーションビットを"ON"にすればFosc/4のクロックを
[RA4]ピンから出力出来てどのPICにも付いている機能ですが、CLKRはシステムクロックを分周して
CLKRピン(PPSで割り付け)から出力出来る機能で、デュティ比も設定可能です。

CLKRCONレジスターの設定を行う
  CLKRCON = 0b00010010 ;
  赤色数字部分 1 = CLKRを動作させる  = CLKRを動作させない
   (ここの設定では動作させないでぇ後でで起動させる事にします)
  緑色数字部分がデュティ比の設定を行います。
11
10
01
00
75%
50%
25%
0%
  青色数字部分でFoscの分周比を設定します。
111
110
101
100
011
010
001
000
Fosc/128
Fosc/64
Fosc/32
Fosc/16
Fosc/8
Fosc/4
Fosc/2
Fosc
     // 基準クロック出力モジュール(CLKR)の設定)
     RC3PPS = 0b00011110 ;         // CLKRをRC3から出力
     CLKRCON= 0b00010010 ;         // 50%デュティ比、分周する(Fosc/4))
     CLKREN = 1 ;                  // CLKRを有効にする
※ 8MHz以上は出力出来ません、
  例えば、Fosc=32MHzで分周比Fosc/2(16MHz)はダメです、Fosc/4(8MHz)はOKとなります。

CCP1/2機能(CAPTURE/COMPARE/PWM MODULES)
CCP機能は、キャプチャ/コンペア/PWMを行うモジュールです。
キャプチャモードでは、外部イベントの発生時間を計測する事が出来ます。
コンペアモードでは、予め設定した時間が経過した時点で外部イベントをトリガする事が出来ます。
PWMモードでは、各種周波数とデューティサイクルのパルス幅変調信号を生成出来ます。
ですがぁ、ここではキャプチャ・コンペアモードの記事は省きますPWMモードのみ記事にします。
又、CCP出力はCLCCWGDSMの入力源となります。

PWMモード
 PWMモードの周波数発生源はTimer2のみです。
 この機能についての説明は16F1705での記述ですが、
 「可変抵抗のツマミを回してLEDの明るさを可変します」を参考にして下さい。
 又、少し詳しい設定等の説明は、16F1827(CCP3)での記述ですがこちらを参考にして下さい。

 尚、1F1705/16F1827のデューティ値はCCPR1L[7:0]+CCP1CON[5:4]の10bitレジスタに
 設定しますが、16F18313ではCCPR1H[7:0]+CCPR1L[7:0]の10bitレジスタとなり、
 右詰め(CCPR1H[1:0]+CCPR1L[7:0])と左詰め(CCPR1H[7:0]+CCPR1L[7:6])が有ります。

 CCP1のサンプルプログラムはこちらからダウンロードして下さい。

キャプチャモード
 キャプチャモードの周波数発生源は16BitTimer0/Timer1です。
 キャプチャ機能の話は、PIC16F1829での記事ですがこちらを参考にして下さい。 *2)

コンペアモード
 コンペアモードの周波数発生源はTimer1です。
 コンペア機能の話は、こちらを参考にして下さい。 *2)

PWM機能(PULSE-WIDTH MODULATION)
16F18313では2つのPWM出力(PWM5/PWM6)を行う事が出来ます。
この機能はCCPからPWM機能を取り出した様なものです。
PWMの周波数発生源はTimer2のみです。
又、PWM出力はCLCCWGDSMの入力源となります。

尚、ハーフブリッジ/フルブリッジ機能やステアリング制御(相補PWM出力)機能等は、
相補出力ジェネレータ(CWG)モジュールで行うようです。

このモードも周波数発生源はTimer2のみです。
この機能についての説明は16F1705での記述ですが、
「可変抵抗のツマミを回してLEDの明るさを可変します」を参考にして下さい。
又、少し詳しい設定等の説明は、12F1501(PWM1OUT)での記述ですがこちらを参考にして下さい。

PWM5のサンプルプログラムはこちらからダウンロードして下さい。

TIMER0
16F18313のTimer0 モジュールは 8/16ビットのタイマ/カウンタです。
このTimer0は今までのPIC12F/16FシリーズのTimer0に比べ、16ビットが選択出来てポストスケーラも
有るのでかなり長い時間のタイマーが作成可能です、又、TIMER0の外部出力も出来ます。
尚、Timer0はTimer1のゲート制御にも使われます。

TIMER0機能は設定した時間毎に割込み処理を行うものです。
TIMER0のクロックソースは、外部ピン・セカンダリクロックと内部クロック(LFINTOSC,HFINTOSC,
FOSC/4)にCLC1出力から選択出来ます。

割込みとは?
 たとえば、Aさんと電話していて、Bさんから割込みキャッチホンがはいれば、
 Bさんと話して終わったらAさんと続きを話しますよね、これと同じ事です。
 プログラムのmain()を処理中にTIMER0割込みがはいれば、main()を一時中断後
 interrupt InterTimer()を処理して再びmain()の続きを再開します。
 (InterTimerの関数名は変更できます)

割込み発生タイミング?
 TIMER0はTMR0L(8ビット)のレジスターをカウントアップして行きます、
 256になった時点(オーバーフロー)で割込みを発生させます。(但し、ポストスケーラは1:1の場合)
 例えば、TMR0L=100と設定した場合は100から256までカウントアップして行きます、
 256-100で156カウントした所でオーバーフローし割込み発生です。
 (割込み発生したらTMR0Lはゼロになっています、TMR0L=100したいなら割込み処理の中で再設定)
 又、TMR0H/TMR0L(16ビット)なら65536でオーバーフローです。

ワンカウントの時間は?
 PICのクロック周波数とプリスケーラ設定値できまります。
 ・ 例えばクロック周波数8MHz(Fosc/4)でプリスケーラ設定値が128なら
  ((1/システムクロック周波数) x 4) x プリスケーラ設定値
  ((1 / 8MHz) x 4) x 128 = 64μs → これがワンカウントの時間です。
  これを256回(8ビット)カウントアップさせると 64x256=16384us(16.384ms)が、
  プリスケーラ値128での最大割込み時間です。(但し、ポストスケーラは1:1の場合)
  で、ポストスケーラはこの割り込み時間を設定した回数分カウントしてくれます、
  例えば、1:10に設定していれば、16384us x 10回で163840usしたら割り込みを発生させます。

 ・タイマークロックソースがHFINTOSC(Fosc)等の場合
  (1/システムクロック周波数) x プリスケーラ設定値

TIMER0の使い方は次の順番で行います
但し、16ビットタイマーでクロック周波数8MHz(Fosc/4)の1秒毎の割り込み発生での設定例です。

@ T0CON1レジスターの設定を行う
  T0CON1 = 0b01000111 ;
  赤色数字部分でタイマーのクロックソースを選択します。
000 001 010 011 100 101 110 111
T0CKIPPS(正) T0CKIPPS(負) FOSC/4 HFINTOSC LFINTOSC   SOSC CLC1
  緑色数字部分はタイマー入力を同期させるかのビット
    = クロック周波数(Fosc/4)で同期する 1 = 非同期
  青色数字部分でプリスケール値の設定を行う
0000 0001 0010 0011 0100 0101 0110 0111 ・・・・・・・
(中略)
1101 1110 1111
1:1 1:2 1:4 1:8 1:16 1:32 1:64 1:128 1:8192 1:16384 1:32768

A T0CON0レジスターの設定を行う
  T0CON0 = 0b00010000 ;
  赤色数字部分 1 = TIMER0を動作させる  = TIMER0を動作させない
   (ここでは動作させないでぇEで起動させる事にします)
  緑色数字部分が8/16 ビット切替え、0 = 8ビット  = 16ビット
  青色数字部分でポストスケーラ値の設定を行う
0000 0001 0010 0011 0100 0101 0110 0111 ・・・・・・・・・・
(中略)
1101 1110 1111
1:1 1:2 1:3 1:4 1:5 1:6 1:7 1:8 1:14 1:15 1:16

B TMR0カウントアップレジスターの初期化を行う(1秒毎の割込み)
  システムクロック8MHz(Fosc/4)でプリスケーラは1:128だから((1/8MHz)x4)x128=64usになり、
  16ビットタイマーだから、65536回カウントアップさせると64x65536=4194304us が最大割込み時間です
  1秒毎なら1000000/64us = 15625回カウントアップさせる、
  それには65536-15625 = 49911で49911からオーバフローするまでカウントさせるので、
  TMR0H/L = 49911 を設定する。(ポストスケーラは1:1で十分ですね)
   TMR0H = 49911 >> 8 ;    // タイマー0のカウント開始の初期値をセットする
   TMR0L = 49911 & 0x00FF ;  // TMR0H=HIGHバイト TMR0L=LOWバイト

  ※ TMR0Hから先に設定してその後にTMR0Lを設定する。
  ※ オーバフローすると、TMR0H/L=0 となるので割込み内で再設定が必要です。

C TMR0IFの割込みフラグを初期化します
  TMR0IF = 0 ;      // タイマー0割込フラグ(TMR0IF)を0にする

D 割込み機能を許可します
  TMR0IE = 1 ;      // タイマー0割込み(TMR0IE)を許可する
  PEIE  = 1 ;       // 周辺装置割り込みを許可する
  GIE  = 1 ;       // 全体の割込み処理を許可する

E タイマー0を起動させます
  T0EN = 1 ;        // TIMER0を開始する

割込み関数の書き方
 void interrupt 割込み関数名( void )
 {
      if (TMR0IF == 1) {  // タイマー0の割込み発生か?
           TMR0H  = 49911 >> 8 ;    // タイマー0のカウント開始の初期値をセットする
           TMR0L  = 49911 & 0x00FF ;  // TMR0H=HIGHバイト TMR0L=LOWバイト
           TMR0IF = 0 ;   // タイマー0割込フラグをリセット(再カウントアップ開始)


      }
 }
PS. *2)
上の割込み処理は32MHz動作で"10us"程の遅延が発生します、下記の様にすると"1.75us"程です。
 49911=0xC2F7ですね。
           TMR0H  = 0xC2 ;  // タイマー0のカウント開始の初期値をセットする
           TMR0L  = 0xF7 ;  // TMR0H=HIGHバイト TMR0L=LOWバイト

 TIMER0のサンプルプログラムはこちらからダウンロードして下さい。
 又、こちらのMPLAB X IDEのMCC機能を使うとタイマーのレジスタ設定がやりやすいかもね。

TIMER1
Timer1 モジュールは 16 ビットのタイマ/カウンタで、タイマー動作の他に、CCPモジュールの
キャプチャ/コンペア機能でも使用されます。
また、Timer0のオーバフロー・外部ピン・コンパレータ出力からの信号によるゲート制御機能が有り、
これによりパルスカウントやサイクル時間の測定が可能と思われますが、この機能には触れません。

割込み発生タイミング
 TIMER1はTMR1(16ビット)のレジスターをカウントアップして行きます、
 65536になった時点(オーバーフロー)で割込みを発生させます。
 だからで割込み発生時点でTMR1は0(オーバーフロー)になっています。

ワンカウントの時間は?
 PICのクロック周波数とプリスケーラ設定値できまります。
 ・タイマークロックソースがFOSC/4の場合
  例えばクロック周波数8MHzでプリスケーラ設定値が1:8なら
  ((1/システムクロック周波数) x 4) x プリスケーラ設定値
  ((1 / 8MHz) x 4) x 8 = 4μs → これがワンカウントの時間です。
  これを65536回カウントアップさせると 4x65536262144us(262.144ms)が、プリスケーラ値8での最大割込み
  時間です。
  なら、4usx62500回=250000us(250ms)にして、割込み回数を4回数えれば1000msだから、
  プリスケーラ値1:8でTMR1:65536-62500=3036をセットして、割込み回数を4回数えたら1秒が出来ます
  (3036からオーバフローするまでカウントアップすれば62500回目で割込み発生ですね)

 ・タイマークロックソースがFOSC等の場合
  (1/システムクロック周波数) x プリスケーラ設定値

TIMER1の使い方は次の順番で行います

@ T1CONレジスターの設定を行う
  T1CON = 0b00111000 ;
  青色数字部分でTimer1のクロックソースを選択します。
   00 = Fosc/4  01 = Fosc  10 = 外部端子(T1CKI又はSOSCI/SOSCO)  11 = LFINTOSC
  緑色数字部分でプリスケーラの設定を行います。
   00 = 1:1  01 = 1:2  10 = 1:4  11 = 1:8
  赤色数字部分 1 = 外部端子はSOSC入力 0 = 外部端子はT1CKI入力
  水色数字部分 1 = TIMER1を動作させる  = TIMER1を動作させない
   (ここでは動作させないでぇDで起動させる事にします)

A TMR1カウントアップレジスターの初期化を行う
  カウントアップを65536までカウントさせたいならTMR1 = 0です。
  62500カウントだけさせたいなら65536-62500=3036だからTMR1 = 3036です。
  (ただし、TMR1=3036の場合は割込み処理の中で再び初期化する必要があります)
  ・TMR1のセット方法
   TMR1Hに上位の8ビットをセットして、TMR1Lに下位の8ビットをセットします。
   で、16ビットカウンターとなります。
   TMR1H = (3036 >> 8) ;
   TMR1L = (3036 & 0x00ff) ;
    こんな感じでセットします。
  ・16ビットモードでレジスタを読み書きする場合は
   TMR0L/TMR0Hへ書込む場合はTMR0HをセットしてからTMR0Lをセットする。
   読込み時はTMR0Lを読込んでからTMR0Hを読み込む必要がある。

B TMR1IFの割込みフラグを初期化します
  TMR1IF = 0 ;

C 割込み機能を許可します
  TMR1IE = 1 ;      // TIMER1の割込みを許可する
  PEIE = 1 ;        // 周辺装置割り込み有効
  GIE = 1 ;         // 全体の割込み処理を許可する
D タイマー1を起動させます
  TMR1ON = 1 ;        // TIMER1を開始する

割込み関数の書き方
 void interrupt 割込み関数名( void )
 {
      if (TMR1IF == 1) {    // タイマー1の割込み発生か?
           TMR1H = ???? ;   // タイマー1(TMR1)の再ど初期化
           TMR1L = ???? ;   // (65536までカウントアップさせるならこの2行は必要ない)
           TMR1IF = 0 ;     // タイマー1割込フラグをリセット(再カウントアップ開始)
      }
 }
 TIMER1のサンプルプログラムはこちらからダウンロードして下さい。
 又、こちらのMPLAB X IDEのMCC機能を使うとタイマーのレジスタ設定がやりやすいかもね。

TIMER2
Timer2 モジュールは 8 ビットのタイマ/カウンタで、タイマー動作の他に、
CCP(PWMモード)モジュールとPULSE-WIDTH MODULATION時の動作のタイムベースとして
使用されます。

TIMER2のサンプルプログラムはこちらからダウンロードして下さい。
また、概要は16F1827での記事ですが、こちらを参考にして下さい。
更又、こちらのMPLAB X IDEのMCC機能を使うとタイマーのレジスタ設定がやりやすいかもね。

CWG(相補波形ジェネレータ)機能
12F1822ではPWMのエンハンスモード(ハーフブリッジ:ステアリング制御)と言っていた機能と同じです
このCWGでは、ハーフブリッジやフルブリッジにステアリング制御(相補PWM出力)と
PWMの周期に合わせて交互に信号を出力する"プッシュプルモード"が有ります。
何方かと言うとぉ、CWGって言うかぁ、16F1705のCOG機能と同等な感じです。

ステアリング制御の話は16F1827での記事ですが、こちらを参考にして下さい。

CWGの概要とサンプルプログラムは「CWG機能を動作させて見ます」を参照して下さい。

NCO(数値制御オシレータ)機能
周波数の直線的な制御を高解像度(20bit)で実現する事が出来るので、
周波数発生器(トーンジェネレータ)として利用。
周波数のカウンターとして利用したりパルス周波数変調(PFM)なども出来る様です。

アプリケーションの例として
蛍光灯等の照明の制御・照明のバラスト・モータ駆動・モデム・D級オーディオアンプ・超音波測距など

NCOのサンプルプログラムはこちらからダウンロードして下さい。
又、概要は12F1501での記事ですが、「NCO機能を動作させて見ます」を参照して下さい。
こちらに16F18313用で書いた記事も参考にして下さい。 *2)

12F1501では、インクリメントレジスタがNCO1INCH/NCO1INCL=65535(0xFFFF)の16ビットでしたが
16F18313では、NCO1INCU/NCO1INCH/NCO1INCL=1048575(0xFFFFF)の20ビットとなっています。
尚、設定する順番は、NCO1INCU/NCO1INCHを設定後NCO1INCLを最後に設定します。

CLC(ロジックセルモジュール)機能
16F18313には2個(CLC1/CLC2)の構成可能なロジックセルモジュールが有ります、
この機能によりソフトウエアではなくハード的にロジック(AND/OR等)が構成出来ます。
1つのモジュールあたり4つの入力が出来、16個の選択可能な入力源(PWM/OSC/TMR/外部PIN等)
が有ります。
ロジック機能はAND-OR/OR-XOR/4-InputAND/Dフロップ/Dラッチ/SR/JKなどです。

CLCの概要とサンプルプログラムは「CLC機能を動作させて見ます」を参照して下さい。

C(MSSP) *1)
I2Cについては、12F1822での記事ですが同じ様に利用出来ます、こちらを参考にして下さい。

16F18313はSDA/SCLのピンが好きな場所に割り当て可能です、この機能をPPSと言います。
例) SDA1ピンをRA2とし、SCL1ピンをRA4にマスターとして割当てる場合は?
   WPUA      = 0b00010100 ;  // RA2/4は内部プルアップ抵抗を指定する
   TRISA     = 0b00010100 ;  // I2Cのピンは入力とする
   // I2CはSCL1/SDA1ピンは入出力両方機能するので両方割り当てる
   RA4PPS    = 0b11000 ; // 出力(SCL1を割当てる)
   SSP1CLKPPS= 0b00100 ; // 入力(RA4を割当てる)
   SSP1DATPPS= 0b00010 ; // 入力(RA2を割当てる)
   RA2PPS    = 0b11001 ; // 出力(SDA1を割当てる)

I2C用のライブラリ(skI2Clib)は、
秋月電子I2C接続小型LCDモジュールに表示を行う」を参照下さい。

SPI(MSSP) *1)
SPIについては、12F1822での記事ですが同じ様に利用出来ます、こちらを参考にして下さい。

16F18313はSCK/SDO/SDI/SSのピンが好きな場所に割り当て可能です、この機能をPPSと言います。
例) SDIピンをRA2とし、SCKピンをRA4とし、SDOピンをRA5にマスターとして割当てる場合は?
   TRISA     = 0b00000100 ;  // SDI:RA2のピンは入力とする
   RA4PPS    = 0b11000 ; // 出力(SCKを割当てる)
   RA5PPS    = 0b11001 ; // 出力(SDOを割当てる)
   SSP1DATPPS= 0b00010 ; // 入力(RA2を割当てる)

SPI用のライブラリ(skSPIlib)は、
マスターにSPIデバイスを複数個接続して見ます」を参照下さい。

USART(EUSART)(非同期モード) *1)
USARTについては、12F1822/16F628Aでの記事ですが同様に利用出来ます、こちらを参考にして下さい

16F18313はTX/RXのピンが好きな場所に割り当て可能です、この機能をPPSと言います。
例) TXピンをRA4とし、RXピンをRA5に割り当てる場合は?
   TRISA  = 0b00100000 ;  // RX:RA5は入力
   RA4PPS= 0b10100 ; // 出力(TXを割当てる)
   RXPPS = 0b00101 ; // 入力(RA5を割当てる)
SPBRGレジスタの設定値とボーレートの関係はデータシートを参照して下さい。
16F18313のデータシートはこちらのP368-P370を見て下さい。

USART用のライブラリ(skUARTlib)は、
FT232RL使用によりUSBをシリアル変換してマイコンと繋ぎます」を参照下さい。

その他



記事一部追記(*3) 2019/04/05
記事一部追記(*2) 2018/04/11
記事一部追記(*1) 2018/01/07


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