串口通讯实验.docx
《串口通讯实验.docx》由会员分享,可在线阅读,更多相关《串口通讯实验.docx(20页珍藏版)》请在冰豆网上搜索。
串口通讯实验
实验3串口通讯实验
3.1实验设计
为了实现在计算机中两个端口之间进行数据通讯,在没有硬件设备的条件下可以利用特定的软件来设置几个虚拟的连接端口,然后通过函数CreateFile()打开串口,根据串口名称打开串口,返回串口资源句柄。
通过GetCommState()获取串口参数,并通过SetCommState()设置串口参数。
所需要设置的串口参数包括波特率、停止位和校验位和超时限制等。
之后可以通过ReadFile()和WriteFile()读取串口数据或者向串口发送数据,这两个函数均需要传递串口句柄。
通过调用CloseHandle()关闭串口。
在程序里设置了两个串口句柄,用于同时打开两个串口,并且他们之间可以相互收发数据。
3.2试验程序
//---------------------------------------------------------------------------
#include
#pragmahdrstop
#include"Com.h"
#include
//---------------------------------------------------------------------------
#pragmapackage(smart_init)
#pragmaresource"*.dfm"
TforCom*forCom;
//---------------------------------------------------------------------------
__fastcallTforCom:
:
TforCom(TComponent*Owner)
:
TForm(Owner)
{
Hand[0].btOpenCom=btOpenCom1;//初始化结构体
Hand[0].btCloseCom=btCloseCom1;
Hand[0].btSetCom=btSetCom1;
Hand[0].btReadCom=btReadCom1;
Hand[0].btClear=btClear1;
Hand[0].btSend=btSendMes1;
Hand[0].btReceive=btReceiveMes1;
Hand[0].cbxComName=cbxComName1;
Hand[0].cbxBute=cbxBute1;
Hand[0].cbxStopbit=cbxStopbit1;
Hand[0].cbxCheck=cbxCheck1;
Hand[0].hCom=NULL;
Hand[0].ComNum=0;
Hand[0].Memo=memoCom1;
Hand[0].edSendNum=edSendNum1;
Hand[0].edReceiveNum=edReceiveNum1;
Hand[0].edMessage=edMessage1;
Hand[1].btOpenCom=btOpenCom2;
Hand[1].btCloseCom=btCloseCom2;
Hand[1].btSetCom=btSetCom2;
Hand[1].btReadCom=btReadCom2;
Hand[1].btClear=btClear2;
Hand[1].btSend=btSendMes2;
Hand[1].btReceive=btReceiveMes2;
Hand[1].cbxComName=cbxComName2;
Hand[1].cbxBute=cbxBute2;
Hand[1].cbxStopbit=cbxStopbit2;
Hand[1].cbxCheck=cbxCheck2;
Hand[1].hCom=NULL;
Hand[1].ComNum=0;
Hand[1].Memo=memoCom2;
Hand[1].edSendNum=edSendNum2;
Hand[1].edReceiveNum=edReceiveNum2;
Hand[1].edMessage=edMessage2;
//inti=0;
myThread=newthreadRecive(true,0);
myThread2=newthreadRecive(true,1);
for(inti=0;i<2;i++)//设置控件属性
{
SetOption(i);
}
}
//---------------------------------------------------------------------------
//关闭串口
void__fastcallTforCom:
:
btCloseCom1Click(TObject*Sender)
{
intIndex=0;
Index=this->FindIndex(Sender);
if(Index==-1)
{
ShowMessage("未知错误");
return;
}
intm;
m=CloseHandle(Hand[Index].hCom);
if(m==0)
{
ShowMessage("Com"+IntToStr(Hand[Index].ComNum)+"关闭失败!
");
return;
}
Hand[Index].hCom=NULL;
Hand[Index].Memo->Lines->Add("Com"+IntToStr(Hand[Index].ComNum)+"成功关闭");
Hand[Index].ComNum=0;
SetOption(Index);
if(Index==0)
{
myThread->Suspend();//挂起线程
}
elseif(Index==1)
{
myThread2->Suspend();
}
}
//---------------------------------------------------------------------------
void__fastcallTforCom:
:
btSetCom1Click(TObject*Sender)//配置串口
{
intIndex=0;
Index=this->FindIndex(Sender);
if(Index==-1)
{
ShowMessage("未知错误");
return;
}
DCBdcb1;
if(GetCommState(Hand[Index].hCom,&dcb1)==0)
{
ShowMessage("配置参数失败!
");
return;
}
dcb1.BaudRate=StrToInt(Hand[Index].cbxBute->Text);
dcb1.StopBits=Hand[Index].cbxStopbit->ItemIndex;
dcb1.Parity=2-Hand[Index].cbxCheck->ItemIndex;
dcb1.ByteSize=8;
if(SetCommState(Hand[Index].hCom,&dcb1)==0)
{
ShowMessage("配置参数失败!
");
return;
}
Hand[Index].Memo->Lines->Add("Com"+IntToStr(Hand[Index].ComNum)+"配置成功");
}
//---------------------------------------------------------------------------
void__fastcallTforCom:
:
btReadCom1Click(TObject*Sender)//读取串口参数
{
intIndex=0;
Index=this->FindIndex(Sender);
if(Index==-1)
{
ShowMessage("未知错误");
return;
}
DCBdcb1;
if(GetCommState(Hand[Index].hCom,&dcb1)==0)
{
ShowMessage("读取参数失败!
");
return;
}
TMemo*memo;
memo=Hand[Index].Memo;
intm;
charn;
m=dcb1.DCBlength;
memo->Lines->Add("DCBlength:
"+IntToStr(m));
m=dcb1.BaudRate;
memo->Lines->Add("BaudRate:
"+IntToStr(m));
m=dcb1.fBinary;
memo->Lines->Add("fBinary:
"+IntToStr(m));
m=dcb1.fParity;
memo->Lines->Add("fParity:
"+IntToStr(m));
m=dcb1.fOutxCtsFlow;
memo->Lines->Add("fOutxCtsFlow:
"+IntToStr(m));
m=dcb1.fOutxDsrFlow;
memo->Lines->Add("fOutxDsrFlow:
"+IntToStr(m));
m=dcb1.fDtrControl;
memo->Lines->Add("fDtrControl:
"+IntToStr(m));
m=dcb1.fDsrSensitivity;
memo->Lines->Add("fDsrSensitivity:
"+IntToStr(m));
m=dcb1.fTXContinueOnXoff;
memo->Lines->Add("fTXContinueOnXoff:
"+IntToStr(m));
m=dcb1.fOutX;
memo->Lines->Add("fOutX:
"+IntToStr(m));
m=dcb1.fInX;
memo->Lines->Add("fInX:
"+IntToStr(m));
m=dcb1.fErrorChar;
memo->Lines->Add("fErrorChar:
"+IntToStr(m));
m=dcb1.fNull;
memo->Lines->Add("fNull:
"+IntToStr(m));
m=dcb1.fRtsControl;
memo->Lines->Add("fRtsControl:
"+IntToStr(m));
m=dcb1.fAbortOnError;
memo->Lines->Add("fAbortOnError:
"+IntToStr(m));
m=dcb1.fDummy2;
memo->Lines->Add("fDummy2:
"+IntToStr(m));
m=dcb1.wReserved;
memo->Lines->Add("wReserved:
"+IntToStr(m));
m=dcb1.XonLim;
memo->Lines->Add("XonLim:
"+IntToStr(m));
m=dcb1.XoffLim;
memo->Lines->Add("XoffLim:
"+IntToStr(m));
m=dcb1.ByteSize;
memo->Lines->Add("ByteSize:
"+IntToStr(m));
m=dcb1.Parity;
memo->Lines->Add("Parity:
"+IntToStr(m));
m=dcb1.StopBits;
memo->Lines->Add("StopBits:
"+IntToStr(m));
m=dcb1.XonChar;
memo->Lines->Add("XonChar:
"+IntToStr(m));
m=dcb1.XoffChar;
memo->Lines->Add("XoffChar:
"+IntToStr(m));
m=dcb1.ErrorChar;
memo->Lines->Add("ErrorChar:
"+IntToStr(m));
m=dcb1.EofChar;
memo->Lines->Add("EofChar:
"+IntToStr(m));
m=dcb1.EvtChar;
memo->Lines->Add("EvtChar:
"+IntToStr(m));
m=dcb1.wReserved1;
memo->Lines->Add("wReserved1:
"+IntToStr(m));
}
//---------------------------------------------------------------------------
void__fastcallTforCom:
:
btClear1Click(TObject*Sender)//清除Memo
{
intIndex=0;
Index=this->FindIndex(Sender);
if(Index==-1)
{
ShowMessage("未知错误");
return;
}
Hand[Index].Memo->Clear();
}
//---------------------------------------------------------------------------
void__fastcallTforCom:
:
btSendMes1Click(TObject*Sender)//发送消息
{
intIndex=0;
inti;
unsignedcharbufToSend[32];
intnumToSend=0;
DWORDdwLength;
AnsiStringfinal;
AnsiStringMess;
AnsiStringStrMid;
intlbNum;//实际发送的字节数
Index=this->FindIndex(Sender);
if(Index==-1)
{
ShowMessage("未知错误");
return;
}
numToSend=StrToInt(Hand[Index].edSendNum->Text);
Mess=Hand[Index].edMessage->Text;
for(i=0;i{
Mess=Mess.Trim();
if(Mess.Length()==0)
{
break;
}
elseif(Mess.Length()==1)//数据位不全,高四位补0
{
//ShowMessage("发送数据格式有误");
//return;
Mess="0"+Mess;
}
StrMid=Mess.SubString(1,2);
Mess=Mess.SubString(3,Mess.Length()-2);
try
{
bufToSend[i]=StrToInt("0x"+StrMid);
//throw("");
}
catch(...)
{
ShowMessage("发送数据格式有误");
return;
}
final=final+StrMid+"";
}
numToSend=i;
intm;
m=WriteFile(Hand[Index].hCom,
bufToSend,
numToSend,
&dwLength,
NULL);
if(m==0)
{
ShowMessage("发送失败!
");
return;
}
lbNum=dwLength;
Hand[Index].Memo->Lines->Add("成功发送"+IntToStr(lbNum)+"个字节");
if(lbNum>0)
{
Hand[Index].Memo->Lines->Add(final);//发送0个以上字节时,显示
}
}
//---------------------------------------------------------------------------
void__fastcallTforCom:
:
btReceiveMes1Click(TObject*Sender)//接收消息
{
intIndex=0;
unsignedcharbufToRead[32];
//COMMTIMEOUTSCommTimeOuts;
intnumToRead;
AnsiStringmess="";;
DWORDlpNum;
Index=this->FindIndex(Sender);
if(Index==-1)
{
ShowMessage("未知错误");
return;
}
numToRead=StrToInt(Hand[Index].edReceiveNum->Text);
intm;
//GetCommTimeouts(Hand[Index].hCom,&CommTimeOuts);//读超时
//CommTimeOuts.ReadIntervalTimeout=100;
//CommTimeOuts.ReadTotalTimeoutMultiplier=1;
//CommTimeOuts.ReadTotalTimeoutConstant=100;/*读数据总超时常量*/
//CommTimeOuts.WriteTotalTimeoutMultiplier=1;
//CommTimeOuts.WriteTotalTimeoutConstant=100;
//SetCommTimeouts(Hand[Index].hCom,&CommTimeOuts);
m=ReadFile(Hand[Index].hCom,
bufToRead,
numToRead,
&lpNum,
NULL);
if(m==0)
{
ShowMessage("接收失败!
");
return;
}
numToRead=lpNum;
chartemp[3];
for(inti=0;i{
m=bufToRead[i];
sprintf(temp,"%02X",m);
mess=mess+temp+"";
}
Hand[Index].Memo->Lines->Add("成功接收"+IntToStr(lpNum)+"个字节");
if(lpNum>0)
{
Hand[Index].Memo->Lines->Add(mess);
}
}
//---------------------------------------------------------------------------
intTforCom:
:
FindIndex(TObject*Sender)//确定是按钮的来源
{
TButton*btTemp;
AnsiStringtemp;
btTemp=dynamic_cast(Sender);
temp=btTemp->Name;
temp=temp.SubString(temp.Length(),1);
if(temp=="1")
{
return0;
}
elseif(temp=="2")
{
return1;
}
return-1;
}
//------------------------------------------------------------------------
void__fastcallTforCom:
:
btOpenCom1Click(TObject*Sender)//打开串口
{
intIndex=0;
unsignedchari;
AnsiStringComName;
intComNum;
Index=this->FindIndex(Sender);
if(Index==-1)
{
ShowMessage("未知错误");
return;
}
ComName=Hand[Index].cbxComName->Text;
ComNum=StrToInt(ComName.SubString(ComName.Length(),1));
if(Hand[Index].hCom!
=NULL)
{
ShowMessage("串口已打开!
");
return;
}
i=Index^0x01;//判断此串口是否在旁边窗口打开.
if(Hand[i].hCom!
=NULL&&Hand[i].ComNum==ComNum)
{
if(Index==0)
{
ShowMessage(ComName+"已在右边打开");
}
else
{
ShowMessage(ComName+"已在左边打开");
}
return;
}
Hand[Index].hCom=CreateFile(Hand[Index].cbxComName->Text.c_str(),
GENERIC_READ|GENERIC_WRITE,
NULL,
NULL,
OPEN_EXISTING,
NULL,
INVALID_HANDLE_VALUE);
if(Hand[Index].hCom==INVALID_HANDLE_VALUE)
{
ShowMessage(ComName+"打开失败!
");
Hand[Index].hCom=NULL;
return;
}
Hand[Index].ComNum=ComNum;
ClrOption(Index);
COMMTIMEOUTSCommTimeOuts;
//GetCommTimeouts(Hand[Index].hCom,&CommTimeOuts);//读超时
CommTimeOuts.ReadIntervalTimeout=100;
CommTimeOuts.ReadTotalTimeoutMultiplier=1;
CommTimeOuts.ReadTotalTimeoutConstant=100;/*读数据总超时常量*/
CommTimeOuts.WriteTotalTimeoutMultiplier=1;//写超时
CommTimeOuts.WriteTotalTimeoutCo