3758
- 收藏
- 点赞
- 分享
- 举报
windows ce下串口操作代码
[code]// CeSerial.h: interface for the CCeSerial class.
//
//////////////////////////////////////////////////////////////////////
#if !defined(AFX_CESERIAL_H__8639DC23_8413_45AD_A32E_CCD5B6E325F6__INCLUDED_)
#define AFX_CESERIAL_H__8639DC23_8413_45AD_A32E_CCD5B6E325F6__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
class CCeSerial
{
public:
CCeSerial();
virtual ~CCeSerial();
// 打开串口
BOOL OpenPort(LPCTSTR Port, int BaudRate, int DataBits, int StopBits, int Parity,
BOOL bDTRShake, BOOL bRTSShake, DWORD UserParam);
// 串口是否打开
BOOL IsPortOpen();
// 关闭串口
BOOL ClosePort(void);
// 发送数据
void Senddata(BYTE *sendbuf, DWORD length);
// 串口接收数据成功回调函数
typedef void (CALLBACK *ONCOMMRECV)(DWORD UserParam, BYTE *buf, DWORD buflen);
ONCOMMRECV OnCommRecv;
DWORD m_UserParam;
private:
DCB dcb; /* 串口参数结构体 */
HANDLE hRecvThread; /* 接收线程句柄 */
HANDLE m_ExitThreadEvent; /* 串口接收线程退出事件 */
HANDLE m_hComm; /* 串口操作句柄 */
// 串口接收线程
static DWORD CommRecvTread(LPVOID lparam);
};
#endif // !defined(AFX_CESERIAL_H__8639DC23_8413_45AD_A32E_CCD5B6E325F6__INCLUDED_)[/code][code]// CeSerial.cpp: implementation of the CCeSerial class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "CeSerial.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CCeSerial::CCeSerial()
{
m_hComm = INVALID_HANDLE_VALUE; /* 串口操作句柄无效 */
hRecvThread = NULL;
m_ExitThreadEvent = NULL; /* 串口接收线程退出事件无效 */
}
CCeSerial::~CCeSerial()
{
ClosePort();
if (hRecvThread != NULL)
{
CloseHandle(hRecvThread);
SetEvent(m_ExitThreadEvent); /* 通知串口接收线程退出 */
Sleep(200);
CloseHandle(m_ExitThreadEvent); /* 关闭线程退出事件 */
}
}
/*******************************************************************************************
函数名称: CCeSerial::CommRecvTread
描 述: 串口接收线程
输入参数: LPVOID lparam: 线程参数,创建线程时传入
输出参数: 无
返 回: 0: 线程退出, 返回值没特殊含义
********************************************************************************************/
DWORD CCeSerial::CommRecvTread(LPVOID lparam)
{
DWORD dwLength;
BYTE *recvBuf = new BYTE[1024];
CCeSerial *pCeSerial = (CCeSerial *)lparam;
while(TRUE)
{ /* 等待线程退出事件 */
if (WaitForSingleObject(pCeSerial->m_ExitThreadEvent, 0) == WAIT_OBJECT_0)
break;
if (pCeSerial->m_hComm != INVALID_HANDLE_VALUE)
{ /* 从串口读取数据 */
BOOL fReadState = ReadFile(pCeSerial->m_hComm, recvBuf, 1024, &dwLength, NULL);
if(!fReadState)
{
//MessageBox(_T("无法从串口读取数据!"));
}
else
{
if(dwLength != 0) /* 接收成功调用回调函数 */
pCeSerial->OnCommRecv(pCeSerial->m_UserParam, recvBuf, dwLength);
}
}
}
delete[] recvBuf;
return 0;
}
/*******************************************************************************************
函数名称: CCeSerial::OpenPort
描 述: 打开串口
输入参数: LPCTSTR Port: 串口名,如"COM0:","COM1:"
int BaudRate: 波特率
int DataBits: 数据位, 取值为7或8
int StopBits: 停止位
int Parity : 奇偶校验位
输出参数: 无
返 回: FALSE: 失败; TRUE: 成功
********************************************************************************************/
BOOL CCeSerial::OpenPort(LPCTSTR Port, int BaudRate, int DataBits, int StopBits, int Parity,
BOOL bDTRShake, BOOL bRTSShake, DWORD UserParam)
{
COMMTIMEOUTS CommTimeOuts;
// 打开串口
m_hComm = CreateFile(Port, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0);
if(m_hComm == INVALID_HANDLE_VALUE)
{
AfxMessageBox(_T("无法打开端口或端口已打开!请检查是否已被占用."));
return FALSE;
}
GetCommState(m_hComm, &dcb); /* 读取串口的DCB */
dcb.BaudRate = BaudRate;
dcb.ByteSize = DataBits;
dcb.Parity = Parity;
dcb.StopBits = StopBits;
dcb.fParity = FALSE; /* 禁止奇偶校验 */
dcb.fBinary = TRUE;
if (bDTRShake == FALSE)
dcb.fDtrControl = 0; /* 禁止流量控制 */
else
dcb.fDtrControl = DTR_CONTROL_HANDSHAKE;
if (bRTSShake == FALSE)
dcb.fRtsControl = 0;
else
dcb.fRtsControl = RTS_CONTROL_HANDSHAKE;
dcb.fOutX = 0;
dcb.fInX = 0;
dcb.fTXContinueOnXoff = 0;
//设置状态参数
SetCommMask(m_hComm, EV_RXCHAR); /* 串口事件:接收到一个字符 */
SetupComm(m_hComm, 16384, 16384); /* 设置接收与发送的缓冲区大小 */
if(!SetCommState(m_hComm, &dcb)) /* 设置串口的DCB */
{
AfxMessageBox(_T("无法按当前参数配置端口,请检查参数!"));
ClosePort();
return FALSE;
}
//设置超时参数
GetCommTimeouts(m_hComm, &CommTimeOuts);
CommTimeOuts.ReadIntervalTimeout = 100; /* 接收字符间最大时间间隔 */
CommTimeOuts.ReadTotalTimeoutMultiplier = 1;
CommTimeOuts.ReadTotalTimeoutConstant = 100; /* 读数据总超时常量 */
CommTimeOuts.WriteTotalTimeoutMultiplier = 0;
CommTimeOuts.WriteTotalTimeoutConstant = 0;
if(!SetCommTimeouts(m_hComm, &CommTimeOuts))
{
AfxMessageBox(_T("无法设置超时参数!"));
ClosePort();
return FALSE;
}
PurgeComm(m_hComm, PURGE_TXCLEAR | PURGE_RXCLEAR); /* 清除收/发缓冲区 */
m_UserParam = UserParam; /* 传递用户参数 */
// 创建线程及句柄
DWORD IDThread;
/* 创建串口接收线程退出事件*/
m_ExitThreadEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
// 创建串口接收线程
hRecvThread = CreateThread(0, 0, CommRecvTread, this, 0, &IDThread);
if (hRecvThread == NULL)
{
ClosePort();
AfxMessageBox(_T("创建接收线程失败!"));
return FALSE;
}
return TRUE;
}
BOOL CCeSerial::IsPortOpen(void)
{
if(m_hComm != INVALID_HANDLE_VALUE)
return TRUE;
return FALSE;
}
/*******************************************************************************************
函数名称: CCeSerial::ClosePort
描 述: 关闭串口
输入参数: 无
输出参数: 无
返 回: FALSE: 失败; TRUE: 成功
********************************************************************************************/
BOOL CCeSerial::ClosePort(void)
{
if(m_hComm != INVALID_HANDLE_VALUE)
{
SetCommMask(m_hComm, 0);
PurgeComm(m_hComm, PURGE_TXCLEAR | PURGE_RXCLEAR); /* 清除收/发缓冲 */
CloseHandle(m_hComm); /* 关闭串口操作句柄 */
m_hComm = INVALID_HANDLE_VALUE;
return TRUE;
}
return FALSE;
}
/*******************************************************************************************
函数名称: CCeSerial::OnOpenCom
描 述: "关闭端口" 代码
输入参数: 无
输出参数: 无
返 回: 无
********************************************************************************************/
void CCeSerial::Senddata(BYTE *psendbuf, DWORD length)
{
DWORD dwactlen;
if (m_hComm == INVALID_HANDLE_VALUE)
{
AfxMessageBox(_T("串口未打开!"));
return;
}
WriteFile(m_hComm, psendbuf, length, &dwactlen, NULL); /* 从串口发送数据 */
}[/code]
//
//////////////////////////////////////////////////////////////////////
#if !defined(AFX_CESERIAL_H__8639DC23_8413_45AD_A32E_CCD5B6E325F6__INCLUDED_)
#define AFX_CESERIAL_H__8639DC23_8413_45AD_A32E_CCD5B6E325F6__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
class CCeSerial
{
public:
CCeSerial();
virtual ~CCeSerial();
// 打开串口
BOOL OpenPort(LPCTSTR Port, int BaudRate, int DataBits, int StopBits, int Parity,
BOOL bDTRShake, BOOL bRTSShake, DWORD UserParam);
// 串口是否打开
BOOL IsPortOpen();
// 关闭串口
BOOL ClosePort(void);
// 发送数据
void Senddata(BYTE *sendbuf, DWORD length);
// 串口接收数据成功回调函数
typedef void (CALLBACK *ONCOMMRECV)(DWORD UserParam, BYTE *buf, DWORD buflen);
ONCOMMRECV OnCommRecv;
DWORD m_UserParam;
private:
DCB dcb; /* 串口参数结构体 */
HANDLE hRecvThread; /* 接收线程句柄 */
HANDLE m_ExitThreadEvent; /* 串口接收线程退出事件 */
HANDLE m_hComm; /* 串口操作句柄 */
// 串口接收线程
static DWORD CommRecvTread(LPVOID lparam);
};
#endif // !defined(AFX_CESERIAL_H__8639DC23_8413_45AD_A32E_CCD5B6E325F6__INCLUDED_)[/code][code]// CeSerial.cpp: implementation of the CCeSerial class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "CeSerial.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CCeSerial::CCeSerial()
{
m_hComm = INVALID_HANDLE_VALUE; /* 串口操作句柄无效 */
hRecvThread = NULL;
m_ExitThreadEvent = NULL; /* 串口接收线程退出事件无效 */
}
CCeSerial::~CCeSerial()
{
ClosePort();
if (hRecvThread != NULL)
{
CloseHandle(hRecvThread);
SetEvent(m_ExitThreadEvent); /* 通知串口接收线程退出 */
Sleep(200);
CloseHandle(m_ExitThreadEvent); /* 关闭线程退出事件 */
}
}
/*******************************************************************************************
函数名称: CCeSerial::CommRecvTread
描 述: 串口接收线程
输入参数: LPVOID lparam: 线程参数,创建线程时传入
输出参数: 无
返 回: 0: 线程退出, 返回值没特殊含义
********************************************************************************************/
DWORD CCeSerial::CommRecvTread(LPVOID lparam)
{
DWORD dwLength;
BYTE *recvBuf = new BYTE[1024];
CCeSerial *pCeSerial = (CCeSerial *)lparam;
while(TRUE)
{ /* 等待线程退出事件 */
if (WaitForSingleObject(pCeSerial->m_ExitThreadEvent, 0) == WAIT_OBJECT_0)
break;
if (pCeSerial->m_hComm != INVALID_HANDLE_VALUE)
{ /* 从串口读取数据 */
BOOL fReadState = ReadFile(pCeSerial->m_hComm, recvBuf, 1024, &dwLength, NULL);
if(!fReadState)
{
//MessageBox(_T("无法从串口读取数据!"));
}
else
{
if(dwLength != 0) /* 接收成功调用回调函数 */
pCeSerial->OnCommRecv(pCeSerial->m_UserParam, recvBuf, dwLength);
}
}
}
delete[] recvBuf;
return 0;
}
/*******************************************************************************************
函数名称: CCeSerial::OpenPort
描 述: 打开串口
输入参数: LPCTSTR Port: 串口名,如"COM0:","COM1:"
int BaudRate: 波特率
int DataBits: 数据位, 取值为7或8
int StopBits: 停止位
int Parity : 奇偶校验位
输出参数: 无
返 回: FALSE: 失败; TRUE: 成功
********************************************************************************************/
BOOL CCeSerial::OpenPort(LPCTSTR Port, int BaudRate, int DataBits, int StopBits, int Parity,
BOOL bDTRShake, BOOL bRTSShake, DWORD UserParam)
{
COMMTIMEOUTS CommTimeOuts;
// 打开串口
m_hComm = CreateFile(Port, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0);
if(m_hComm == INVALID_HANDLE_VALUE)
{
AfxMessageBox(_T("无法打开端口或端口已打开!请检查是否已被占用."));
return FALSE;
}
GetCommState(m_hComm, &dcb); /* 读取串口的DCB */
dcb.BaudRate = BaudRate;
dcb.ByteSize = DataBits;
dcb.Parity = Parity;
dcb.StopBits = StopBits;
dcb.fParity = FALSE; /* 禁止奇偶校验 */
dcb.fBinary = TRUE;
if (bDTRShake == FALSE)
dcb.fDtrControl = 0; /* 禁止流量控制 */
else
dcb.fDtrControl = DTR_CONTROL_HANDSHAKE;
if (bRTSShake == FALSE)
dcb.fRtsControl = 0;
else
dcb.fRtsControl = RTS_CONTROL_HANDSHAKE;
dcb.fOutX = 0;
dcb.fInX = 0;
dcb.fTXContinueOnXoff = 0;
//设置状态参数
SetCommMask(m_hComm, EV_RXCHAR); /* 串口事件:接收到一个字符 */
SetupComm(m_hComm, 16384, 16384); /* 设置接收与发送的缓冲区大小 */
if(!SetCommState(m_hComm, &dcb)) /* 设置串口的DCB */
{
AfxMessageBox(_T("无法按当前参数配置端口,请检查参数!"));
ClosePort();
return FALSE;
}
//设置超时参数
GetCommTimeouts(m_hComm, &CommTimeOuts);
CommTimeOuts.ReadIntervalTimeout = 100; /* 接收字符间最大时间间隔 */
CommTimeOuts.ReadTotalTimeoutMultiplier = 1;
CommTimeOuts.ReadTotalTimeoutConstant = 100; /* 读数据总超时常量 */
CommTimeOuts.WriteTotalTimeoutMultiplier = 0;
CommTimeOuts.WriteTotalTimeoutConstant = 0;
if(!SetCommTimeouts(m_hComm, &CommTimeOuts))
{
AfxMessageBox(_T("无法设置超时参数!"));
ClosePort();
return FALSE;
}
PurgeComm(m_hComm, PURGE_TXCLEAR | PURGE_RXCLEAR); /* 清除收/发缓冲区 */
m_UserParam = UserParam; /* 传递用户参数 */
// 创建线程及句柄
DWORD IDThread;
/* 创建串口接收线程退出事件*/
m_ExitThreadEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
// 创建串口接收线程
hRecvThread = CreateThread(0, 0, CommRecvTread, this, 0, &IDThread);
if (hRecvThread == NULL)
{
ClosePort();
AfxMessageBox(_T("创建接收线程失败!"));
return FALSE;
}
return TRUE;
}
BOOL CCeSerial::IsPortOpen(void)
{
if(m_hComm != INVALID_HANDLE_VALUE)
return TRUE;
return FALSE;
}
/*******************************************************************************************
函数名称: CCeSerial::ClosePort
描 述: 关闭串口
输入参数: 无
输出参数: 无
返 回: FALSE: 失败; TRUE: 成功
********************************************************************************************/
BOOL CCeSerial::ClosePort(void)
{
if(m_hComm != INVALID_HANDLE_VALUE)
{
SetCommMask(m_hComm, 0);
PurgeComm(m_hComm, PURGE_TXCLEAR | PURGE_RXCLEAR); /* 清除收/发缓冲 */
CloseHandle(m_hComm); /* 关闭串口操作句柄 */
m_hComm = INVALID_HANDLE_VALUE;
return TRUE;
}
return FALSE;
}
/*******************************************************************************************
函数名称: CCeSerial::OnOpenCom
描 述: "关闭端口" 代码
输入参数: 无
输出参数: 无
返 回: 无
********************************************************************************************/
void CCeSerial::Senddata(BYTE *psendbuf, DWORD length)
{
DWORD dwactlen;
if (m_hComm == INVALID_HANDLE_VALUE)
{
AfxMessageBox(_T("串口未打开!"));
return;
}
WriteFile(m_hComm, psendbuf, length, &dwactlen, NULL); /* 从串口发送数据 */
}[/code]
我来回答
回答0个
时间排序
认可量排序
暂无数据
或将文件直接拖到这里
悬赏:
E币
网盘
* 网盘链接:
* 提取码:
悬赏:
E币
Markdown 语法
- 加粗**内容**
- 斜体*内容*
- 删除线~~内容~~
- 引用> 引用内容
- 代码`代码`
- 代码块```编程语言↵代码```
- 链接[链接标题](url)
- 无序列表- 内容
- 有序列表1. 内容
- 缩进内容
- 图片![alt](url)
相关问答
-
2008-05-27 11:09:53
-
2008-07-18 20:42:04
-
2010-06-01 23:29:28
-
2008-07-12 19:14:12
-
2012-12-05 13:38:25
-
2008-08-18 22:21:13
-
2008-07-24 01:33:17
-
2012-12-05 14:39:10
-
2012-11-25 23:00:03
-
2012-12-05 14:32:53
-
2012-12-05 11:12:01
-
2012-12-05 11:13:14
-
2012-12-05 14:27:39
-
2012-12-05 11:07:55
-
2012-12-05 13:33:42
-
2012-12-05 13:34:26
-
2012-12-04 11:37:28
-
2012-12-04 14:09:01
-
2012-12-04 13:54:12
无更多相似问答 去提问
点击登录
-- 积分
-- E币
提问
—
收益
—
被采纳
—
我要提问
切换马甲
上一页
下一页
悬赏问答
-
5Hi3516CV610 如何使用SD卡升级固件
-
5cat /dev/logmpp 报错 <3>[ vi] [func]:vi_send_frame_node [line]:99 [info]:vi pic queue is full!
-
50如何获取vpss chn的图像修改后发送至vo
-
5FPGA通过Bt1120传YUV422数据过来,vi接收不到数据——3516dv500
-
50SS928 运行PQtools 拼接 推到设备里有一半画面会异常
-
53536AV100的sample_vdec输出到CVBS显示
-
10海思板子mpp怎么在vi阶段改变视频数据尺寸
-
10HI3559AV100 多摄像头同步模式
-
9海思ss928单路摄像头vio中加入opencv处理并显示
-
10EB-RV1126-BC-191板子运行自己编码的程序
举报反馈
举报类型
- 内容涉黄/赌/毒
- 内容侵权/抄袭
- 政治相关
- 涉嫌广告
- 侮辱谩骂
- 其他
详细说明
提醒
你的问题还没有最佳答案,是否结题,结题后将扣除20%的悬赏金
取消
确认
提醒
你的问题还没有最佳答案,是否结题,结题后将根据回答情况扣除相应悬赏金(1回答=1E币)
取消
确认