GBCの赤外線通信ポート用レジスタ(0xFF56)のビット4にシリアルポートのP14入力が繋がっていることを利用して、GBCでPCのキーボードやパーコードスキャナなどのPS/2インターフェイスが繋がるようになりましたが、そのPS/2インターフェイスと並んで昔から現在までずっと使われてきているPCの基本的な I/Oの代表としてシリアルインターフェイスがあります。RS−232Cという規格で親しまれてきたインターフェイスです。最近ではUSBインターフェイスが大変普及してきていますが、まだまだ(レガシィ)シリアルインターフェイスは健在です。
P14の発見者であるKen Kaarvik氏がP14を利用したrs232.asmというシリアルインターフェイスの実験プログラムを公開されています。通信仕様は、9600bps、データビット8、ストップビット1、パリティなし専用のものです。PCに繋いで Tera Term Pro でそのプログラムの動作確認をしてみました。キーボード入力のような1バイト単位のアイドル時間の長いデータの受信については問題ありませんでしたが、通常のシリアル通信で要求される文字列を連続して送るような複数バイトデータの受信を行った場合は、大半のデータを取りこぼしてしまい使い物にはなりませんでした。ソースファイルを調べてみると、スタートビットの受信待ちループの中で割り込みを許可していることが原因のようです。
このソースコードは、RGBASM用に書かれていたので、ドライバ部分を切り出しGBDKのC言語から利用できるようにしました。そしてドライバ内では割り込みを禁止にしてみると連続したデータの受信が正常にできました。GPSレシーバはこの通信仕様(9600bps)のドライバで動作しました。次にこのドライバをベースにケータイとの通信用(600bps)を作りました。
今後もこんな調子で機器毎に専用ドライバを作って行ったのでは脳がないので、PCのシリアル通信ドライバのように一通りの通信パラメータが指定でき汎用的に使える本格的なシリアル通信ドライバを開発し、それを公開して多くの方に利用してもらおうと考えました。
#define SPEED_110 0x00U // 0000 **** #define SPEED_300 0x10U // 0001 **** #define SPEED_600 0x20U // 0010 **** #define SPEED_1200 0x30U // 0011 **** #define SPEED_2400 0x40U // 0100 **** #define SPEED_4800 0x50U // 0101 **** #define SPEED_9600 0x60U // 0110 **** #define SPEED_14400 0x70U // 0111 **** #define DATA_8 0x00U // **** 0*** #define DATA_7 0x01U // **** 1*** #define STOP_1 0x00U // **** *0** #define STOP_2 0x04U // **** *1** #define PARITY_NONE 0x00U // **** **00 #define PARITY_ODD 0x03U // **** **11 #define PARITY_EVEN 0x02U // **** **10 #define ADJUST_M3P 0x00U // adjust -3% #define ADJUST_0P 0x01U // adjust 0% #define ADJUST_P3P 0x02U // adjust +3%
#include <gb.h>
#include "gb232.h"
:
#define BYTE_LENGTH 127 // 127 bytes receive
#define TIMEOUT_COUNT 1 // 0.1 msec
extern UBYTE gRcvData[127];
:
unsigned char gMsgTest[] = { "GB-232 (c)2001 TeamKNOx" };
:
void send_msg( unsigned char *msg )
{
while ( *msg ) {
send_gb232( *msg );
msg++;
}
}
:
:
void main()
{
UWORD error_result;
UBYTE error_code, error_byte;
:
:
set_gb232( SPEED_9600 | DATA_8 | STOP_1 | PARITY_NONE, ADJUST_0P );
init_gb232();
:
send_msg( gMsgTest );
:
error_result = receive_gb232( BYTE_LENGTH, TIMEOUT_COUNT );
error_code = (UBYTE)(error_result % 256);
error_byte = BYTE_LENGHT - (UBYTE)(error_result / 256) + 1;
:
:
}
|
Pin1: +5v(必要により) Pin2: TxD Pin3: 接続しません Pin4: RxD Pin5: 接続しません Pin6: GND |
![]() |



| bps | -3% | 0% | +3% |
| 14400 | 0.072 | 0.069 | 0.067 |
| 9600 | 0.107 | 0.104 | 0.101 |
| 4800 | 0.215 | 0.208 | 0.202 |
| 2400 | 0.429 | 0.417 | 0.404 |
| 1200 | 0.858 | 0.833 | 0.808 |
| 600 | 1.717 | 1.667 | 1.617 |
| 300 | 3.433 | 3.333 | 3.233 |
| 110 | 9.364 | 9.091 | 8.818 |