#include "resource.h" #include "Main" />
当前位置:文档之家› C语言串口通信助手代码

C语言串口通信助手代码

该程序全部由C写成没有C++ 更没用MFC完全是自娱自乐给需要的人一个参考#include "stdafx.h"#include <windowsx.h>#include "resource.h"#include "MainDlg.h"#include <windows.h>#include <stdio.h>#include <stdlib.h>HANDLE hComm;//用于获取串口打开函数的返回值(句柄或错误值)OVERLAPPED m_ov;COMSTAT comstat;DWORD m_dwCommEvents;TCHAR cRecs[200],cSends[100]; //接收字符串发送字符串char j=0,*cCom; //接收用统计数据大小变量端口选择BOOL WINAPI Main_Proc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam){switch(uMsg){HANDLE_MSG(hWnd, WM_INITDIALOG, Main_OnInitDialog); HANDLE_MSG(hWnd, WM_COMMAND, Main_OnCommand); HANDLE_MSG(hWnd,WM_CLOSE, Main_OnClose);}return FALSE;}/*系统初始化函数*/BOOL Main_OnInitDialog(HWND hwnd, HWND hwndFocus, LPARAM lParam){HWND hwndCombo1=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);void CALLBACK TimerProc (HWND hwnd, UINT message, UINT iTimerID, DWORD dwTime);SetTimer(hwnd,1,1000,TimerProc);return TRUE;}/*监视串口错误时使用的函数*/bool ProcessErrorMessage(char* ErrorText){char *Temp = new char[200];LPVOID lpMsgBuf;FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |FORMAT_MESSAGE_FROM_SYSTEM,NULL,GetLastError(),MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language(LPTSTR) &lpMsgBuf,NULL);sprintf(Temp, "WARNING: %s Failed with the following error:\n%s\nPort: %d\n", (char*)ErrorText, lpMsgBuf, "com2"); MessageBox(NULL, Temp, "Application Error", MB_ICONSTOP); LocalFree(lpMsgBuf);delete[] Temp;return true;}bool openport(char *portname)//打开串口{hComm = CreateFile(portname, //串口号“com1”“com2” 调用方法:bool open; open=openport("com2");GENERIC_READ | GENERIC_WRITE, //允许读写0, //通讯设备必须以独占方式打开0, //无安全属性OPEN_EXISTING, //通讯设备已存在FILE_FLAG_OVERLAPPED, //异步I/O0); //通讯设备不能用模板打开if (hComm == INVALID_HANDLE_VALUE) //如果被占用或是没有打开时返回的是这个错误代码CloseHandle(hComm);return FALSE;}elsereturn true;}bool setupdcb(int rate_arg)//设置port的属性{DCB dcb;int rate= rate_arg;memset(&dcb,0,sizeof(dcb));if(!GetCommState(hComm,&dcb))//获取当前DCB配置return FALSE;// set DCB to configure the serial portdcb.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;// set DCBif(!SetCommState(hComm,&dcb))return false;elsereturn true;}/*串口读取相关时间设置*/bool setuptimeout(DWORD ReadInterval,DWORD ReadTotalMultiplier,DWORD ReadTotalconstant,DWORD WriteTotalMultiplier,DWORD WriteTotalconstant){COMMTIMEOUTS timeouts;timeouts.ReadIntervalTimeout=ReadInterval; //读取两个字节间隔最大值mS如超过立即返回不再读取timeouts.ReadTotalTimeoutConstant=ReadTotalconstant; //如果同下面一个都为0 则无论是否读到数据都返回// 可以毫秒为单位指定一个乘数,该乘数用来计算读操作的总限时时间timeouts.ReadTotalTimeoutMultiplier=ReadTotalMultiplier; // 以毫秒为单位指定一个常数,用于计算读操作的总限时时间0表示不限时timeouts.WriteTotalTimeoutConstant=WriteTotalconstant;// 写操作延时同上timeouts.WriteTotalTimeoutMultiplier=WriteTotalMultiplier;if(!SetCommTimeouts(hComm, &timeouts))return false;elsereturn true;}int Clearn() //清除buff中的内容并返回buff中现有数据量的大小并读取错误原因{DWORD dwError = 0;DWORD BytesRead = 0;ClearCommError(hComm, &dwError, &comstat);return comstat.cbInQue; //返回buff中数据量}/*串口数据接收读取函数*/void ReceiveChar(){BOOL bRead = TRUE;BOOL bResult = TRUE;DWORD dwError = 0;DWORD BytesRead = 0;char i=0,n;char RXBuff;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, // Handle to COMM port &RXBuff, // RX Buffer Pointer1, // Read one byte&BytesRead, // Stores number of bytes read&m_ov); // pointer to the m_ov structure// printf("%c",RXBuff);cRecs[j++]=(char)RXBuff;if (!bResult){switch (dwError = GetLastError()){case ERROR_IO_PENDING:{bRead = FALSE;break;}default: break;}elsebRead = TRUE; // close if (bRead)if (!bRead){bRead = TRUE;bResult = GetOverlappedResult(hComm, // Handle to COMM port&m_ov, // Overlapped structure&BytesRead, // Stores number of bytes readTRUE); // Wait flag}}}bool WriteChar(char* m_szWriteBuffer,DWORD m_nToSend) //写字符的函数{BOOL bWrite = TRUE;BOOL bResult = TRUE;DWORD BytesSent = 0;HANDLE m_hWriteEvent;ResetEvent(m_hWriteEvent);if (bWrite){m_ov.Offset = 0;m_ov.OffsetHigh = 0;// Clear bufferbResult = WriteFile(hComm, // Handle to COMM Portm_szWriteBuffer, // Pointer to message buffer in calling finction m_nToSend, // Length of message to send&BytesSent, // Where to store the number of bytes sent&m_ov ); // Overlapped structureif (!bResult){DWORD dwError = GetLastError();switch (dwError){case ERROR_IO_PENDING:{// continue to GetOverlappedResults()BytesSent = 0;bWrite = FALSE;break;}default:// all other error codesbreak;}}} // end if(bWrite)if (!bWrite){bWrite = TRUE;bResult = GetOverlappedResult(hComm, // Handle to COMM port &m_ov, // Overlapped structure&BytesSent, // Stores number of bytes sentTRUE); // Wait flag// deal with the error codeif (!bResult){printf("GetOverlappedResults() in WriteFile()");}} // end if (!bWrite)// Verify that the data size send equals what we tried to send if (BytesSent != m_nToSend){printf("WARNING: WriteFile() error.. Bytes Sent: %d; Message Length: %d\n", BytesSent, strlen((char*)m_szWriteBuffer));}return true;}/*window时间函数回调*/void CALLBACK TimerProc (HWND hwnd, UINT message, UINT iTimerID, DWORD dwTime){SYSTEMTIME time; //定义机构体变量timeGetLocalTime(&time); //取系统时间以指针方式TCHAR strTime[256]; //程序只有一个作用wsprintf(strTime,"%04d-%02d-%02d %02d:%02d:%02d",time.wYear, //就是读取系统时间time.wMonth,time.wDay,time.wHour,time.wMinute,time.wSecond);//然后写进strTimeSetDlgItemText(hwnd,IDC_TIME,strTime); //这个字符串}void Main_OnCommand(HWND hwnd, int id, HWND hwndCtl, UINT codeNotify){switch(id){case IDC_SEND:{GetDlgItemText (hwnd,IDC_EDIT2,cSends,sizeof(cSends)); unsigned n=sizeof(cSends); //n是通知串口将发送字节的长度char send[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;/*case IDC_RECEIVE: //暂时未用采用直接显示的方式{}break;*/case IDC_CHECK:{int ctr;HWND hwndCombo1=GetDlgItem(hwnd,IDC_COMBO1);ctr = ComboBox_GetCurSel(hwndCombo1);switch (ctr){case 0:cCom="com1";break;case 1:cCom="com2";break;case 2:cCom="com3";break;case 3:cCom="com4";break;case 4:cCom="com5";break;default: cCom="com1";break;}if (openport(cCom)){ SetDlgItemText(hwnd,IDC_EDIT3,"OK !");MessageBox(hwnd,"串口打开成功!","",0); }elseSetDlgItemText(hwnd,IDC_EDIT3,"FAIL");if(setupdcb(9600)&&setuptimeout(1024,0,0,20,1000)) //初始化串口属性波特率9600SetDlgItemText(hwnd,IDC_EDIT4,"串口属性设置成功");elseSetDlgItemText(hwnd,IDC_EDIT4,"串口初始化失败!"); PurgeComm(hComm, PURGE_RXCLEAR | PURGE_TXCLEAR | PURGE_RXABORT | PURGE_TXABORT);}default:break;}}void Main_OnClose(HWND hwnd) {EndDialog(hwnd, 0);}。

相关主题