PC16550(AT互換機についているシリアルポートチップ)のページ †
- (by K & penさん, 2006.04.14)
おもにpenさんによる情報 †
- OS開発時においての活用方法を中心とした、9pinシリアルポートに関する資料です
- 別名、COM1 COM2 ポート
- COM1 = IRQ4, 0x03F8~0x3FF(8bitアクセス)
- COM2 = IRQ3, 0x02F8~0x2FF(8bitアクセス)
- 転送レート 300~115200bps (max 11.25kByte/sec)
- by pen
他のPCへの「データ送信」 †
受信側PCの設定 †
PC同士の結線には、クロスケーブルが使われます (両端が9PinメスのRS232Cクロスケーブル)
(参考)千石電商 @秋葉原 @sengoku.co.jp
それでは、受信側のPCでwindowsが使われると仮定した上で、設定へと進みます
以上で受信側の設定は完了です
なおQEMU内から送信した場合、QEMUの仮想シリアルコンソール(Alt+Ctrl+3)に受信されるため、これらの準備は不要です
開発中OSからの文字の送信 †
ここでは、次の設定で利用してみます。レジスタは全て8bitです
COM1
通信スピード(19200)
ラインコントロール(データbit=8, ストップビット=1, パリティ=なし)
制御pin(DTR=1,RTS=1)
IRQ(なし)
- 通信スピード
- [0x03FB] に 0x80をセット /* baud-rate */
- [0x03F8] に 0x06をセット /* 0x06=19200, 0x01=115200 */
- ラインコントロール
- [0x03FB] に 0x03をセット /* 8bit */
- 制御pin
- [0x03FC] に 0x0bをセット /* pin */
- 割り込み要因
- [0x03F9] に 0x00をセット(デフォルト) /* irq */
以上で初期設定は完了です。データ送信については、
- [0x03F8] に ASCIIコードをセット。必要ならば続いて、
- [0x03F8] に 2つ目のASCIIコードをセット
セットされると、すぐに送信されます。実質2バイト分のバッファがあります
このビットが1にセットされていれば、データ送信済みです
レジスタ構成 †
COM1(hex) | COM2(hex) | 名称 | R/W | 説明 |
03F8 | 02F8 | レシーブデータ | R | 受信データを読み出す(DLAB=0) |
03F8 | 02F8 | トランスミットデータ | W | 送信データを書き込む(DLAB=0) |
03F8 | 02F8 | ボーレート・LSB | R/W | 通信スピードの下位情報を書き込む(DLAB=1) |
03F9 | 02F9 | ボーレート・MSB | R/W | 通信スピードの上位情報を書き込む(DLAB=1) |
03F9 | 02F9 | インタラプトイネーブル | R/W | IRQ要因を書き込む(DLAB=0) |
03FA | 02FA | インタラプトID | R | 現在の割り込み要因を読み出す |
03FA | 02FA | FIFOコントロール | W | 内蔵FIFOの動作を書き込む |
03FB | 02FB | ラインコントロール | R/W | 送受信データのフォーマットを書き込む(bit7がDLAB) |
03FC | 02FC | モデムコントロール | R/W | 9Pinの制御ピンからの割り込みフラグを読み出す。制御ピンの操作を書き込む |
03FD | 02FD | ラインステータス | R | 通信状態を読み出す |
03FE | 02FE | モデムステータス | R | 9Pinの制御ピンを読み出す |
03FF | 02FF | スクラッチ | R/W | 制御に関係のないレジスタ |
ボーレート MSB/LSB †
1.8432Mhzから16分周されたクロックを元に、通信スピードを指定します
speed | fast | | | | | | | | | slow |
MSB/LSB(hex) | 00/01 | 00/02 | 00/03 | 00/06 | 00/0c | 00/18 | 00/30 | 00/60 | 00/c0 | 01/80 |
bps | 115.2k | 57.6k | 38.4k | 19.2k | 9600 | 4800 | 2400 | 1200 | 600 | 300 |
インタラプトイネーブル †
IRQ発生要因を指定します
bit | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
| rsv | rsv | rsv | rsv | modem | Rx line | Tx data | Rx data |
R/W | R=0 | R=0 | R=0 | R=0 | R/W | R/W | R/W | R/W |
- [bit3=1] モデムステータス割り込み
- [bit2=1] ラインステータス(Rx)割り込み
- [bit1=1] 送信データエンプティ割り込み
- [bit0=1@16450互換モード] データ受信割り込み
- [bit0=1@16550互換モード] Rx FIFOトリガーレベル&タイムアウト割り込み
インタラプトID †
割り込み発生時の発生要因が示されます
bit | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
| FIFO | FIFO | rsv | rsv | ID | ID | ID | pending |
R/W | R | R | R=0 | R=0 | R | R | R | R |
- [bit7,6=11b] 16550互換モード
- [bit7,6=00b] 16450互換モード
- [bit3,2,1] 割り込みがある場合に更新(複数割り込み時は高優先度を示す)
- (011b) Rx line status /優先度1st
- (010b) Rx data @16450互換モード /優先度2nd
- (010b) Rx FIFO trigger @16550互換モード /優先度2nd
- (110b) Rx FIFO time-out /優先度3rd
- (001b) Tx data empty @16450互換モード /優先度4th
- (001b) Tx FIFO empty @16550互換モード /優先度4th
- (000b) modem status /優先度5th
- [bit0=0] 割り込み有り(初期値1b)
FIFOコントロール †
内蔵Tx/Rx FIFO(各16Byte)を使用する場合は16550互換モードへ移行し、FIFOの設定を行います
bit | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
| Rx trigger | Rx trigger | rsv | rsv | DMA | Tx clear | Rx clear | enable |
R/W | W | W | W=0 | W=0 | W | W | W | W |
- [bit7,6] Rx FIFOが割り込みを起動する、受信データ数(Rx FIFO trigger)
- (00b) 1Byte
- (01b) 4Byte
- (10b) 8Byte
- (11b) 14Byte
- [bit3] 送受信割り込み要因
- (1b) Rx FIFO trigger, Rx FIFO time-out, Tx FIFO emptyを有効化
- (0b) 上記は無視され、1キャラクタ毎に割り込みを起動
- [bit2=1] Tx FIFOのデータをクリア。フラグは自動で0クリアされる
- [bit1=1] Rx FIFOのデータをクリア。フラグは自動で0クリアされる
- [bit0=1] 16550互換モードへ移行(初期値0b)
受信データ数が設定されたレベルに満たない場合、4キャラクタ時間後にタイムアウト割り込みが発生される
ラインコントロール †
bit | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
| DLAB | break | parity | parity | parity | stop | word | word |
R/W | R/W | R/W | R/W | R/W | R/W | R/W | R/W | R/W |
- [bit7=1] ボーレートMSB/LSBへのアクセスを可能にする
- [bit6=1] ブレーク出力 ※
- [bit5=1] 送信データのパリティ値を固定
- [bit4] (0b)奇数パリティ(1b)偶数パリティ
- [bit3=1] 送受信データのパリティ有効
- [bit2=1] ストップビット長を2にする
- [bit1,0=11b] 送受信データを8bitにする
※動作は未確認です
モデムコントロール †
bit | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
| rsv | rsv | rsv | loop | out2 | out1 | RTS | DTR |
R/W | R=0 | R=0 | R=0 | R/W | R/W | R/W | R/W | R/W |
- [bit4=1] ループバックモード※
- [bit3=1] 割り込みの発生を有効化
- [bit2=1] ループバックモード用※
- [bit1=1] RTSピンをアクティブ(アサート)にする
- [bit0=1] DTRピンをアクティブ(アサート)にする
※ロジックの診断を行う場合に使用するようです
ラインステータス †
bit | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
| Rx FIFO | Tx | Tx | break | framing | prarity | overrun | Rx |
R/W | R | R | R | R | R | R | R | R |
- [bit7=1] エラーのある受信データがRx FIFOにセットされた(パリティ、フレーミング、ブレーク)
- [bit6=1] データの送信が完了
- [bit5=1] 送信動作の開始によって、トランスミットデータレジスタ or Tx FIFOが空になった
- [bit4=1] ブレーク受信の発生
- [bit3=1] フレーミングエラー発生
- [bit2=1] パリティーエラーの発生
- [bit1=1] 受信データがあふれた
- [bit0=1] データを受信した
bit4~1のフラグが、ラインステータス割り込みの要因になる
モデムステータス †
bit | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
| DCD | RI | DSR | CTS | DCDx | RIx | DSRx | CTSx |
R/W | R | R | R | R | R | R | R | R |
- [bit7=1] 現在DCDピンは、アクティブ(アサート)な状態を受けている
- [bit6=1] 現在RIピンは、アクティブ(アサート)な状態を受けている
- [bit5=1] 現在DSRピンは、アクティブ(アサート)な状態を受けている
- [bit4=1] 現在CTSピンは、アクティブ(アサート)な状態を受けている
- [bit3=1] DCDピンが変化された
- [bit2=1] RIピンがインアクティブ(ネゲート)への変化を受けた
- [bit1=1] DSRピンが変化された
- [bit0=1] CTSピンが変化された
bit3~0のフラグが、モデムステータス割り込みの要因になる
おまけ †
ここでの用語解説 †
- Tx : トランスミット, 送信
- Rx : レシーブ, 受信
- FIFO : ハードウェアで組まれているリングバッファ
- rsv : リザーブ, 予約。該当部分の読み出しは bit=0、書き込みも bit=0
- IRQ : PICへのインタラプト
- 割り込み~ : デバイス内部のインタラプト
- キャラクタ : スタートビット+データ列+(パリティ)+ストップビット
- アサート : 起きている状態, RS232Cでは bit=1 はマイナス電圧
- ネゲート : 寝ている状態, RS232Cでは bit=0 はプラス電圧
- 9Pinの制御ピン : TxD/RxD/GND 以外の端子
Pin No. | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
記号 | CD | RxD | TxD | DTR | GND | DSR | RTS | CTS | RI |
In/Out | In | In | Out | Out | - | In | Out | In | In |
junk †
ここは、メモ書きです
(無接続) | GNDピン | 非通信時 | スタートビット | データ(1b) | データ(0b) | ストップビット |
0ボルト/あいまい | 0ボルト/しっかり | ↑プラス | ↓マイナス | ↓マイナス | ↑プラス | ↑プラス |
- リニアモード時には、BIOSで9600bps(max)通信。いいと思います
- モデム接続 & 68kMac時代には、お世話になった低速シリアル通信
- 過去にRS422に変換して50mほど引き回しました
- アサートは朝、ネゲートは、、
- happy hacking!
こめんと欄 †
- まだ書いてる途中です。ごめんなさいねぇ -- pen 2006-04-15 (土) 01:19:51
- http://www.linux.or.jp/JF/JFdocs/Modem-HOWTO-15.html 読み物 -- pen 2006-04-15 (土) 12:57:04
- fixいたしました。ご指摘頂戴します -- pen 2006-04-16 (日) 08:49:26
- penさんのおかげで、「はりぼてOS」にRS232制御プログラムを実装できました。ありがとうございました。今度の10月28日のOSCで展示する予定です。 -- uchan 2006-10-12 (木) 22:11:22
- オメデト! -- pen 2006-12-02 (土) 19:16:31