18F26J50には、5本のタイマーがあります。タイマー0は、8ビットモードと16ビットモードをソフトウエアで選ぶことができます。 ここでは、内部クロックをカウントする16ビットタイマーとして使用し、タイマーがカウントアップする仕様について説明します。サンプルで作成したプログラムは、タイマー0がカウントアップするとLEDを点滅するものです。なお、下表空色のレジスタ項目の設定は、C18のライブラリtimers関数である(OpenTimer0)を利用するためCプログラムで個別に設定する必要はありません。下表レジスタ項目の緑色はリセット直後の設定を表しています。
*注意*
Timer0 の全16ビットを一括して読み出すために、下位バイトを読み出すタイミングで上位バイトの値を読み出しTMR0H(バッファ)に保存します。これによって、Timer0 の全16 ビットの値を同時に取得することができます。書き込みは、まず、TMR0H のバッファレジスタに上位バイトに書き込む値を保存した後で、TMR0L への書き込みが実行されると、TMR0H の内容によって上位バイトも更新されます。これによって、Timer0 の全16 ビットを同時に更新できます。
*注意*
T0CKIピンは、Peripheral Pin Select (PPS)機能でプログラムで、物理的に接続するピンを指定します。
高低2レベルの優先度を使用するタイマー0に関連するレジスターを一覧で説明します。
| レジスタ | bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 |
|---|---|---|---|---|---|---|---|---|
| TMR0L | Timer0 Register, Low Byte | |||||||
| TMR0H | Timer0 Register, High Byte | |||||||
| RCON | IPEN | SBOREN | — | RI | TO | PD | POR | BOR |
| INTCON | GIE/GIEH | PEIE/GIEL | TMR0IE | INTIE | RABIE | TMR0IF | INT0IF | RABIF |
| INTCON2 | nRABPU | INTEDG0 | INTEDG1 | INTEDG2 | — | TMR0IP | — | RABIP |
| T0CON | TMR0ON | T08BIT | T0CS | T0SE | PSA | T0PS2 | T0PS1 | T0PS0 |
| レジスタ | BIT | 名 | 説明 | 1 | 0 | |||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| RCON | 7 | IPEN | 2レベルのインタラプト優先度 | 使用 | 不 | |||||||
| INTCON2 | 2 | TMR0IP | タイマー0 インタラプト優先度 | 高 | 低 | |||||||
| INTCON | 7 | GIEH | 高優先度インタラプトを使用許可 | 許可 | 不 | |||||||
| 6 | GIEL | 低優先度インタラプトを使用許可 | 許可 | 不 | ||||||||
| 5 | TMR0IE | タイマー0 インタラプトを使用許可 | 許可 | 不 | ||||||||
| 2 | TMR0IF | タイマー0 オーバーフロー発生フラグ | 発生 | |||||||||
| T0CON | 7 | TMR0ON | タイマー0 ON/OFF | ON | OFF | |||||||
| 6 | T08BIT | タイマー0 8/16Bitモード | 8 | 16 | ||||||||
| 5 | T0CS | タイマー0 クロック選択 | 外部 | 内部 | ||||||||
| 4 | T0SE | タイマー0 クロックエッジ選択 | UP | DN | ||||||||
| 3 | PSA | タイマー0 プリスケラー使用 | 不 | 使用 | ||||||||
| 2 | T0PS2 | プリスケラー比率
|
||||||||||
| 1 | T0PS1 | |||||||||||
| 0 | T0PS0 | |||||||||||
クロック周波数とタイムアップ間隔
| Prescalerl | 8bitモード | 16bitモード | ||||
|---|---|---|---|---|---|---|
| 31k | 4M | 48M | 31k | 4M | 48M | |
| なし | 33mS | 256μS | 21μS | 8.5Sec | 66mS | 5.5mS |
| 1:4 | 132mS | 1024μS | 85μS | 34Sec | 262mS | 22mS |
| 1:32 | 1S | 8.2mS | 682μS | 4.5min | 2.1Sec | 175mS |
| 1:256 | 8.5Sec | 66mS | 5.5mS | 36min | 16.7Sec | 1.4Sec |
PortC - RC2 に接続されたLEDが点灯するプログラムを作成しました。Timer0で内部クロック(4MHz)をカウントし、カウントオーバー(262mS間隔)でLEDが点滅する。
プログラム
// File name: Timer0
// Description: Timer0 example
// Timer0で内部クロック(4MHz)をカウントし、
// カウントオーバーでLEDを点滅させる。
// Notes: 4MHz内部クロック
// LED RB0
// LED RB1
// LED RB2
// LED RB3
// Language: MPLAB xc8
// Target: PIC18F26J50
#include <xc.h>
//
#pragma config WDTEN = OFF, PLLDIV = 2, STVREN = ON, XINST = OFF
#pragma config CPUDIV = OSC1, CP0 = OFF
#pragma config OSC = INTOSC, T1DIG = OFF
#pragma config LPT1OSC = OFF, FCMEN = OFF, IESO = OFF
#pragma config WDTPS = 32768
#pragma config DSWDTOSC = INTOSCREF, RTCOSC = T1OSCREF
#pragma config DSBOREN = OFF, DSWDTEN = OFF, DSWDTPS = 8192
#pragma config IOL1WAY = OFF, MSSP7B_EN = MSK7
#pragma config WPFP = PAGE_1, WPEND = PAGE_0, WPCFG = OFF
#pragma config WPDIS = OFF
void main(void){
OSCCON = 0b01100010; // 内部クロック4Mhz
LATB = 0; // PortCのすべてのビットを「0」
TRISB = 0b11110000; // LEDの接続されているポートを出力に設定
T0CON = 0b10000001; // Timer 0 設定(262mSecごと)
// 16BIT_mode SOURCE_INT PS_1/4
LATB = 0x03; // LED 2個を点灯
while(1){ // 繰り返しループ
while(! INTCONbits.TMR0IF); // Timer 0 のタイムアップを待つ
INTCONbits.TMR0IF = 0; // Timer 0 からのキャリーフラッグをクリア
LATB ^= 0x0F; // LED 4個の出力を反転
}
}