C语言串口通信助手代码.docx
《C语言串口通信助手代码.docx》由会员分享,可在线阅读,更多相关《C语言串口通信助手代码.docx(13页珍藏版)》请在冰豆网上搜索。
C语言串口通信助手代码
该程序全部由C写成没有C++更没用MFC
完全是自娱自乐给需要的人一个参考
#include"stdafx.h"
#includeVWindowsx.h>
#include"resource.h"
#include"MainDlg.h"
#includeVWindows.h>
#includeVStdio.h>
#includeVStdIib.h>
HANDLEhComm;//用于获取串口打开函数的返回值(句柄或错误值)
OVERLAPPEDm_ov;
COMSTATCOmStat;
DWORDm_dwCommEvents;
TCHARcRecs[200],cSends[100];//接收字符串发送字符串
charj=0,*cCom;//接收用统计数据大小变量端口选择
BOOLWINAPIMain_Proc(HWNDhWnd,UINTuMsg,WPARAMwParam,
LPARAMlParam)
{
switch(uMsg)
{
HANDLE_MSG(hWnd,WM_INITDIALOG,Main_OnInitDialog);
HANDLE_MSG(hWnd,WM_COMMAND,Main_OnCommand);
HANDLE_MSG(hWnd,WM_CLOSE,Main_OnClose);
}
returnFALSE;
}
/*系统初始化函数*/
BOOLMain_OnInitDialog(HWNDhwnd,HWNDhwndFocus,LPARAMlParam)
{
HWNDhwndCombo1=GetDlgItem(hwnd,IDC_COMBO1);
ComboBox_InsertString(hwndCombo1,-1,TEXT("COM1"));
ComboBox_InsertString(hwndCombo1,-1,TEXT("COM2"));
ComboBox_InsertString(hwndCombo1,-1,TEXT("COM3"));
ComboBox_InsertString(hwndCombo1,-1,TEXT("COM4"));
ComboBox_InsertString(hwndCombo1,-1,TEXT("COM5"));ComboBox_SetCurSel(hwndCombo1,0);
voidCALLBACKTimerProc(HWNDhwnd,UINTmessage,UINTiTimerID,DWORDdwTime);
SetTimer(hwnd,1,1000,TimerProc);
returnTRUE;
}
/*监视串口错误时使用的函数*/
boolProcessErrorMessage(char*ErrorText)
{
char*Temp=newchar[200];
LPVOIDlpMsgBuf;
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM,
NULL,
GetLastError(),
MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT),//Defaultlanguage
(LPTSTR)&lpMsgBuf,
0,
NULL
);
sprintf(Temp,"WARNING:
%sFailedwiththefollowingerror:
\n%s\nPort:
%d\n",(char*)ErrorText,lpMsgBuf,"com2");
MessageBox(NULL,Temp,"ApplicationError",MB_ICONSTOP);
LocalFree(lpMsgBuf);
delete[]Temp;
returntrue;
}
boolopenport(char*portname)//打开串口
{
hComm=CreateFile(POrtname,//串口号“coml”“调用方法:
boolOPen;
open=openport("com2");
GENERIC_READ|GENERIC_WRITE,//允许读写
0,//通讯设备必须以独占方式打开
0,//无安全属性
OPEN_EXISTING,//通讯设备已存在
FILE_FLAG_OVERLAPPED,//异步I/O
0);//通讯设备不能用模板打开
if(hComm==INVALID_HANDLE_VALUE)//如果被占用或是没有打开时返
回的是这个错误代码
CloseHandle(hComm);
returnFALSE;
}
else
returntrue;
}
boolsetupdcb(intrate_arg)//设置port的属性
{
DCBdcb;
intrate=rate_arg;
memset(&dcb,0,sizeof(dcb));
if(!
GetCommState(hComm,&dcb))//获取当前DCB配置returnFALSE;
//setDCBtoconfiguretheserialport
dcb.DCBlength=sizeof(dcb);
dcb.BaudRate=rate;
dcb.Parity=NOPARITY;//奇偶校验值0~4分别对应无校验、奇校验、偶校验、校验置位、校验清零
dcb.fParity=0;//为1的话激活奇偶校验检查
dcb.StopBits=ONESTOPBIT;//停止位个数,0~2分别对应1位、1.5位、2
位停止位
dcb.ByteSize=8;//数据位数
dcb.fOutxCtsFlow=0;
dcb.fOutxDsrFlow=0;
dcb.fDtrControl=DTR_CONTROL_DISABLE;dcb.fDsrSensitivity=0;
dcb.fRtsControl=RTS_CONTROL_DISABLE;dcb.fOutX=0;
dcb.fInX=0;
dcb.fErrorChar=0;
dcb.fBinary=1;
dcb.fNull=0;dcb.fAbortOnError=0;
dcb.wReserved=0;
dcb.XonLim=2;
dcb.XoffLim=4;
dcb.XonChar=0x13;
dcb.XoffChar=0x19;dcb.EvtChar=0;
//setDCBif(!
SetCommState(hComm,&dcb))returnfalse;
else
returntrue;
/*串口读取相关时间设置*/
boolsetuptimeout(DWORDReadInterval,DWORD
ReadTotalMultiplier,DWORDReadTotalconstant,DWORD
WriteTotalMultiplier,DWORDWriteTotalconstant)
{
COMMTIMEOUTStimeouts;
timeouts.ReadIntervalTimeout=ReadInterval;//读取两个字节间隔最大值mS如超过立即返回不再读取timeouts.ReadTotalTimeoutConstant=ReadTotalconstant;//如果同下面一个都为0则无论是否读到数据都返回
//可以毫秒为单位指定一个乘数,该乘数用来计算读操作的总限时时间timeouts.ReadTotalTimeoutMultiplier=ReadTotalMultiplier;//以毫秒为单
位指定一个常数,用于计算读操作的总限时时间0表示不限时timeouts.WriteTotalTimeoutConstant=WriteTotalconstant;//写操作延时
同上
timeouts.WriteTotalTimeoutMultiplier=WriteTotalMultiplier;if(!
SetCommTimeouts(hComm,&timeouts))returnfalse;
else
returntrue;
}
intClearn()//清除buff中的内容并返回buff中现有数据量的大小并读取错误
原因
{
DWORDdwError=0;
DWORDBytesRead=0;
ClearCommError(hComm,&dwError,&comstat);returncomstat.cbInQue;//返回buff中数据量}
/*串口数据接收读取函数*/
voidReceiveChar()
{
BOOLbRead=TRUE;
BOOLbResult=TRUE;
DWORDdwError=0;
DWORDBytesRead=0;
chari=0,n;
charRXBuff;
j=0;
while(i-n)
{
n=i;
Sleep(10);
bResult=ClearCommError(hComm,&dwError,&comstat);i=(char)comstat.cbInQue;
for(;i>0;i--)
{
if(bRead)
bResult=ReadFile(hComm,//HandletoCOMMport
&RXBuff,//RXBufferPointer
1,//Readonebyte
&BytesRead,//Storesnumberofbytesread&m_ov);//pointertothem_ovstructure//printf("%c",RXBuff);
cRecs[j++]=(char)RXBuff;
if(!
bResult)
{
switch(dwError=GetLastError())
{
caseERROR_IO_PENDING:
{
bRead=FALSE;
break;
}
default:
break;
else
bRead=TRUE;//closeif(bRead)
if(!
bRead)
{
bRead=TRUE;
bResult=GetOverlappedResult(hComm,//HandletoCOMMport
&m_ov,//Overlappedstructure
&BytesRead,//Storesnumberofbytesread
TRUE);//Waitflag
}
}
写字符的
}
boolWriteChar(char*m_szWriteBuffer,DWORDm_nToSend)//
函数
{
BOOLbWrite=TRUE;
BOOLbResult=TRUE;
DWORDBytesSent=0;
HANDLEm_hWriteEvent;
ResetEvent(m_hWriteEvent);
if(bWrite)
m_ov.Offset=0;
m_ov.OffsetHigh=0;//Clearbuffer
bResult=WriteFile(hComm,//HandletoCOMMPortm_szWriteBuffer,//Pointertomessagebufferincallingfinctionm_nToSend,//Lengthofmessagetosend
&BytesSent,//Wheretostorethenumberofbytessent
&m_ov);//Overlappedstructure
if(!
bResult)
{
DWORDdwError=GetLastError();
switch(dwError)
{
caseERROR_IO_PENDING:
{
//continuetoGetOverlappedResults()
BytesSent=0;
bWrite=FALSE;
break;
}
default:
//allothererrorcodes
break;
}
}
}//endif(bWrite)
if(!
bWrite)
{
bWrite=TRUE;
bResult=GetOverlappedResult(hComm,//HandletoCOMMport
&m_ov,//Overlappedstructure
&BytesSent,//Storesnumberofbytessent
TRUE);//Waitflag
//dealwiththeerrorcode
if(!
bResult)
{
printf("GetOverlappedResults()inWriteFile()");
}
}//endif(!
bWrite)
//Verifythatthedatasizesendequalswhatwetriedtosend
if(BytesSent!
=m_nToSend)
{
printf("WARNING:
WriteFile()error..BytesSent:
%d;Message
Length:
%d\n",BytesSent,strlen((char*)m_szWriteBuffer));
returntrue;
}
/*window时间函数回调*/
voidCALLBACKTimerProc(HWNDhwnd,UINTmessage,UINTiTimerID,
DWORDdwTime)
{
SYSTEMTIMEtime;//定义机构体变量time
GetLocalTime(&time);//取系统时间以指针方式
TCHARstrTime[256];//程序只有一个作用
wsprintf(strTime,"%04d-%02d-%02d%02d:
%02d:
%02d",time.wYear,//就是读取系统时间
然后写
time.wMonth,time.wDay,time.wHour,time.wMinute,time.wSecond);//进strTime
SetDlgItemText(hwnd,IDC_TIME,strTime);//这个字符串
}
voidMain_OnCommand(HWNDhwnd,intid,HWNDhwndCtl,UINTcodeNotify)
{
switch(id)
{
caseIDC_SEND:
GetDlgItemText(hwnd,IDC_EDIT2,cSends,sizeof(cSends));
unsignedn=sizeof(cSends);//n是通知串口将发送字节的长度
charsend[100];
wsprintf(send,"%s",cSends);
WriteChar(send,n-1);
SetCommMask(hComm,EV_RXCHAR);//监视串口是否接收有数据ReceiveChar();//读取串口sbuff中数据cRecs[j]='\0';//将cRecs转为字符串
SetDlgItemText(hwnd,IDC_EDIT1,cRecs);
}break;
/*
caseIDC_RECEIVE:
//暂时未用采用直接显示的方式
{
}
break;*/
caseIDC_CHECK:
{
intctr;
HWNDhwndCombo1=GetDlgItem(hwnd,IDC_COMBO1);
ctr=ComboBox_GetCurSel(hwndCombo1);
switch(ctr)
case0:
cCom="com1";break;
case1:
cCom="com2";break;
case2:
cCom="com3";break;
case3:
cCom="com4";break;
case4:
cCom="com5";break;
default:
cCom="com1";
break;
}
if(openport(cCom))
{SetDlgItemText(hwnd,IDC_EDIT3,"OK!
");
MessageBox(hwnd,"串口打开成功!
","",0);}
else
SetDlgItemText(hwnd,IDC_EDIT3,"FAIL");
if(setupdcb(9600)&&setuptimeout(1024,0,0,20,1000))//初始化串口属性波特率9600
SetDlgItemText(hwnd,IDC_EDIT4,"串口属性设置成功");
else
SetDlgItemText(hwnd,IDC_EDIT4,"串口初始化失败!
");
PurgeComm(hComm,PURGE_RXCLEAR|PURGE_TXCLEAR|PURGE_RXABORT|PURGE_TXABORT);
}
default:
break;
voidMain_OnClose(HWNDhwnd)
{
EndDialog(hwnd,0);
}