//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "RsStatusUnit.h"
#include "ReadCommUnit.h"
#include "MainUnit.h"
#include <vcl\inifiles.hpp>
#include <string.h>
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TMainForm *MainForm;
//---------------------------------------------------------------------------
__fastcall TMainForm::TMainForm(TComponent* Owner)
: TForm(Owner)
{
formCaption = "Serial Tester"; // タイトル
Memo1->Clear();
Edit1->Text = "0123456789";
CommOpen->Enabled = true; // メニューをトグルさせる
CommClose->Enabled = false;
Button1->Enabled = false; // [Send] ボタンを無効にする
// +----------------------------------------------+
// | INIファイルからRS-232C関連の値を読み込み |
// +----------------------------------------------+
// INIファイルの使い方「http://homepage1.nifty.com/kaityo/tips/tips3.html」
TIniFile *ini;
ini = new TIniFile(ChangeFileExt(Application->ExeName, ".ini"));
// INIファイルの値をRS-232C関連変数へセット
// RS_PortName = 1; // [1]=COM1,[2]=COM2...
// RS_BaudRate = 9600;
// RS_ByteSize = 8;
// RS_StopBits = 0; // [0]=1, [1]=1.5, [2]=2
// RS_Parity = 0; // [0]=なし,[1]=奇数,[2]=偶数
// RS_FlowControl = 0; // [0]=none,[1]=hard,[2]=soft
// RS_RxdBuffSize = 4096; // 6144 受信バッファサイズ(4096bytes〜Windows限界まで)
// RS_RxdMaxSize = 512; // 1024 受信読込最大サイズ(200の場合、受信時にErrorCode.8193が発生)
// RS_TxdBuffSize = 128; // 512 送信バッファサイズ
// RS_TxTimer = 1000; // 1000 送信タイムアウト
RS_PortName = StrToInt(ini->ReadString("RsStatus","PortName","0")) + 1;
RS_BaudRate = StrToInt(ini->ReadString("RsStatus","BaudRate","9600"));
RS_ByteSize = StrToInt(ini->ReadString("RsStatus","DataBits","8"));
RS_StopBits = StrToInt(ini->ReadString("RsStatus","StopBits","0"));
RS_Parity = StrToInt(ini->ReadString("RsStatus","Parity","2"));
RS_FlowControl = StrToInt(ini->ReadString("RsStatus","FlowControl","0"));
delete ini;
//+----------------+
//| タイトル |
//+----------------+
char str1[6] = "COM";
AnsiString str2 = IntToStr(RS_PortName); // 整数型を文字列型に変換
LPTSTR str3 = strcat(str1, str2.c_str()); // AnsiString型をchar型のポインタとして使用
MainForm->Caption = formCaption;
MainForm->Caption = MainForm->Caption + ": "+ str3;
MainForm->Caption = MainForm->Caption + "," + RS_BaudRate;
MainForm->Caption = MainForm->Caption + "," + IntToStr(RS_ByteSize);
if(RS_StopBits==0){ // ストップビット:1
MainForm->Caption = MainForm->Caption + ",1";
}else if(RS_StopBits==1){ // ストップビット:1.5
MainForm->Caption = MainForm->Caption + ",1.5";
}else if(RS_StopBits==2){ // ストップビット:2
MainForm->Caption = MainForm->Caption + ",2";
}
if(RS_Parity==0){ // パリティ:なし
MainForm->Caption = MainForm->Caption + ",none";
}else if(RS_Parity==1){ // パリティ:奇数
MainForm->Caption = MainForm->Caption + ",odd";
}else if(RS_Parity==2){ // パリティ:偶数
MainForm->Caption = MainForm->Caption + ",even";
}
if(RS_FlowControl==0){ // フロー制御:なし
MainForm->Caption = MainForm->Caption + ",none";
}else if(RS_FlowControl==1){ // フロー制御:Hardware(RTS/CTS)
MainForm->Caption = MainForm->Caption + ",hard";
}else if(RS_FlowControl==2){ // フロー制御:Software(Xon/Xoff)
MainForm->Caption = MainForm->Caption + ",soft";
}
MainForm->Caption = MainForm->Caption + " -- Port Disconnected --";
}
//---------------------------------------------------------------------------
// 終了
//---------------------------------------------------------------------------
void __fastcall TMainForm::FileExitClick(TObject *Sender)
{
exit(0);
}
//---------------------------------------------------------------------------
// ポート・オープン
//---------------------------------------------------------------------------
void __fastcall TMainForm::CommOpenClick(TObject *Sender)
{
// +--------------------+
// | 通信設定を取得 |
// +--------------------+
RS_PortName = RsStatusForm->CommPortName->ItemIndex + 1;
RS_BaudRate = StrToInt(RsStatusForm->CommBaudRate->Items->Strings[RsStatusForm->CommBaudRate->ItemIndex]);
RS_ByteSize = (BYTE)StrToInt(RsStatusForm->CommByteSize->Items->Strings[RsStatusForm->CommByteSize->ItemIndex]);
RS_StopBits = (BYTE)RsStatusForm->CommStopBits->ItemIndex;
RS_Parity = (BYTE)RsStatusForm->CommParity->ItemIndex;
RS_FlowControl = (BYTE)RsStatusForm->CommFlowControl->ItemIndex;
// --- オープン成功
if(RS232C_open()){
//+--------------------+
//| 受信スレッド |
//+--------------------+
m_pReadCommThread = new TReadCommThread(true, m_hComm); // 受信スレッドの生成2/2
// 受信スレッドを作動させる
m_pReadCommThread->Resume();
//+----------------+
//| タイトル |
//+----------------+
char str1[6] = "COM";
AnsiString str2 = IntToStr(RS_PortName); // 整数型を文字列型に変換
LPTSTR str3 = strcat(str1, str2.c_str()); // AnsiString型をchar型のポインタとして使用
MainForm->Caption = formCaption;
MainForm->Caption = MainForm->Caption + ": "+ str3;
MainForm->Caption = MainForm->Caption + "," + RS_BaudRate;
MainForm->Caption = MainForm->Caption + "," + IntToStr(RS_ByteSize);
if(RS_StopBits==0){ // ストップビット:1
MainForm->Caption = MainForm->Caption + ",1";
}else if(RS_StopBits==1){ // ストップビット:1.5
MainForm->Caption = MainForm->Caption + ",1.5";
}else if(RS_StopBits==2){ // ストップビット:2
MainForm->Caption = MainForm->Caption + ",2";
}
if(RS_Parity==0){ // パリティ:なし
MainForm->Caption = MainForm->Caption + ",none";
}else if(RS_Parity==1){ // パリティ:奇数
MainForm->Caption = MainForm->Caption + ",odd";
}else if(RS_Parity==2){ // パリティ:偶数
MainForm->Caption = MainForm->Caption + ",even";
}
if(RS_FlowControl==0){ // フロー制御:なし
MainForm->Caption = MainForm->Caption + ",none";
}else if(RS_FlowControl==1){ // フロー制御:Hardware(RTS/CTS)
MainForm->Caption = MainForm->Caption + ",hard";
}else if(RS_FlowControl==2){ // フロー制御:Software(Xon/Xoff)
MainForm->Caption = MainForm->Caption + ",soft";
}
MainForm->Caption = MainForm->Caption + " -- Port Connected --";
//+----------------+
//| メニュー |
//+----------------+
CommOpen->Enabled = false; // メニューをトグルさせる
CommClose->Enabled = true;
CommSetup->Enabled = false;
Button1->Enabled = true; // [Send] ボタンを有効にする
// --- オープン失敗
}else{
//+----------------+
//| タイトル |
//+----------------+
char str1[6] = "COM";
AnsiString str2 = IntToStr(RS_PortName); // 整数型を文字列型に変換
LPTSTR str3 = strcat(str1, str2.c_str()); // AnsiString型をchar型のポインタとして使用
MainForm->Caption = formCaption;
MainForm->Caption = MainForm->Caption + ": "+ str3;
MainForm->Caption = MainForm->Caption + "," + RS_BaudRate;
MainForm->Caption = MainForm->Caption + "," + IntToStr(RS_ByteSize);
if(RS_StopBits==0){ // ストップビット:1
MainForm->Caption = MainForm->Caption + ",1";
}else if(RS_StopBits==1){ // ストップビット:1.5
MainForm->Caption = MainForm->Caption + ",1.5";
}else if(RS_StopBits==2){ // ストップビット:2
MainForm->Caption = MainForm->Caption + ",2";
}
if(RS_Parity==0){ // パリティ:なし
MainForm->Caption = MainForm->Caption + ",none";
}else if(RS_Parity==1){ // パリティ:奇数
MainForm->Caption = MainForm->Caption + ",odd";
}else if(RS_Parity==2){ // パリティ:偶数
MainForm->Caption = MainForm->Caption + ",even";
}
if(RS_FlowControl==0){ // フロー制御:なし
MainForm->Caption = MainForm->Caption + ",none";
}else if(RS_FlowControl==1){ // フロー制御:Hardware(RTS/CTS)
MainForm->Caption = MainForm->Caption + ",hard";
}else if(RS_FlowControl==2){ // フロー制御:Software(Xon/Xoff)
MainForm->Caption = MainForm->Caption + ",soft";
}
MainForm->Caption = MainForm->Caption + " -- Port Disconnected --";
//+----------------+
//| メニュー |
//+----------------+
CommOpen->Enabled = true; // メニューをトグルさせる
CommClose->Enabled = false;
CommSetup->Enabled = true;
Button1->Enabled = false; // [Send] ボタンを無効にする
}
}
//---------------------------------------------------------------------------
// ポート・クローズ
//---------------------------------------------------------------------------
void __fastcall TMainForm::CommCloseClick(TObject *Sender)
{
//+--------------------------------+
//| シリアルポートのクローズ |
//+--------------------------------+
CloseHandle(m_hComm);
//+----------------+
//| タイトル |
//+----------------+
char str1[6] = "COM";
AnsiString str2 = IntToStr(RS_PortName); // 整数型を文字列型に変換
LPTSTR str3 = strcat(str1, str2.c_str()); // AnsiString型をchar型のポインタとして使用
MainForm->Caption = formCaption;
MainForm->Caption = MainForm->Caption + ": "+ str3;
MainForm->Caption = MainForm->Caption + "," + RS_BaudRate;
MainForm->Caption = MainForm->Caption + "," + IntToStr(RS_ByteSize);
if(RS_StopBits==0){ // ストップビット:1
MainForm->Caption = MainForm->Caption + ",1";
}else if(RS_StopBits==1){ // ストップビット:1.5
MainForm->Caption = MainForm->Caption + ",1.5";
}else if(RS_StopBits==2){ // ストップビット:2
MainForm->Caption = MainForm->Caption + ",2";
}
if(RS_Parity==0){ // パリティ:なし
MainForm->Caption = MainForm->Caption + ",none";
}else if(RS_Parity==1){ // パリティ:奇数
MainForm->Caption = MainForm->Caption + ",odd";
}else if(RS_Parity==2){ // パリティ:偶数
MainForm->Caption = MainForm->Caption + ",even";
}
if(RS_FlowControl==0){ // フロー制御:なし
MainForm->Caption = MainForm->Caption + ",none";
}else if(RS_FlowControl==1){ // フロー制御:Hardware(RTS/CTS)
MainForm->Caption = MainForm->Caption + ",hard";
}else if(RS_FlowControl==2){ // フロー制御:Software(Xon/Xoff)
MainForm->Caption = MainForm->Caption + ",soft";
}
MainForm->Caption = MainForm->Caption + " -- Port Disconnected --";
//+----------------+
//| メニュー |
//+----------------+
CommOpen->Enabled = true; // メニューをトグルさせる
CommClose->Enabled = false;
CommSetup->Enabled = true;
Button1->Enabled = false; // [Send] ボタンを無効にする
}
//---------------------------------------------------------------------------
// 送信
//---------------------------------------------------------------------------
void __fastcall TMainForm::Button1Click(TObject *Sender)
{
char str[MAX_PATH]; // 書き込みデータバッファ
int writeSize; //
DWORD dwErrors; // エラー情報
COMSTAT ComStat; // デバイスの状態
DWORD dwWritten; // ポートへ書き込んだバイト数
int freeBufSize; //
// 1文字ずつ出力
AnsiString OutChar = Edit1->Text;
for (int i=1; i<OutChar.Length()+1; i++ ){
AnsiString OneChar = OutChar[i];
// 文字列出力
strcpy(str, OneChar.c_str());
writeSize = strlen(str);
// 送信バッファに書き込めるまで待機
do{
ClearCommError(m_hComm, &dwErrors, &ComStat);
Application->ProcessMessages();
freeBufSize = MAX_PATH - ComStat.cbOutQue;
}while(freeBufSize <= writeSize );
//データをバッファへ書き込む
WriteFile(m_hComm, str, writeSize, &dwWritten, NULL);
}
}
//---------------------------------------------------------------------------
// CommSetupClick
//---------------------------------------------------------------------------
void __fastcall TMainForm::CommSetupClick(TObject *Sender)
{
RsStatusForm->ShowModal();
}
//---------------------------------------------------------------------------
// RS232C_open
//---------------------------------------------------------------------------
bool __fastcall TMainForm::RS232C_open()
{
//+--------------------------------+
//| シリアルポートのオープン |
//+--------------------------------+
char str1[6] = "COM";
AnsiString str2 = IntToStr(RS_PortName); // 整数型を文字列型に変換
LPTSTR str3 = strcat(str1, str2.c_str()); // AnsiString型をchar型のポインタとして使用
m_hComm = CreateFile(str3, // オープンするポート
GENERIC_READ | GENERIC_WRITE, // アクセスモード
0, // 共有モード
NULL, // セキュリティー属性
OPEN_EXISTING, // 作成方法
FILE_ATTRIBUTE_NORMAL, // ファイル属性
NULL); // コピーする属性付きファイルのハンドル
if(m_hComm == INVALID_HANDLE_VALUE){ // 通信ポート接続失敗
Application->MessageBox("Error opening port.\n\nSelect new settings,try again.","Error",MB_OK);
return(0);
}
//+--------------------------+
//| DCB構造体の設定 |
//+--------------------------+
GetCommState(m_hComm, &m_DCB); // 通信パラメータを取得
m_DCB.BaudRate = RS_BaudRate; // ボーレート
m_DCB.ByteSize = RS_ByteSize; // 受信データのバイトあたりのビット数(4〜8)
if(RS_Parity==0){ // ストップビット:1
m_DCB.StopBits = ONESTOPBIT;
}else if(RS_Parity==1){ // ストップビット:1.5
m_DCB.StopBits = ONE5STOPBITS;
}else if(RS_Parity==2){ // ストップビット:2
m_DCB.StopBits = TWOSTOPBITS;
}
if(RS_Parity==0){ // パリティ:なし
m_DCB.fParity = false;
m_DCB.Parity = NOPARITY;
}else if(RS_Parity==1){ // パリティ:奇数
m_DCB.fParity = true;
m_DCB.Parity = ODDPARITY;
}else if(RS_Parity==2){ // パリティ:偶数
m_DCB.fParity = true;
m_DCB.Parity = EVENPARITY;
}
// m_DCB.fOutxCtsFlow = false; // CTS(ClearToSend)出力フロー制御
// m_DCB.fOutxDsrFlow = false; // DSR(DataSetReady)出力フロー制御
// m_DCB.fDtrControl = DTR_CONTROL_HANDSHAKE; // DTR(DataTerminalReady)フロー制御の種類
// m_DCB.fRtsControl = RTS_CONTROL_HANDSHAKE; // RTS(RequestToSend)フロー制御の種類
// m_DCB.fInX = true; // XON/XOFF入力フロー制御
// m_DCB.fOutX = true; // XON/XOFF出力フロー制御
// m_DCB.fNull = true; // ヌル ストリッピングを有効
// m_DCB.XonChar = 0x11; // 送受信時のXON文字
// m_DCB.XoffChar = 0x13; // 送受信時のXOFF文字
SetCommState(m_hComm, &m_DCB); // 通信パラメータをセット
//+--------------------------+
//| タイムアウトの設定 |
//+--------------------------+
GetCommTimeouts(m_hComm, &m_CommTimeOuts); // タイムアウト情報を取得
m_CommTimeOuts.ReadIntervalTimeout = 0;
m_CommTimeOuts.ReadTotalTimeoutMultiplier = 0; // 0 0
m_CommTimeOuts.ReadTotalTimeoutConstant = 100; // 100 0
m_CommTimeOuts.WriteTotalTimeoutMultiplier = 0; // 0 200
m_CommTimeOuts.WriteTotalTimeoutConstant = 0; // 0 10000
SetCommTimeouts(m_hComm, &m_CommTimeOuts); // タイムアウト値をセット
// --- 監視するイベントのセットを指定する
// SetCommMask(m_hComm, EV_RXCHAR);
//+----------------------------------------------------+
//| 端末をレディ状態に(RTS、DTR信号をオンにする) |
//+----------------------------------------------------+
if (EscapeCommFunction(m_hComm, SETRTS | SETDTR) == true){ // RTS、DTR信号設定成功
}else{ // RTS、DTR信号設定失敗
Application->MessageBox("Error opening port.\n\nSelect new settings,try again.","Error",MB_OK);
return(0);
}
return(1); // 正常終了
}
|