標準TTLだけ(!)でCPUをつくろう!(組立てキットです!)
(ホントは74HC、CMOSなんだけど…)
[第189回]

●C++でRS232C送信プログラムを作る

ハイパーターミナルにはバグがあることがわかってしまいました。
そういうことがなかったとしても、ハイパーターミナルは今回の目的である、データファイルの送信ということだけに限定して考えた場合、あまり使い勝手の良いツールだとは思えません。
いずれ自分でつくらなくてはいけないだろうなぁ、とは思っていました。
でも、正直なところ、C++は好きではない(C++に限らず、Cだろうが、VisualC++だろうが、よーするにCの眷属全てが、はっきり言って、嫌い。できるならば、さわりたくはない)。
だから、自分で作るのは、できるだけ後回しにして、とりあえずは、使えそうに思えたハイパーターミナルを使ってみよう、と考えたというのが、本当のところです。

ずるを決め込んで、手抜きをしようと思ったら、見事、天罰てきめんで、とんでもない手間がかかってしまいました。
こんなくらいなら、さっさとC++で送信プログラムを作ってしまえばよかった…!

●送信プログラムのソースリストです

/// w232.cpp for mycpu 09/03/13 3/20 3/21
/// rs232c write
#include <windows.h>
#include <stdio.h>
//
char outbf[250]="\0";
char comname[5]="\0";
unsigned long int dwWrite;
HANDLE hcom;
int open();
///
void main(int argn,char *args[])
{
FILE *rfp;
char *fname;
int dtbyte=0;
int e;
fname=args[1];
//file open
if(!(rfp=fopen(fname,"r")))
{
printf("can't open file %s\n",fname);
}// pass to end
//
else
{
sprintf(comname,"COM3");
e=open();
if(e==0)
{
printf("can't open %s\n",comname);fclose(rfp);
}// pass to end
else
//file read & send data
{
while(fgets(outbf,250,rfp)!='\0')
{
WriteFile(hcom,outbf,strlen(outbf),&dwWrite,NULL);
dtbyte=dtbyte+strlen(outbf);
}
printf("send data %d bytes\n",dtbyte);
CloseHandle(hcom);//com close
fclose(rfp);//file close
printf("end\n");
}
}
}
///
/// com open
int open()
{
hcom=CreateFile(comname,GENERIC_READ|GENERIC_WRITE,0,NULL,
OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
if(hcom==INVALID_HANDLE_VALUE)return 0;
/// get DCB & set DCB
DCB dcb;
GetCommState(hcom,&dcb);//get DCB
dcb.BaudRate=2400;
dcb.ByteSize=8;
dcb.Parity=NOPARITY;
dcb.StopBits=ONESTOPBIT;
if(!SetCommState(hcom,&dcb))return 0;//set DCB
return 1;
}
///

Web上では、あちこちで、「232Cのプログラムの書き方を教えて」なる質問をみかけます。
フリーソフトとして公開されているものもありますが、ソースリストを公開しているケースはそれほど多くはないようです。
たまたま公開されていても、汎用にということでしょうか、いろいろな機能が含まれていたりして、初心者には敷居が高すぎたりします。
しかし、ファイルを232Cで送信すればよい、というだけのプログラムならば、それほど複雑なものにはなりません。
そこで、どうせ、カクゴを決めて作るのならば、できるだけシンプルにして、初心者の方々にも理解可能なものにしてみよう、と考えて作ってみました。

なんて、エラそうなクチをきいたりしていますけれど、ことC++に限って言えば、不肖このワタクシメも、実は初心者です。
このプログラムだって、ちょこちょこって書いてしまったように見えますけれど、そんなに簡単にいくはずはないです。
実は何年か前に、当社のBASICボード、ZBK開発システムなるものを、WindowsXP対応にするために、それまで86アセンブラで書いてあったプログラムをC++で書き直さなくてはならなくなりました。
それまでのWindows95、98用ではパラレルポート(プリンタポート)を直接制御して、BASICボードとの間でデータの受け渡しをしていました。
ところがWindowsXPではI/Oを直接制御させてはくれません(NT、2000も同じ)。
さらに困ったことに、WindowsXPの普及にともなって、パラレルポートやシリアルポートのないパソコンが増えてきてしまいました。
みんなUSBになってしまいそうです。
そうすると、それに対応するためには、USB→シリアル変換ICを使った上で、それを制御するプログラムをC++で書くのが一番いい。とまあ、当時の私は考えたのですけれど、他の選択肢もあるかも知れません。
ともあれ、私はC++でいくことを選択したのです。

今回ここで公開したソースプログラムは、当時かなり苦戦苦闘しながら作ったZBK新開発セット付属のプログラムから、必要な部分のみを切り取って、できるだけシンプルになるようにアレンジしたものです。
必要があれば、”COM3”や、BaudRateのところだけ直せば、他はさわる必要はありません。

私が使っているコンパイラはBorland C++ Compiler5.5です。
フリーのコンパイラで、Borlandのサイトから無償でダウンロードできます(と思います)。
私自身はC++解説書に付録でついていたCDROMから落としました。
コマンドライン(DOSプロンプト)で軽快に動くコンパイラです。

上のソースリストは、そのままコピーしてnotepad(メモ帳)に貼り付ければ、それだけで、コンパイル可能なソースプログラムファイルに出来てしまうように、と考えて、プレーンテキスト形式で表示してあります。

上のソースプログラムリスト(w232.cpp)をコンパイルしている様子です。


bcc32 w232.cppで、いきなりコンパイル開始です。
bcc32.exeというのがborlandC++コンパイラ本体です。
ただちにコンパイルが開始されます。ごちゃごちゃあれこれしなくても、このようにキーボードから1行だけ打ち込めばそれで完了してしまいます。コマンドラインのいいところです(なかなか離れられません)。
警告が2行出ています。理由がわかっている警告は無視しても構いません。

1番目の警告は、
if(!(rfp=fopen(fname,"r")))
に対して出されたものです。間違いではありませんが、でも書き方が乱暴でした。
ここは、
rfp=fopen(fname,"r");
if(rfp==0)
のように書き直すと、警告が出されなくなります。

2番目の警告は、使わないけれど、省略できないので仕方がありません。
よくあるmain()ではなくて、今回はファイル名を取得する必要がありますから、通常は空白またはvoidにしておくmain()の中に、コマンドライン引数取得のための「おまじない」が置いてあります。

この程度の長さのプログラムなら、じきにコンパイル完了です。
同じディレクトリ(フォルダ)に、実行ファイルw232.exeが出来あがっています。

せっかくですから、w232.exeをただちに実行してみます。
w232 anatest1.htxです。
送信ファイル名anatest1.htxがコマンドライン引数の値として読み込まれます。
あっという間に、40バイトのデータが送信されてしまいました。
「つくるCPU」試作基板側ではエラーなく受信できたことは、言うまでもありません。

さて、せっかくプログラムリストも公開したことですし、本当は自分自身のための覚書きも兼ねて、C++プログラムの説明などもできるといいなあ、と思うのですけれど、でも、そうすると、またまた脱線してしまって、ちっとももとの回路の説明に戻ることができません。
ですから「C++お勉強のお部屋」は、いずれ、今進めている回路の説明が一区切りしたときにでもやりたいと思います。
2009.3.22upload

前へ
次へ
ホームページトップへ戻る