#pragma once
#include "Com.h"
class CComDlgDlg : public CDialog
{
// 构造
public:
CComDlgDlg(CWnd* pParent = NULL); // 标准构造函数
// 对话框数据
enum { IDD = IDD_COMDLG_DIALOG };
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持
// 实现
protected:
HICON m_hIcon;
static void RecComData(BYTE *pdata, DWORD len);
static HWND gHwndRec;
static char *pRecStr;
CCom *m_com;
// 生成的消息映射函数
virtual BOOL OnInitDialog();
afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
afx_msg void OnPaint();
afx_msg HCURSOR OnQueryDragIcon();
DECLARE_MESSAGE_MAP()
public:
afx_msg void OnBnClickedButton1();
};
//初始化串口
HWND CComDlgDlg::gHwndRec = NULL;
char* CComDlgDlg::pRecStr = NULL;
BOOL CComDlgDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// 将“关于...”菜单项添加到系统菜单中。
// IDM_ABOUTBOX 必须在系统命令范围内。
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
CString strAboutMenu;
strAboutMenu.LoadString(IDS_ABOUTBOX);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}
// 设置此对话框的图标。当应用程序主窗口不是对话框时,框架将自动
// 执行此操作
SetIcon(m_hIcon, TRUE); // 设置大图标
SetIcon(m_hIcon, FALSE); // 设置小图标
// TODO: 在此添加额外的初始化代码
gHwndRec = m_hWnd;
m_com = new CCom();
m_com->OpenCom("COM5", 115200, RecComData);
pRecStr = new char[32768];
return TRUE; // 除非将焦点设置到控件,否则返回 TRUE
}
//接收数据,在textbox里面显示
void CComDlgDlg::RecComData(BYTE *pdata, DWORD len)
{
char *pTmp = pRecStr;
int i, cnt,unit;
cnt = ::GetDlgItemText(gHwndRec, IDC_EDIT_REC, (LPSTR)pRecStr, 32768);
pTmp += cnt;
do{
unit = sprintf(pTmp, "%02X ", *pdata++);
cnt += unit;
if (cnt >= 32768)
{
memset(pRecStr, 0, 32768);
pTmp = pRecStr;
cnt = 0;
}else pTmp += unit;
if (cnt % 50 == 48)
{
unit = sprintf(pTmp, "\r\n");
cnt += unit;
if (cnt >= 32768)
{
memset(pRecStr, 0, 32768);
pTmp = pRecStr;
cnt = 0;
}
else pTmp += unit;
}
} while (--len);
::SetDlgItemText(gHwndRec, IDC_EDIT_REC, (LPSTR)pRecStr);
}
//发送数据
void CComDlgDlg::OnBnClickedButton1()
{
// TODO: Add your control notification handler code here
int len;
BYTE str[1024];
len=GetDlgItemText(IDC_EDIT_SEND, (char*)str, 1024);
m_com->SendData(str, len);
}
//windows下面串口类,
// Com.cpp: implementation of the CCom class.
//
//
#include "stdafx.h"
#include "windows.h"
#include "string.h"
#include "com.h"
#pragma warning(disable:4996)
//
// Construction/Destruction
//
CCom::CCom()
{
//h_Semaphore=CreateSemaphore(NULL,1,1,NULL);
}
CCom::~CCom()
{
CloseCom();
}
DWORD WINAPI CCom::ReadThread(LPVOID lpParam)
{
BYTE *pReadData=NULL;
DWORD dwRead=0; //,dwErr;
CCom *pCom=(CCom*)lpParam;
BOOL ReadState;
pCom->m_running=TRUE;
pReadData=new BYTE[256];
while(pCom->m_running==TRUE)
{
//系统读出数据
ReadState=ReadFile(pCom->m_hcom,pReadData,256,&dwRead,&pCom->m_osReader);
if(!ReadState)
{
if(GetLastError()==ERROR_IO_PENDING)
{
//等待串口接收结果
GetOverlappedResult(pCom->m_hcom,&pCom->m_osReader,&dwRead,TRUE);
ReadState=TRUE;
}
}
if(ReadState && dwRead)
{
if(pCom->fnc!=NULL)
pCom->fnc(pReadData,dwRead);
}
else Sleep(1);
}
delete pReadData;
return 1;
}
VOID CCom::CloseCom()
{
if(m_running==TRUE)
{
m_running=FALSE;
Sleep(5);
CloseHandle(m_osReader.hEvent);
CloseHandle(m_osWriter.hEvent);
CloseHandle(m_hcom);
}
}
DWORD CCom::SendData(const BYTE *src,DWORD len)
{
DWORD dwWrite;
BOOL bResult;
if(m_running==FALSE) return len;
do{
m_osWriter.Offset=0;
m_osWriter.OffsetHigh=0;
dwWrite=0;
bResult=WriteFile(m_hcom,src,len,&dwWrite,&m_osWriter);
if(!bResult)
{
if(GetLastError()==ERROR_IO_PENDING)
{
GetOverlappedResult(m_hcom,&m_osWriter,&dwWrite,TRUE); //等待异步写完成
bResult=TRUE;
}
}
len-=dwWrite;
src+=dwWrite;
}while(len && bResult==TRUE);
return len;
}
BOOL CCom::OpenCom(LPCTSTR lpName, DWORD boud,VFNC recdeal)
{
TCHAR portName[128];
BOOL UsbMode=FALSE;
portName[0]=0;
strcat(portName,lpName);
if(strlen(portName)==5)
{
TCHAR tmp[128]="\\\\.\\";
strcat(tmp,portName);
strcpy(portName,tmp);
}
m_hcom=CreateFile(portName, GENERIC_READ | GENERIC_WRITE, 0, NULL , OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
if (m_hcom == INVALID_HANDLE_VALUE)
{
return FALSE;
}
else
{
DCB wdcb = {0};
GetCommState(m_hcom, &wdcb);
wdcb.BaudRate = boud;
wdcb.ByteSize = 8;
//设置串口参数
SetCommState(m_hcom, &wdcb);
//设置串口超时参数
COMMTIMEOUTS toUsb =// 串口超时控制参数
{
1, // 读字符间隔超时时间
1, // 读操作时每字符的时间
100, // 基本的(额外的)读超时时间
0, // 写操作时每字符的时间
0 // 基本的(额外的)写超时时间
};
COMMTIMEOUTS toNormal =// 串口超时控制参数
{
50, // 读字符间隔超时时间
1, // 读操作时每字符的时间
50, // 基本的(额外的)读超时时间
2, // 写操作时每字符的时间
100 // 基本的(额外的)写超时时间
};
if(UsbMode==TRUE) SetCommTimeouts(m_hcom, &toUsb);
else SetCommTimeouts(m_hcom, &toNormal);
//设置串口缓冲队列
SetupComm(m_hcom, 1024, 1024);
//清空并结束串口当前动作
PurgeComm(m_hcom, PURGE_TXCLEAR | PURGE_RXCLEAR);
fnc=recdeal;
FillMemory(&m_osReader, sizeof(OVERLAPPED),0);
FillMemory(&m_osWriter, sizeof(OVERLAPPED),0);
m_osReader.hEvent = CreateEvent(NULL,TRUE,FALSE,NULL);
m_osWriter.hEvent = CreateEvent(NULL,TRUE,FALSE,NULL);
HANDLE hThread =CreateThread(NULL, 0, ReadThread, this, 0, &dwThreadID);
CloseHandle(hThread);
}
return TRUE;
}
软件运行截图