この記事でわかること
・PIC16F1ファミリ(5桁Ver)のタイマ機能について
・タイマ0、1、2の違いと、割込みの使い方
・タイマ割込みプログラムの設計方法
PIC16F18857等の末尾の数字が5桁のバージョンは、
定番であるPIC16F1ファミリの中でも新しいシリーズで、高機能で低価格なPICマイコンです。
本記事では、PIC16F1ファミリの5桁Verにおけるタイマ割込みの使い方について解説します。
本記事で使用する新居浜高専PICマイコン学習キットについては下記記事で解説しています。
キットの回路図やプログラムはキットを販売している秋月電子のHPからダウンロードできます。
秋月電子 新居浜高専PICマイコン学習キットVer.3 ACアダプタ付
また、参考書も販売されています。
※本記事はPICマイコン学習方法の一例を紹介するものであり、
ここで紹介するキットやソフトの動作を保証するものではありません。
キット等の購入については自己責任でお願いします。
(不明点等の質問にはお答えできません)
<本ソフトの利用環境と設定について>
本記事におけるMPLABの開発環境は以下の通りです。
・MPLAB X IDE v.15
・XC8 v2.46
・Device Family Pack PIC16F1xxxx_DFP(1.24.387)
※ダウンロードしたプロジェクトファイル(NNCTkit_v3.X)は、
そのままビルドするとエラーになるため、以下の変更を実施しました。
・helpstr.h 9行目
変更前:const __section(“title”) unsigned char title[224]={
変更後:const __section(“help_title“) unsigned char help_title[224]={
セクション名がtitleだとエラーになるので、別の名前にします。
ここではhelp_titleにしましたが、何でも良いです。
この時、配列名はtitleのままでも問題ありませんが、
他のデータ同様、配列名をセクション名と同じにする場合は、
この配列を使用しているソースファイルの方も直します。
・monitor.c 2093行目
変更前:TX1REG = title[i];
変更後:TX1REG = help_title[i];
MPLABの使い方については下記で解説しています。
PIC16F1ファミリのタイマ機能
PIC16F1ファミリ(5桁Ver)には3種類のタイマがあり、
学習キットに使用されているPIC16F18857は以下のタイマを利用できます。
タイマ0 :基本的なタイマで、2つのカウンタモード(8bit/16bit)から選択できる
タイマ1,3,5 :16bitカウンタで、外部信号によりカウントの動作/停止を制御できる
タイマ2,4,6 :8bitカウンタで、外部信号によりカウントのスタートやリセットを制御できる
タイマがカウントアップし、ある条件になるとカウント値がリセットされ、ゼロに戻ります。
この時、タイマ割込みフラグ(TMRxIF)が1にセット(※)されます。(x=0,1,2,…,6)
※タイマ0とタイマ2,4,6については、ポストスケーラの出力分周設定が1:1の場合(出力分周については後で説明)
但し、以下の割込み許可を1にしておかないとタイマ割込みは発生しません。
・グローバル割込み許可(GIE) :全ての割込みを有効にする
・ペリフェラル割込み許可(PEIE) :ペリフェラル割込みを有効にする(※)
※タイマ0割込みはペリフェラル割込みではない為、PEIEが0でも割込みは発生します。
・タイマ割込み許可(TMRxIE) :タイマx(x=0,1,2,…,6)の割込みを有効にする
カウント値がリセットされる条件ですが、8bitカウンタと16bitカウンタで異なります。
8bitカウンタ :カウント値が予め設定した値(周期値)に到達した時
16bitカウンタ :カウント値が最大値(0xFFFF:65,535)に到達した時
従って、タイマが1周するカウント数は、タイマ0の8bitモードとタイマ2,4,6は周期値になり、
タイマ0の16bitモードとタイマ1,3,5については、
カウントを開始する値をセットすることで、(65,535ーカウント開始値)になります。
タイマ0の機能と使い方
タイマ0は以下の構成となっています。
タイマ0 クロック信号
タイマ0は、カウント用のクロック信号を、システムクロック(Fosc/4)や、
内部/外部発振器、外部入力(T0CKI)等から選択できます。
入力したクロック信号はプリスケーラによって分周でき、
システムクロック(Fosc/4)に同期させることもできます。
タイマ0 カウンタ
タイマ0カウンタは2種類(8bitと16bit)のモードがあります。
8bitモードでは、TMR0Lをカウント値、TMR0Hを周期値に使用し、
16bitモードでは、TMR0Lを下位8bit用、TMR0Hを上位8bit用カウント値として使用します。
タイマ0カウンタがカウントアップ時に以下の条件を満たすと、
タイマ0割込み (タイマ0割込フラグ(TMR0IF)が1になる)が発生(※)します。
※ポストスケーラの出力分周設定が1:1の時の場合(出力分周については後で説明)
①8 bitモード時
TMR0L(8bitカウント値)がTMR0H (周期値)に到達し、ゼロに戻った時
(割込み周期は「タイマ0クロック周期×TMR0H」)
②16 bitモード時
TMR0H & TMR0L (16bitカウント値)が最大値(0xFFFF)に到達し、ゼロに戻った時(※)
(割込み周期は「タイマ0クロック周期×(0xFFFFーカウント開始値)」)
※カウント値が最大値に達して、ゼロに戻ることをロールオーバーと呼ぶ
TMR0HとTMR0Lは、レジスタ値の同時更新を行うため、
TMR0Hの読み書きはバッファを経由して行うようになっており、
バッファからTMR0HへのコピーはTMR0Lの読み書きのタイミングで行われます。
このため、カウント開始値の書込みは、TMR0Hから行うようにすると、
TMR0HとTMR0Lが同時に更新できます。
同様の理由で、カウント値を読み出す場合は、TMR0Lから行うようにします。
以上より、8bitモードではTMR0Hに周期値を、
16bitモードではTMR0H 及び TMR0Lにカウント開始値をセットすることで、
割込み周期を設定できます。
タイマ0 出力分周
タイマ0割込みは、①又は②の条件を満たした時に発生しますが、
ポストスケーラによって、これらの条件を指定した回数(出力分周比)分、
満たした時に割込みが発生します。
プリスケーラやポストスケーラを組み合わせることで、長時間の割込み周期を設定できます。
割込みフラグと同時に出力されるタイマ出力TMR0は、
出力毎にH/Lレベルが切り替わるトグル動作を行います。
タイマ0の設定
タイマ0の設定は、旧来のPICマイコンはOPTIONレジスタで行っていましたが、
PIC16F1ファミリの5桁Verでは、2つのタイマ0制御レジスタ(T0CON0、T0CON1)に
変更されました。
T0CON0(タイマ0 制御レジスタ 0)
T0EN :タイマ0有効化 (1 = 有効、0 = 無効)
T0OUT :タイマ0出力(TMR0)(読取り専用)
T016BIT :タイマ0モード選択 (1 = 16bitモード、0 = 8bitモード)
T0OUTPS :タイマ0 出力分周比(ポストスケーラ) 1:(1+ T0OUTPS)
1111 = 1:16、1110 = 1:15、~、0001 = 1:2 、0000 = 1:1
T0CON1(タイマ0 制御レジスタ 1)
T0CS :タイマ0 クロック ソース選択
111 = 未使用
110 = LC1_out :CLC(※)からの出力
※Configurable Logic Cell:構成可能ロジック セル(CPLDの様に論理出力をプログラムで構成できる)
101 = SOSC :外部サブ発振器(32.768 kHz 水晶発振子)
100 = LFINTOSC :低周波内部発振器 (31 kHz)
011 = HFINTOSC :高周波内部発振器 (1 ~ 32 MHz)
010 = FOSC/4 :システムクロック(Fosc/4)
※PIC16F18857の場合、Foscは最大で32MHz
001 = T0CKIPPS (反転) :PPS(※)で選択されたピンからの入力信号(反転入力)
000 = T0CKIPPS :PPS(※)で選択されたピンからの入力信号
※Peripheral Pin Select:入出力ピンに、どの信号を割り当てるか選択する
T0ASYNC :タイマ0 クロック同期化(1 = 非同期、0 = システムクロック(Fosc/4) に同期)
T0CKPS :タイマ0 クロック分周比(プリスケーラ) 1:2T0CKPS
1111 = 1:32768(=215)、 ~、 0001 = 1:2(=22) 、0000 = 1:1(=20)
タイマ1の機能と使い方
タイマ1はタイマ0の16bitモードと同じく、ロールオーバーで割込みが発生しますが、
外部信号によって、カウントの動作/停止を制御できるゲート機能が追加されています。
タイマ3、5もタイマ1と同じでものであり、ここでは代表してタイマ1を説明します。
タイマ1 クロック信号
タイマ1は、カウント用のクロック信号を、システムクロック(Fosc)や、
内部/外部発振器、外部入力(T1CKI)等から選択できます。
入力したクロック信号はプリスケーラにより分周でき、
システムクロック(Fosc/2)に同期(※)させることもできます。
※タイマ1クロック信号の選択をシステムクロック以外にした場合
タイマ1 カウンタ
タイマ1レジスタ TMR1H & TMR1L (16bitカウント値)は、クロック信号でカウントアップし、
ロールオーバー(最大値(0xFFFF:65,535)に到達し、ゼロに戻った時)になったら、
タイマ1割込みが発生します。(具体的には、TMR1IF(タイマ 1 割込みフラグ)が1になる)
従って、タイマ1レジスタに初期値xをセットすると、
割込みは(65,536 ーx)カウント後に発生します。
ゲート機能
ゲート機能を有効にすると、外部信号を使って、カウントの動作/停止を制御できます。
ゲート入力信号は、他のタイマからの出力や、
コンパレータ、PWM等の各モジュール出力、外部入力(T1GI)等から選択でき、
極性を反転して使用することも可能です。
ゲート機能には、通常モードの他にトグルモードやシングルパルスモードがあります。
通常モードは、ゲート入力信号がH時にカウントを行います。
トグルモードは、ゲート入力信号が来る毎にカウントと停止を交互に繰り返します。
これは、ゲート入力信号がHになったらカウントを行い、
Lになってもカウントを継続し、次にHになったら停止します。
カウントの再開は、一度Lになってから、Hに戻った時です。
シングルパルスモードは、ゲート入力信号の1パルス分だけカウントを行います。
シングルパルス開始フラグ(GGO/DONE)を1にすると、
ゲート入力信号Hでカウント開始、Lでカウント停止して、GGO/DONEが0(終了)に戻ります。
これを用いると、 ゲート入力信号のH期間をタイマでカウント(計測)できます。
また、ゲート機能には、ゲート信号と同時にゲート割込みを発生させることができます。
(具体的には、TMR1GIF(タイマ 1ゲート 割込フラグ)が1になる)
シングルパルスとトグルモードを組み合わせると、
ゲート入力信号の最初の1パルス分(H + L期間)、カウントが有効になります。
これを用いると、ゲート入力信号のサイクル タイムを計測できます。
タイマ1の設定
タイマ本体の制御をタイマ制御(T1CON)と、クロック選択(T1CLK)レジスタで行い、
ゲート制御をゲート制御(T1GCON)と、ゲート選択(T1GATE)レジスタで行います。
T1CON(タイマ1 制御レジスタ)
CKPS :入力クロック プリスケール(分周比)選択 1:2CKPS
11 = 1:8(= 23) 、10 = 1:4(=22)、01 = 1:2(=21) 、00 = 1:1(=20)
SYNC :同期制御(1 = 非同期、0 = システム クロック(Fosc/2)と同期)
※本設定はタイマクロックをシステムクロック(Fosc 又は Fosc/4)にした場合は無効
RD16 :タイマカウンタのモード設定(1 = 16bitモード、0 = 8bitモード)
ON :タイマ有効化(1 = 有効、0 = 無効)
T1GCON(タイマ1 ゲート制御レジスタ)
GE :ゲート有効化(1 = 有効、0 = 無効)
※本設定はON = 0(タイマ無効)の場合は無効
GPOL :ゲート極性(1 = Hレベル、 0 = Lレベル) ※タイマカウントする極性を指定
GTM :ゲート トグル モード (1 = 有効、0 = 無効)
GSPM :ゲート シングル パルス モード (1 = 有効、0 = 無効)
GGO/DONE :ゲート シングル パルス取得状態
1 = ゲート シングルパルス取得準備完了、ゲート信号のエッジ待機状態
0 = ゲート シングルパルス取得完了、又は未開始
※本フラグは、ソフトにより1にセットし、GSPM が0になると自動的に0に戻る。
GVAL :ゲート出力状態 ※GE=0(ゲート無効)でもゲート出力状態を示している。
T1CLK(タイマ1 クロック選択レジスタ)
CS :クロック選択
1111 = LC4_out :CLC(※10)からの出力
1110 = LC3_out :CLC(※10)からの出力
1101 = LC2_out :CLC(※10)からの出力
1100 = LC1_out :CLC(※10)からの出力
1011 = タイマ5 出力(注3)
1010 = タイマ3 出力(注2)
1001 = タイマ1 出力(注1)
1000 = タイマ0 出力
0111 = CLKR(※11)出力クロック(外部出力クロック信号)
0110 = SOSC :外部サブ発振器(32.768 kHz 水晶発振子)
0101 = MFINTOSC :中周波内部発振器 (500 kHz)
0100 = LFINTOSC :低周波内部発振器 (31 kHz)
0011 = HFINTOSC :高周波内部発振器 (1 ~ 32 MHz)
0010 = Fosc :システムクロック
※PIC16F18857の場合、Foscは最大で32MHz
0001 = Fosc/4 :システムクロック/4
0000 = T1CKIPPS :PPS(※12)で選択されたピンからの入力信号
T1GATE(タイマ1 ゲート選択レジスタ)
GSS :ゲート入力信号の選択
11111 = 未使用
・・・
11001 = 未使用
11000 = LC4_out :CLC(※10)からの出力
10111 = LC3_out :CLC(※10)からの出力
10110 = LC2_out :CLC(※10)からの出力
10101 = LC1_out :CLC(※10)からの出力
10100 = ZCD1_出力 :ZCD(※13)ゼロクロス検出出力
10011 = C2OUT_同期 :コンパレータ同期出力
10010 = C1OUT_同期 :コンパレータ同期出力
10001 = DDS_out :NCO(※14)からのデジタル信号出力
10000 = PWM7_out :PWMモジュールからのPWM信号
01111 = PWM6_out :PWMモジュールからのPWM信号
01110 = CCP5_out :CCPモジュール(※15)からのコンペア信号
01101 = CCP4_out :CCPモジュール(※15)からのコンペア信号
01100 = CCP3_out :CCPモジュール(※15)からのコンペア信号
01011 = CCP2_out :CCPモジュール(※15)からのコンペア信号
01010 = CCP1_out :CCPモジュール(※15)からのコンペア信号
01001 = SMT2_一致 :SMT2モジュール(※16)からの一致信号
01000 = SMT1_一致 :SMT1モジュール(※16)からの一致信号
00111 = タイマ6出力
00110 = タイマ5 出力(注3)
00101 = タイマ4出力
00100 = タイマ3 出力(注2)
00011 = タイマ2出力
00010 = タイマ1 出力(注1)
00001 = タイマ0出力
00000 = T1G :PPS(※12)で選択されたピンからの入力信号
注 1:タイマ1 の場合、使用不可
2:タイマ3 の場合、使用不可
3:タイマ5 の場合、使用不可
※10:CLC(Configurable Logic Cell):構成可能ロジック セル
CPLDの様に論理出力をプログラムで構成できる。
※11:CLKR(Clock Reference):システムクロックFoscを分周して外部ピンに出力できる信号
※12:PPS(Peripheral Pin Selectz):ペリフェラル・ピン選択モジュール
各ペリフェラルの入出力をデバイスの I/O ピンに割り当てる機能
※13:ZCD(ZERO CROSS DETECTION):ゼロクロス検出モジュール
入力した交流信号の0Vを横切るタイミングを検出
※14:NCO(Numerical Controlled Oscillator 数値制御発振器)モジュール
DDS(Direct Digital Synthesizer デジタル信号発生器)とも呼ばれ、
デジタル合成で任意の波形(正弦波や矩形波など)を出力する。
※15:CCP(Capture/Compare/PWM):キャプチャやコンペアを行うモジュール
※16:SMT(SIGNAL MEASUREMENT TIMER):信号測定タイマ
タイマ1割込みの設定例
学習キットにある電子ピアノ プログラムでは、タイマ1割込みを利用し、
指定した周波数を持つパルス信号をブザーに出力することで音階を制御しています。
電子ピアノ プログラムの詳細は下記で解説してます。
ここではタイマ1の設定について概略を説明します。
タイマ1の設定は、初期設定関数SetConfig( )で行っており、
タイマ1クロックをFosc/4、分周器の設定を1:1にしています。
本プログラムでは、システムクロック周波数Foscを32MHzにしているので、
8MHzのタイマ1クロック信号となり、タイマ1レジスタをカウントします。
また、ゲート機能を無効にしているので、タイマ1は常にカウントされます。
タイマ1がロールオーバー時に発生するタイマ1割込みの処理内容については、
割込み処理関数 isr( ) で定義しています。
割込み関数内では、まず、タイマ1割込みフラグ(TMR1IF)を0にクリアし、
次回の割込み処理が、次のロールオーバーまで行わないようにします。
そして、タイマ1レジスタに初期カウント値をセットしますが、
先に説明した様に、先に上位8bit用のTMR1H、次に下位8bit用のTMR1Lの順にセットします。
初期カウント値をxとすると、次の割込みは(65536ーx)カウント後に発生します。
ここでは、割込みが発生する毎にRB4をトグル出力(※)するようにしているので、
RB4のH/L信号の1周期が割込み周期2回分となり、RB4の周波数をfとすると、
1/f=2× (65536ーx) × (1/8MHz)
となります。
※それまでの出力がHならL、LならHにすることで、前回とは逆の出力にすること。
例えば、低い「ド」(261.6Hz)の音を鳴らす場合の初期カウント値xは、
1/261.6Hz=2×(65536ーx) × (1/8MHz)
65536ーx=8MHz/(2×261.6Hz) ≒15291
x=65536ー15291=50245(0xC445)
となるので、TMR1H=0xC4、TMR1L=0x45をセットします。
また、タイマ1割込みを実行できるようにするために、
メインプログラムで以下の割込み許可を行っています。
PIE4bits.TMR1IE= 1 タイマ1割込を許可
INTCONbits.PEIE = 1 ペリフェラル割込を許可
INTCONbits.GIE = 1 グローバル割込を許可
上記のコードですが、厳密にはメインプログラムmain( )でコールする
電子ピアノプログラムElectricPiano( )内にあります。
タイマ2の機能と使い方
タイマ2はタイマ0の8bitモードと同じく、
設定した周期値に到達してゼロに戻った時に割込みが発生しますが、
外部信号によって、カウントのスタートやリセットを制御できる機能が追加されています。
タイマ4、6もタイマ2と同じでものであり、ここでは代表してタイマ2を説明します。
タイマ2 クロック信号
タイマ2は、カウント用のクロック信号(TMR2_clk)を、システムクロック(Fosc)や、
内部/外部発振器、外部入力(T2IN)等から選択できます。
入力したクロック信号は極性を反転させたり、プリスケーラにより分周でき、
システムクロック(Fosc/4)に同期(※)させることもできます。
※タイマ2クロック信号の選択をシステムクロック以外にした場合
タイマ2 カウンタ
タイマ2レジスタ TMR2(8bitカウント値)は、クロック信号によってカウントアップし、
予め設定したT2PR(タイマ2周期レジスタ)の値に到達したらゼロに戻り、
タイマ2割込みが発生します。(具体的には、TMR2IF(タイマ2 割込みフラグ)が1になる)
但し、これは後述するポストスケーラの出力分周設定が1:1の時になります。
タイマ2 出力分周
タイマ2割込みの条件は、上述した通り、TMR2 = T2PRですが、
ポストスケーラによって、この条件を指定した回数(出力分周比)分、
満たした時に割込みが発生するように変更することができます。
プリスケーラやポストスケーラを組み合わせることで、長時間の割込み周期を設定できます。
動作モードの設定
外部リセット信号(TMR2_ers)によって、カウントのスタートやリセットを制御することで
3つの動作モード(フリーランニング期間、ワンショット、単安定)を設定できます。
動作モードの設定は、T2HLT(タイマ2 ハードウェア制限制御レジスタ)の
MODE(制御モード)によって行います。
外部リセット信号(TMR2_ers)は、他のタイマ出力や、
コンパレータ、PWM等の各モジュール出力、外部入力(T2IN)等から選択できます。
フリーランニング期間モード
カウント値がT2PR(タイマ2周期レジスタ)の値に到達したらゼロに戻るを繰り返すモードで、
このモードには外部信号によるリセット方法によって、複数のモードに分かれます。
・ソフトウェアゲートモード
外部信号によるリセットを行わない基本的な動作モードです。
・ハードウェアゲートモード
外部リセット信号(TMRx_ers)がH又はLレベルになったらカウントを停止するモードです。
T2HLT(タイマ2 ハードウェア制限制御レジスタ)のMODE(制御モード)によって、
動作/停止する外部リセット信号レベルを指定します。
MODE = 00001 :正論理(Hレベルで動作、Lレベルで停止)
MODE = 00010 :負論理(Lレベルで動作、Hレベルで停止)
・エッジトリガ リセットモード
外部リセット信号(TMRx_ers)の変化(エッジ)によってタイマをリセットできるモードです。
T2HLT(タイマ2 ハードウェア制限制御レジスタ)のMODE(制御モード)によって、
リセットするエッジの種類を指定します。
MODE = 00011 :立上りエッジ又は立下りエッジ
MODE = 00100 :立上りエッジ
MODE = 00101 :立下りエッジ
・レベルトリガ リセット制限モード
外部リセット信号(TMRx_ers)のレベルによってタイマをリセットできるモードです。
T2HLT(タイマ2 ハードウェア制限制御レジスタ)のMODE(制御モード)によって、
リセットする信号レベルを指定します。
MODE = 00110 :Lレベルでリセット
MODE = 00111 :Hレベルでリセット
ワンショットモード
カウント値がT2PR(タイマ2周期レジスタ)の値に到達し、ゼロに戻ったら、
T2CON(タイマ2制御レジスタ)のON(タイマ有効)が自動的に0になり、
停止したままになることで、カウント1周分だけ動作するモードです。
※本モードはポストスケーラによる出力分周設定は無効になります。(つまり、出力分周比は1:1固定)
このモードには外部リセット信号による制御方法によって、複数のモードに分かれます。
・ソフトウェアスタート ワンショットモード
外部信号によるリセットを行わない基本的なワンショットモードです。
ソフトウェアで ON を1にセットするとタイマが開始し、
カウント値が T2PR(周期値)と一致するとタイマがリセットされ、
ON がクリアされることでカウントが停止します。
タイマを再開するには、ソフトウェアで ON を1にセットする必要があります。
・エッジトリガ スタート ワンショットモード
外部リセット信号(TMRx_ers)の変化(エッジ)によってタイマをスタートするモードです。
T2HLT(タイマ2 ハードウェア制限制御レジスタ)のMODE(制御モード)によって、
スタートするエッジの種類を指定します。
MODE = 01001 :立上りエッジ
MODE = 01010 :立下りエッジ
MODE = 01011 :立上り、又は立下りエッジ
・エッジトリガ スタート&リセット ワンショットモード
外部リセット信号(TMRx_ers)の変化(エッジ)によって
タイマをスタート&リセットするモードです。
カウントの開始は、エッジから2 タイマクロック後に行います。
T2HLT(タイマ2 ハードウェア制限制御レジスタ)のMODE(制御モード)によって、
スタート&リセットするエッジの種類を指定します。
MODE = 01100 :立上りエッジ
MODE = 01101 :立下りエッジ
・エッジトリガ スタート&レベルリセット ワンショットモード
外部リセット信号(TMRx_ers)のレベルでタイマをリセットし、
変化(エッジ)によってタイマをスタートするモードです。
カウントの開始は、エッジから2 タイマクロック後に行います。
T2HLT(タイマ2 ハードウェア制限制御レジスタ)のMODE(制御モード)によって、
スタートするエッジとリセットする信号レベルを指定します。
MODE = 01110 :Lレベル リセット、立上りエッジ スタート
MODE = 01111 :Hレベル リセット、立下りエッジ スタート
・レベルトリガ スタート&リセット ワンショットモード
外部リセット信号(TMRx_ers)のレベルによってタイマをリセット&スタートするモードです。
カウントの開始は、エッジから2 タイマクロック後にカウント再開します。
T2HLT(タイマ2 ハードウェア制限制御レジスタ)のMODE(制御モード)によって、
スタート&リセットする信号レベルを指定します。
MODE = 10110 :Lレベル リセット、Hレベル スタート
MODE = 10111 :Hレベル リセット、Lレベル スタート
単安定モード
基本的な動作はワンショットモードと同じで、カウント1周分だけ動作します。
違いは、カウント値がT2PR(周期値)と一致してゼロに戻った時にカウントは停止しますが、
T2CON(タイマ2制御レジスタ)のON(タイマ有効)は自動的に0(タイマ無効)にならない点です。
従って、外部リセット信号(TMRx_ers)のエッジが来れば、タイマは再スタートします。
T2HLT(タイマ2 ハードウェア制限制御レジスタ)のMODE(制御モード)によって、
スタートするエッジの種類を指定します。
MODE = 10001 :立上りエッジ
MODE = 10010 :立下りエッジ
MODE = 10011 :立上り、又は立下りエッジ
※本モードもポストスケーラによる出力分周設定は無効になります。(つまり、出力分周比は1:1固定)
タイマ2の設定
タイマ本体の制御をタイマ制御(T2CON)と、クロック選択(T2CLKCON)レジスタで行い、
モード制御をハードウェア制限制御(T2HLT)と、外部リセット信号選択(T2RST)レジスタで行います。
T2CON(タイマ2制御レジスタ)
ON :タイマ有効化(1 = 有効、0 = 無効)
(1)ワンショットモードでは、ハードウェアによって自動的に0になる
CKPS :クロック分周比(プリスケーラ) 1:2CKPS
111 = 1:128(=27)、 ~、 0001 = 1:2(=21) 、0000 = 1:1(=20)
OUTPS :出力分周比(ポストスケーラ) 1:(1+ OUTPS)
1111 = 1:16、1110 = 1:15、~、0001 = 1:2 、0000 = 1:1
T2CLKCON(タイマ2 クロック選択レジスタ)
CS :クロック選択
1111 = 未使用
1110 = 未使用
1101 = LC4_out :CLC(※10)からの出力
1100 = LC3_out :CLC(※10)からの出力
1011 = LC2_out :CLC(※10)からの出力
1010 = LC1_out :CLC(※10)からの出力
1001 = ZCD1_出力 :ZCD(※13)ゼロクロス検出出力
1000 = NCO 出力 :NCO(※14)からのデジタル信号出力
0111 = CLKR(※11)出力クロック(外部出力クロック信号)
0110 = SOSC :外部サブ発振器(32.768 kHz 水晶発振子)
0101 = MFINTOSC/16 (31.25 kHz) (MFINTOSC:中周波内部発振器 (500 kHz))
0100 = LFINTOSC :低周波内部発振器 (31 kHz)
0011 = HFINTOSC :高周波内部発振器 (1 ~ 32 MHz)
0010 = FOSC :システムクロック
0001 = FOSC/4 :システムクロック/4
0000 = T2CKIPPS :PPS(※12)で選択されたピンからの入力信号
T2HLT(タイマ2 ハードウェア制限制御レジスタ)
PSYNC :プリスケーラ同期化(1 = Fosc/4 に同期、0 = 非同期)
(1)同期した場合、タイマ値の読み取りで有効な値が返されることが保証される
(2)同期した場合、タイマ2 はスリープ モードで動作できない
CKPOL :クロック極性
1 = 立下りエッジでカウントアップ
0 = 立上りエッジでカウントアップ
(3)ON = 1(タイマ有効)時は CKPOL を変更しないこと
CKSYNC :タイマ有効化の同期化(1 = TMR2_clk に同期、0 = 非同期)
(4)同期した場合、ON(タイマ有効)切替時のグリッチを防止できる
(5)同期した場合、ON = 1(タイマ有効)後、2クロック後にタイマ動作する
MODE :制御モード(TABLE 29-1参照)
(6)全モード共、ON = 1 で開始、ON = 0 で停止(カウント値を維持)
(7)TMR2 = PR2 の場合、動作モードに関係なく、次のクロックで TMR2 がクリアされる
T2RST(タイマ2外部リセット信号選択レジスタ)
RSEL :外部リセット信号選択
11111 = 未使用
・・・
10010 = 未使用
10001 = LC4_out :CLC(※10)からの出力
10000 = LC3_out :CLC(※10)からの出力
01111 = LC2_out :CLC(※10)からの出力
01110 = LC1_out :CLC(※10)からの出力
01101 = ZCD1_出力 :ZCD(※13)ゼロクロス検出出力
01100 = C2OUT_同期 :コンパレータ同期出力
01011 = C1OUT_同期 :コンパレータ同期出力
01010 = PWM7_out :PWMモジュールからのPWM信号
01001 = PWM6_out :PWMモジュールからのPWM信号
01000 = CCP5_out :CCPモジュール(※15)からのコンペア信号
00111 = CCP4_out :CCPモジュール(※15)からのコンペア信号
00110 = CCP3_out :CCPモジュール(※15)からのコンペア信号
00101 = CCP2_out :CCPモジュール(※15)からのコンペア信号
00100 = CCP1_out :CCPモジュール(※15)からのコンペア信号
00011 = タイマ6出力(注3)
00010 = タイマ4出力(注2)
00001 = タイマ2出力(注1)
00000 = T2IN :PPS(※12)で選択されたピンからの入力信号
注 1:タイマ2 の場合、使用不可
2:タイマ4 の場合、使用不可
3:タイマ6 の場合、使用不可
※10:CLC(Configurable Logic Cell):構成可能ロジック セル
CPLDの様に論理出力をプログラムで構成できる。
※11:CLKR(Clock Reference):システムクロックFoscを分周して外部ピンに出力できる信号
※12:PPS(Peripheral Pin Selectz):ペリフェラル・ピン選択モジュール
各ペリフェラルの入出力をデバイスの I/O ピンに割り当てる機能
※13:ZCD(ZERO CROSS DETECTION):ゼロクロス検出モジュール
入力した交流信号の0Vを横切るタイミングを検出
※14:NCO(Numerical Controlled Oscillator 数値制御発振器)モジュール
DDS(Direct Digital Synthesizer デジタル信号発生器)とも呼ばれ、
デジタル合成で任意の波形(正弦波や矩形波など)を出力する。
※15:CCP(Capture/Compare/PWM):キャプチャやコンペアを行うモジュール
※16:SMT(SIGNAL MEASUREMENT TIMER):信号測定タイマ
タイマ2割込みの設定例
学習キットの各種プログラムでは、タイマ2割込みを利用した1秒周期動作により、
時計やタイマーなどの正確な時間処理を行っています。
時計プログラムの詳細については下記で解説してます。
タイマープログラムの詳細については下記で解説してます。
ここではタイマ2の設定について概略を説明します。
タイマ2の設定は、初期設定関数SetConfig( )で行っており、
タイマ2クロックをFosc/4、プリスケーラの設定を1:8、
ポストスケーラの設定を1:1しています。
システムクロック周波数Foscは32MHzなので、
1MHzのタイマ2クロック信号となり、タイマ2レジスタをカウントアップします。
また、制御モードをソフトウェアゲートモードにしているので、
外部リセット信号は使用せず、タイマ2は常にカウントされます。
このプログラムでは、周期値T2PRを199にセットしており、
199+1=200カウント目に割込みが発生し、クロック周期は1/1MHz=1usなので、
割込み処理は1us×200=200us毎に行われます。
タイマ2割込みの処理内容は割込み処理関数 isr で定義しています。
割込み関数内では、まず、タイマ2割込みフラグ(TMR2IF)を0にクリアし、
次回の割込み処理が、次のタイマ周期値到達まで行わないようにします。
タイマ2割込み処理では、次の2つの変数を制御しています。
・タイマ2割込回数カウンタ(t2_icnt)
割込み発生(200us)毎にカウントアップする
・1秒経過フラグ(sec_flag)
t2_icntの値が定数TIMECONSTを超えたら、1にセットする
この時、t2_icntはゼロにクリアされる
TIMECONSTはソースファイル(nnct_kit_v3.c)の初めにある
define命令によって、固定値(4999)に定義されています。
#define TIMECONST 4999
これによって、200us×5000=1s経過後にsec_flagが1になることで、
1秒間の計測に利用されています。
この2つの変数はグローバル変数(※)として定義されており、
各関数(プログラム)でこの変数を使用することで、1秒間を計測しています。
※関数の外で宣言した変数で、同じソースファイル内の関数で共用できる。
詳しくは、別記事(C言語ソースファイル分割のやり方)で解説
また、タイマ2割込みを実行できるようにするために、
メインプログラムで以下の割込み許可を行っています。
PIE4bits.TMR2IE= 1 タイマ2割込を許可
INTCONbits.PEIE = 1 ペリフェラル割込を許可
INTCONbits.GIE = 1 グローバル割込を許可
上記のコードですが、厳密にはメインプログラムmain( )でコールする
各プログラム内にあります。