P16F18325には、16 bitが3本,8 bitが4本のタイマー•カウンターがあります。タイマー0には、多くの改良が加えられました。8ビットまたは16ビットのどちらにも設定でき、その入力信号も多岐に及びます。 また、プリスケーラ•ポストスケーラも強化されています。ここでは、内部クロックをカウントするタイマーとして使用し、タイマーがカウントアップする仕様について説明します。サンプルで作成したプログラムは、タイマー0がカウントアップするとLEDを点滅するものです。 主な改良点は以下の通り
Timer0は、8ビットのタイマー/カウンターまたは16ビットのタイマー/カウンターとして動作できます。モードは、T0CONレジスタのT016BITビットで選択されます。
内部クロックソースとともに使用する場合、モジュールはタイマーであり、命令サイクルごとにインクリメントします。モジュールを外部クロックソースとともに使用すると、タイマーまたはカウンターとして使用でき、外部ソースの立ち上がりエッジごとにインクリメントします。
通常の動作では、TMR0はクロックソースの立ち上がりエッジでインクリメントします。クロック入力の15ビットプリスケーラは、いくつかのプリスケールオプションを提供します(プリスケーラ制御ビット、T0CON1レジスタのT0CKPS <3:0>を参照)。
通常の動作では、TMR0はクロックソースの立ち上がりエッジでインクリメントします。クロック入力の15ビットプリスケーラは、いくつかのプリスケールオプションを提供します(プリスケーラ制御ビット、T0CON1レジスタのT0CKPS <3:0>を参照)。
TMR0Lの値は、各クロックサイクルで、TMR0HのコピーであるPeriodバッファーの値と比較されます。2つの値が一致すると、次のイベントが発生します。
8ビットモードでは、TMR0LおよびTMR0Hレジスタは両方とも直接読み取りおよび書き込み可能です。TMR0Lレジスタはデバイスのリセット時にクリアされますが、TMR0HレジスタはFFhで初期化されます。
プリスケーラとポストスケーラの両方のカウンタは、次のイベントでクリアされます。
カウンタモードでは、プリスケーラは通常、T0CON1レジスタのT0CKPSビットを「0000」に設定することによって無効になります。クロック入力(またはプリスケーラが使用されている場合はプリスケーラの出力)の立ち上がりエッジごとに、カウンタが「1」ずつインクリメントされます。
タイマーモードでは、有効なクロック信号があり、T0CON1レジスタ(レジスタ25-4)のT0CKPSビットが「0000」に設定されている限り、Timer0モジュールは命令サイクルごとにインクリメントします。プリスケーラが追加されると、タイマーはプリスケーラの値に基づいた速度で増分します。
T0CON1レジスタのT0ASYNCビットがセットされている場合(T0ASYNC = 1)、カウンタは入力ソース(または使用されている場合はプリスケーラの出力)の立ち上がりエッジごとにインクリメントします。非同期モードでは、クロックもスリープ中に動作し続けるという条件で、カウンタはスリープモード中に動作を継続できます。
25.1.1.1
Timer0 16ビットモードでの読み取りと書き込み
TMR0Hは、16ビットモードのTimer0の実際の上位バイトではありません。これは実際にはTimer0の実際の上位バイトのバッファバージョンであり、直接読み取りも書き込みもできません(図25-1を参照)。TMR0Hは、TMR0Lの読み取り中にTimer0の上位バイトの内容で更新されます。これにより、上位バイトと下位バイトの連続する読み取り間のロールオーバーにより、上位バイトと下位バイトの読み取りが有効であったことを確認することなく、Timer0の16ビットすべてを読み取ることができます。
同様に、Timer0の上位バイトへの書き込みもTMR0Hバッファレジスタを介して行う必要があります。TMR0Lへの書き込みが発生すると、上位バイトがTMR0Hの内容で更新されます。これにより、Timer0の16ビットすべてを一度に更新できます。
T0CON1レジスタのT0ASYNCビットがクリアされると(T0ASYNC = 0)、カウンタクロックはシステムオシレータ(FOSC / 4)に同期されます。同期モードで動作している場合、カウンタクロック周波数はFOSC / 4を超えることはできません。
T0CON1レジスタのT0CS <2:0>ビットは、Timer0のクロックソースを選択するために使用されます。レジスタ25-4は、クロックソースの選択を表示します。
内部クロックソースが選択されると、Timer0はタイマーとして動作し、Timer0プリスケーラーによって決定されるようにクロックソースの倍数でインクリメントします。
外部クロックソースが選択されている場合、Timer0はタイマーまたはカウンターとして動作できます。Timer0は、Timer0プリスケーラーによって決定されるように、外部クロックソースの立ち上がりエッジの倍数でインクリメントします。
ソフトウェアでプログラム可能なプリスケーラは、Timer0専用です。Timer0には、1:1から1:32768までの2の累乗の範囲の16のプリスケーラーオプションがあります。プリスケーラ値は、T0CON1レジスタのT0CKPS <3:0>ビットを使用して選択されます。
プリスケーラは直接読み取りまたは書き込みができません。プリスケーラレジスタのクリアは、TMR0LレジスタまたはT0CON1レジスタに書き込むことで実行できます。
ソフトウェアでプログラム可能なポストスケーラー(出力分周器)は、Timer0専用です。Timer0には、1:1から1:16の範囲の16のポストスケーラーオプションがあります。ポストスケーラ値は、T0CON0レジスタのT0OUTPS <3:0>ビットを使用して選択されます。
ポストスケーラーは直接読み取りまたは書き込みができません。ポストスケーラレジスタのクリアは、TMR0LレジスタまたはT0CON0レジスタに書き込むことで実行できます。
同期して動作している場合、Timer0は停止します。非同期で動作している場合、入力クロックソースがアクティブであれば、Timer0は引き続きインクリメントし、デバイスをスリープから復帰させます(Timer0割り込みが有効になっている場合)。
Timer0割り込みフラグビット(TMR0IF)は、次のいずれかの条件が発生したときにセットされます。
ポストスケーラビット(T0OUTPS <3:0>)が1:1動作(除算なし)に設定されている場合、TMR0の一致またはロールオーバーごとにT0IFフラグビットが設定されます。一般に、TMR0IFフラグビットは、T0OUTPS + 1の一致またはロールオーバーごとに設定されます。
Timer0割り込みが有効になっている場合(PIE0レジスタのTMR0IEビット= 1)、CPUが中断され、デバイスがスリープから復帰する場合があります(詳細については、セクション25.5「スリープ中の操作」を参照してください)。
Timer0出力は、RxyPPS出力選択レジスタを介して任意のI/Oピンにルーティングできます(詳細については、セクション12.0「ペリフェラルピン選択(PPS)モジュール」を参照してください)。Timer0出力は、アナログ-デジタルコンバータの自動変換トリガーなどの他の周辺機器でも使用できます。最後に、Timer0出力は、T0CON0レジスタ(レジスタ25-3)のTimer0出力ビット(T0OUT)を介してソフトウェアで監視できます。
TMR0_outは、8ビットモードでTMR0LとTMR0Hの間で一致が発生した場合、またはTMR0が16ビットモードでロールオーバーした場合に、1つのポストスケールクロック周期になります。Timer0出力は50%のデューティサイクルであり、TMR0_outのクロックの立ち上がりエッジごとに切り替わります。
Prescaler | 8bitモード | 16bitモード | ||||
---|---|---|---|---|---|---|
31k | 1M | 32M | 31k | 1M | 32M | |
1:1 | 33mS | 1024uS | 32uS | 8.5秒 | 262mS | 8192uS |
1:4 | 132mS | 4096uS | 128uS | 33秒 | 1048mS | 33mS |
1:32 | 1秒 | 33mS | 1024uS | 4.5分 | 8.4秒 | 262mS |
1:256 | 8.5秒 | 262mS | 8192uS | 36分 | 67秒 | 2.1秒 |
1:2048 | 68秒 | 2.1秒 | 66mS | 4.8時間 | 8.9分 | 16.8秒 |
1:32768 | 18分 | 33.6秒 | 1秒 | 77時間 | 2.4時間 | 4.5分 |
レジスタ | bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 |
---|---|---|---|---|---|---|---|---|
INTCON | GIE | PEIE | - | - | - | - | - | INTEDG |
PIR0 | - | - | TMR0IF | IOCIF | - | - | - | INTF |
PIE0 | - | - | TMR0IE | IOCIE | - | - | - | INTE |
TMR0L | Holding Register for TMR0L<7:0> | |||||||
TMR0H | Holding Register for TMR0H<7:0> or TMR0<15:8> | |||||||
T0CON0 | T0EN | - | T0OUT | T016BIT | T0OUTPS<3:0> | |||
T0CON1 | T0CS<2:0> | T0ASYNC | T0CKPS<3:0> |
レジスタ | BIT | 名 | 説明 | 1 | 0 | ||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
INTCON | 7 | GIE | 全インタラプトの使用許可 | 許可 | 否 | ||||||||||||||
PIR0 | 2 | TMR0IF | タイマー0 オーバーフロー発生フラグ | 発生 | 否 | ||||||||||||||
PIE0 | 5 | TMR0IE | タイマー0 インタラプトを使用許可 | 許可 | 否 | ||||||||||||||
T0CON0 | 7 | T0EN | タイマー0 ON/OFF選択 | ON | OFF | ||||||||||||||
5 | T0OUT | タイマー0 出力(read-only) | 1 | 0 | |||||||||||||||
4 | T016BIT | タイマー長の16/8bit選択 | 16bit | 8bit | |||||||||||||||
3 | T0OUTPS3 | ポストスケラー比率 0000=1:1(既定)
|
|||||||||||||||||
2 | T0OUTPS2 | ||||||||||||||||||
1 | T0OUTPS1 | ||||||||||||||||||
0 | T0OUTPS0 | ||||||||||||||||||
T0CON1 | 7 | T0CS2 | 入力クロックF選択
|
||||||||||||||||
6 | T0CS1 | ||||||||||||||||||
5 | T0CS0 | ||||||||||||||||||
4 | T0ASYNC | 入力のシステムクロックとの同期 | 非同期 | 同期 | |||||||||||||||
3 | T0CKPS3 | プリスケラー比率 0000=1:1(既定)
|
|||||||||||||||||
2 | T0CKPS2 | ||||||||||||||||||
1 | T0CKPS1 | ||||||||||||||||||
0 | T0CKPS0 |
PortC に接続されたLEDが点灯するプログラムを作成しました。System ClockはConfigで内部1MHzに設定 RC0 は TMR0IF で反転 RC3 は PPSでTMR0を出力する。
プログラム
/************************************* * File: Timer 0 sample * System ClockはConfigで内部1MHzに設定 * RC0 は TMR0IF で反転 * RC3 は PPSでTMR0を出力 * PIC16F18325 * Created on July 22, 2017, 2:37 PM **************************************/ #include <xc.h> #pragma config FEXTOSC = OFF,RSTOSC = HFINT1 // HFINTOSC (1MHz) #pragma config CLKOUTEN = OFF,CSWEN = OFF,FCMEN = OFF #pragma config MCLRE = OFF,PWRTE = OFF,WDTE = OFF,LPBOREN = OFF #pragma config BOREN = OFF,BORV = LOW,PPS1WAY = OFF,STVREN = ON #pragma config DEBUG = OFF #pragma config WRT = OFF,LVP = OFF,CP = OFF,CPD = OFF #define LED LATCbits.LATC0 void main(void) { TRISC = 0b110110; // RC0,RC3を出力に設定 // -------------------------------------------- // Timer0 は、Fosc/4を16bitモードでカウント // カウントアップ(262mS)でTMR0IFが「1」になる // TMR0IFを常時モニタしLED(RC0)を反転 // また、PPS機能を使いTMR0出力をRC3に出力する // -------------------------------------------- T0CON1 = 0b01000000; // Fosc/4 Sync PreS 1/1 T0CON0 = 0b10010000; // T0 ON 16bit Post 1/1 RC3PPS = 0b11100; // TMR0をRC3に出力 while(1){ if(TMR0IF){ // Timer0カウントアップを待つ TMR0IF=0; LED = !LED; // LEDを反転 } } }
入力クロック周波数とカウントアップ時間の関係