PIT : Programmable Interval Timer (Intel 8254) Edit

目次 Edit

基礎知識 Edit

PITとは Edit

Programmable Interval Timerの略で、システムのタイマー、カウンタなどに使用する。
PITには3つのタイマーがあり、メトロノームやキッチンタイマーのような働きをする。

PIT詳細 Edit

AT互換機では、1,193,182Hzのクロックで動作している。
1,193,182Hz = 1,193,182クロック/秒。
カウント値を0x2e9c(11932)に設定することで、11932回カウントする毎に割り込みが発生する。
1,193,182 / 11932 ≒ 100。1秒に100回割り込みが発生する。 = 0.01秒に1回割り込みが発生する。

割り込み回数の設定値表 Edit
割り込み回数/sカウント数
10/s119,318.20x1d216.333333333
100/s11,931.820x2e9b.d1eb851ec
1,000/s1,193.1820x4a9.2e978d4fe
10,000/s119.31820x77.51758e219
100,000/s11.931820xb.ee8bc169c
誤差0の設定値表 Edit

1秒あたりの誤差が0の割り込み回数は以下の通りです。
ですが、ハードウェアなんて適当なものだと思うので、少しくらい誤差があったほうが逆にぴったりになる気もします。(推測)

基本的には、回数が増えるにつれて、1秒あたりの誤差はどんどん増えていくので、1回の論理的誤差が0だからといって、実際の誤差が少ないとは限りません。
実際に調べてみる必要があるでしょう。

割り込み回数/sカウント数
41/s29,102.00x71ae
82/s14,551.00x38d7
14,551/s82.00x52
29,102/s41.00x29
596,591/s2.00x2

ただし、これらのカウント数だと、0.1秒や、0.01秒などの10進数の小数点数がとれないのであしからず。
1/14551秒とか、1/29102秒という単位で使えばいいかと思います。

計測結果
処理が追いつかない。orz...
QEMUで14551/sだと、ぜんぜん処理が追いつきませんでした。
割り込みの取りこぼしが明らかに多く、14551回カウントするのに2,3秒かかりました。。

I/Oポート、レジスタ Edit

PITのI/Oポートマップ Edit

I/OポートサイズR/W説明
0x00408bitR/Wカウンタ0(IRQ0)
0x00418bitR/Wカウンタ1
0x00428bitR/Wカウンタ2(ビープ音)
0x00438bitWコントールレジスタ

コントロールレジスタ (Port:0x0043) Edit

カウントモード (bit:0) Edit
  • 0:2進数カウント
  • 1:BCDカウント(2進化10進。こんなもので来ても困る。(そのまま表示の場合意外と使える。それ以外でも計算が簡単 by skyblue-tks))
動作モード (bit:1~3) Edit
  • 000:モード0(ターミナルカウント)指定したカウント値を0まで減算し、0になったらOUT信号を"H"にする。
  • 001:モード1(プログラマブルワンショット)指定した長さのワンショットパルス(OUT信号を"L")を出力する。
  • *10:モード2(レートジェネレータ)入力クロックをn分周する。
  • *11:モード3(方形波レートジェネレータ)入力クロックを出力デューティ比50%で n分周する。
  • 100:モード4(ソフトウェアトリガストローブ)指定したカウントが終了するとストローブパルスを出力する。
  • 101:モード5(ハードウェアトリガストローブ)外部トリガ入力によりカウントを開始し、カウントが終了するとストローブパルスを出力する。
カウンタアクセスモード (bit:4,5) Edit
  • 00:カウント値ラッチ
  • 01:下位8bitのリードロード
  • 10:上位8bitのリードロード
  • 11:16bitリードロード(下位8bit、上位8bitの順)
カウンタレジスタ指定 (bit:6,7) Edit
  • 00:カウンタ0
  • 01:カウンタ1
  • 10:カウンタ2
  • 11:リードバックコマンド

参考ソース Edit

#define	PORT_PIT_COUNTER0	( 0x0040 )		//カウンタ0
#define	PORT_PIT_COUNTER1	( 0x0041 )		//カウンタ1
#define	PORT_PIT_COUNTER2	( 0x0042 )		//カウンタ2
#define	PORT_PIT_CONTROL	( 0x0043 )		//コントロール

/*******************************************************************************
	PIT初期化
*******************************************************************************/
	Out1( PORT_PIT_CONTROL, 0x34 );		//カウンタ0, 16bitリードロード(下位8bit、上位8bitの順), モード2(レートジェネレータ), 2進数カウント
	Out1( PORT_PIT_COUNTER0, 0x9c );	//カウンタ値Low
	Out1( PORT_PIT_COUNTER0, 0x2e );	//カウンタ値High

参考・関連 Edit


Since 2008 July. OS Project Wiki
リロード   新規 下位ページ作成 編集 凍結 差分 添付 コピー 名前変更   ホーム 一覧 検索 最終更新 バックアップ リンク元   ヘルプ   最終更新のRSS