CE 操作串口
WinCE里面都是通过标准的系统API对串口进行操作的,但是串口不同于其它文件,它是是独占式地操作的。
下面是一个操作的串口类:
#pragma once
typedef void (*LPDataArriveProc)(char *data,int length,DWORD userdata); // 定义数据处理回调函数(指针类型)
class CPSerialPort
{
public:
CPSerialPort();
virtual ~CPSerialPort();
//打开串口
BOOL OpenPort(LPCTSTR Port,);
//关闭串口
BOOL ClosePort();
//激活与关闭持续接收
BOOL Activate();
BOOL Deactivate();
BOOL IsActive();
//接收数据线程函数
static DWORD WINAPI ReadPortThread(LPVOID lpParameter);
DWORD ReadPort(char *data,int length); //读取一定长度的数据
DWORD WritePort(unsigned char *data,int length); //发送数据
DWORD WriteFileToPort(LPCTSTR FileName); //发送文件
private:
HANDLE m_hComm; //串口设备handle
HANDLE m_hReadThread; //读串口线程handle
BOOL m_bReceiving; //是否持续接收
int m_nBufferSize; //缓冲大小
char *Buffer; //缓冲区
LPDataArriveProc m_lpDataArriveProc; //回调函数,用于处理数据
DWORD m_dwUserData;
//串口设置以及超时参数
DCB dcb;
COMMTIMEOUTS CommTimeOuts;
protected:
void ReceiveChar(CPSerialPort *port,COMSTAT comstat);
};
#include "StdAfx.h"
#include "PSerialPort.h"
CPSerialPort::CPSerialPort()
{
m_hComm = INVALID_HANDLE_VALUE;
m_hReadThread = NULL;
m_bReceiving = FALSE;
m_nBufferSize = ; //缓冲大小
}
CPSerialPort::~CPSerialPort()
{
ClosePort();
}
//串口接收线程,主要是中断处理,调用另外一个专门的接收函数实现
DWORD WINAPI CPSerialPort::ReadPortThread(LPVOID lpParameter) //参数指向串口类
{
DWORD evtMask; //事件驱动变量WaitCommEvent()用
DWORD dwReadErrrors; //保存出错状态用
COMSTAT cmState;
CPSerialPort* m_pSerial;
m_pSerial =(CPSerialPort*)lpParameter;
if(m_pSerial->m_hComm!=INVALID_HANDLE_VALUE)
{
PurgeComm(m_pSerial->m_hComm, PURGE_RXCLEAR | PURGE_TXCLEAR ); //清空串口驱动的发送和接收区,此函数一般用在第一次打开串口或长时间未用串口时
SetCommMask (m_pSerial->m_hComm, EV_RXCHAR); //设置响应事件//EV_RXCHAR:输入缓冲区中已收到数据
}
while((m_pSerial->m_hComm!=INVALID_HANDLE_VALUE)&&(m_pSerial->m_bReceiving))
{ if(WaitCommEvent(m_pSerial->m_hComm,&evtMask,NULL)) //等接收信号
{ //有数据
ClearCommError(m_pSerial->m_hComm,&dwReadErrrors,&cmState); //清错误并查询,保证下一次的waitcommEvent();
m_pSerial->ReceiveChar(m_pSerial,cmState); //读数据
}
}
;
}
//读并保存串口数据
void CPSerialPort::ReceiveChar(CPSerialPort *port, COMSTAT comstat)
{
BOOL bResult = TRUE;
DWORD dwError = ;
DWORD dwWantRead;
BOOL fReadState;
DWORD dwLength;
char* buf=new char[port->m_nBufferSize]; //生成缓存区
if(!buf) //分配内存失败,返回
return;
for(;;) //读数
{
bResult=ClearCommError(port->m_hComm,&dwError,&comstat);
|| !port->m_bReceiving) //无数据或按退出则退出程序
{
break; //返回
}
//确定读数长度
dwWantRead=comstat.cbInQue;
if(dwWantRead> (DWORD)(port->m_nBufferSize))
{
dwWantRead=port->m_nBufferSize;
}
fReadState=ReadFile(port->m_hComm,buf,dwWantRead,&dwLength,NULL);
if(!fReadState)
{
//AfxMessageBox(_T("无法从串口读取数据!"));
}
else
{
)
{
// 回送数据
if(port->m_lpDataArriveProc!=NULL) // 如果处理数据回调函数不为空
{
port->m_lpDataArriveProc(buf,dwLength,port->m_dwUserData); // 处理数据
}
}
}
}
// 释放内存
if (buf)
{
delete[] buf;
buf = NULL;
}
}
//打开串口
BOOL CPSerialPort::OpenPort(LPCTSTR Port,int BaudRate,int DataBits,int StopBits,int Parity,LPDataArriveProc proc,DWORD userdata)
{
m_lpDataArriveProc=proc; //接收线程用的回调函数
m_dwUserData=userdata; //用户参数(指向调用OpenPort()的窗口
if(m_hComm==INVALID_HANDLE_VALUE)
{
m_hComm=CreateFile(Port,GENERIC_READ|GENERIC_WRITE,,,OPEN_EXISTING,,); //打开串口
if(m_hComm==INVALID_HANDLE_VALUE )
{
AfxMessageBox(_T("无法打开端口!请检查是否已被占用。"));
return FALSE;
}
GetCommState(m_hComm,&dcb);
dcb.BaudRate=BaudRate;
dcb.ByteSize=DataBits;
dcb.Parity=Parity;
dcb.StopBits=StopBits;
dcb.fParity=FALSE;
dcb.fBinary=TRUE;
dcb.fDtrControl=;
dcb.fRtsControl=;
dcb.fOutX=dcb.fInX=dcb.fTXContinueOnXoff=;
// 设置状态参数
SetCommMask(m_hComm,EV_RXCHAR); //设置"接收到一个字符"事件
SetupComm(m_hComm,,); //设置接收,发送缓存大小为16384byte
if(!SetCommState(m_hComm,&dcb)) //将设置的参数写入串口
{
AfxMessageBox(_T("无法按当前参数配置端口,请检查参数!"));
PurgeComm(m_hComm,PURGE_TXCLEAR|PURGE_RXCLEAR); //清除串口发送接收
ClosePort(); //关闭
return FALSE;
}
//设置超时参数
GetCommTimeouts(m_hComm,&CommTimeOuts);
CommTimeOuts.ReadIntervalTimeout=; //查询方式读数时的时间间隔
CommTimeOuts.ReadTotalTimeoutMultiplier=; //读一个字节时的时间超时上限
CommTimeOuts.ReadTotalTimeoutConstant=; //总超时量
CommTimeOuts.WriteTotalTimeoutMultiplier=;
CommTimeOuts.WriteTotalTimeoutConstant=;
if(!SetCommTimeouts(m_hComm,&CommTimeOuts)) //写入串口
{ AfxMessageBox(_T("无法设置超时参数!"));
PurgeComm(m_hComm,PURGE_TXCLEAR|PURGE_RXCLEAR); //清除串口发送接收区
ClosePort();
return FALSE;
}
PurgeComm(m_hComm,PURGE_TXCLEAR|PURGE_RXCLEAR); //清除串口发送接收区
return TRUE;
}
return FALSE;
}
BOOL CPSerialPort::ClosePort()
{
Deactivate();
if(m_hComm!=INVALID_HANDLE_VALUE)
{ SetCommMask(m_hComm,); //清事件
PurgeComm(m_hComm,PURGE_TXCLEAR|PURGE_RXCLEAR); //清除串口发送接收区
CloseHandle(m_hComm);
m_hComm=INVALID_HANDLE_VALUE;
return TRUE;
}
return TRUE;
}
BOOL CPSerialPort::Activate()
{
if(m_hComm==INVALID_HANDLE_VALUE)
{ return FALSE;
}
if(!m_bReceiving)
{ //开始接收线程
PurgeComm(m_hComm,PURGE_TXCLEAR|PURGE_RXCLEAR);
m_bReceiving=TRUE;
m_hReadThread=CreateThread(NULL,,ReadPortThread,,NULL);
}
if(m_hReadThread!=NULL)
{
return TRUE;
}
else
{
m_bReceiving=FALSE;
return FALSE;
}
//return FALSE;
}
BOOL CPSerialPort::Deactivate()
{
if(m_hComm==INVALID_HANDLE_VALUE)
{ return FALSE;
}
//停止接收线程
if(m_bReceiving)
{
m_bReceiving=FALSE; //关串口读数线程
SetCommMask(m_hComm,); //退出等待线程
WaitForSingleObject(m_hReadThread,);
CloseHandle(m_hReadThread);
m_hReadThread=NULL;
return TRUE;
}
return FALSE;
}
BOOL CPSerialPort::IsActive()
{
return m_bReceiving;
}
DWORD CPSerialPort::WritePort(unsigned char *data,int length)
{
DWORD fg;
COMSTAT cmstat;
if(m_hComm==INVALID_HANDLE_VALUE)
{
;
}
ClearCommError(m_hComm,&fg,&cmstat); // 清错并查询状态
BOOL fWriteState;
DWORD dwBytesWritten=;
fWriteState=WriteFile(m_hComm,data,length*sizeof(char),&dwBytesWritten,NULL);
return dwBytesWritten;
}
DWORD CPSerialPort::ReadPort(char *data,int length)
{
BOOL fReadState;
DWORD dwLength,dwBytesRead;
int TimeOutCount;
dwBytesRead=;
TimeOutCount=;
while(m_hComm!=INVALID_HANDLE_VALUE)
{
char* buf=new char[length];
fReadState=ReadFile(m_hComm,data,length,&dwLength,NULL);
if(!fReadState)
{
break;
}
else
{
dwBytesRead+=dwLength;
data+=dwLength;
}
if(dwBytesRead==(DWORD)length)
{
break;
}
)
{
TimeOutCount=;
}
else
{
TimeOutCount++;
Sleep();
}
)
{
break;
}
}
return dwBytesRead;
}
DWORD CPSerialPort::WriteFileToPort(LPCTSTR FileName)
{
if(m_hComm==INVALID_HANDLE_VALUE)
{ ;
}
CFile cf;
BOOL fWriteState;
DWORD dwBytesWritten;
DWORD dwCharToWrite;
dwCharToWrite=;
if(!cf.Open(FileName,CFile::modeRead))
{
//AfxMessageBox(_T("无法打开Hex文件!"));
;
}
dwCharToWrite=(DWORD)cf.GetLength();
cf.Seek(,CFile::begin);
dwBytesWritten=;
)
{
char* buf=new char[dwCharToWrite];
cf.Read(buf,dwCharToWrite);
fWriteState=WriteFile(m_hComm,buf,dwCharToWrite*sizeof(char),&dwBytesWritten,NULL);
if(!fWriteState)
{
//AfxMessageBox(_T("无法向端口写入数据!"));
}
if(buf)
{
delete[] buf;
buf = NULL;
}
}
cf.Close();
return dwBytesWritten;
}
CE 操作串口的更多相关文章
- C#操作串口总结
Technorati 标签: C#,SerialPort,ReadTo,ReadTimeout 最近几天一直在调一个要长时间连续不断的操作串口,并且是多线程运行,不允许中断的服务.后来服 ...
- MSComm控件与Win32 API操作串口有何区别?
MSComm控件与Win32 API操作串口有何区别? [问题点数:50分,结帖人shell_shell] 收藏帖子 回复 我是一个小兵,在战场上拼命! 结帖率 83.33% 我以前用MSCo ...
- android开发(37) android使用android_serialport_api 操作串口,解决权限问题
最近有个项目,要使用android设备操作串口的 斑马GK888T打印机,使用打印机打印二维码. 硬件设备连接方式: 安卓设备 通过 串口RS232 连接 斑马打印机的串口 那么就要解决:使用安卓设备 ...
- 通过shell操作串口
1. 通过stty工具设置串口参数,例如 stty -F /dev/ttyUSB0 raw speed 9600 -echo min 0 time 10 上例设置了ttyUSB0设备的数据流格式为ra ...
- Pyserial操作串口
pySerial 介绍 封装了串口通讯模块,支持Linux.Windows.BSD(可能支持所有支持POSIX的操作系统),支持Jython(Java)和IconPython(.NET and Mon ...
- python操作串口
import serial test = serial.Serial("COM1",115200)#这里就已经打开了串口 print(test.portstr) test.writ ...
- C# 如何操作串口
1.首先要引用 System.IO.Ports using System; using System.Collections.Generic; using System.ComponentModel ...
- qt 操作串口 QSerialPort
准备工作 *.pro中加入 QT += serialport 初始化 void MainWindow::initPort() { //读取串口信息 foreach (const QSerialPort ...
- qt 操作串口
第三方类下载 https://sourceforge.net/projects/qextserialport/files/ 目录介绍 搭建工程 拷贝qextserialbase.cpp.qextser ...
随机推荐
- hihoCoder#1014
刚开始学习C语言,准备在做hiho的题目的过程中来学习,在此进行记录,如果代码中有错误或者不当的地方还请指正. 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi和小 ...
- [网络技术][转]网卡的offload概念
网络数据包分析 网卡Offload 对于网络安全来说,网络传输数据包的捕获和分析是个基础工作,绿盟科技研究员在日常工作中,经常会捕获到一些大小远大于MTU值的数据包,经过分析这些大包的特性,发现和网卡 ...
- hightchart属性(更新中...)
legend:{ layout: 'vertical', //legend中内容垂直放置 align: 'right', //放在图表右边 verticalAlign: 'middle', // ...
- git clone错误
git clone错误 Initialized empty Git repository in ***/.git/ error: The requested URL returned error: 4 ...
- Java网络编程及安全
一.实验内容: 1.运行教材上TCP代码,结对进行,一人服务器,一人客户端: 2.利用加解密代码包,编译运行代码,一人加密,一人解密: 3.集成代码,一人加密后通过TCP发送: 注:加密使用AES或者 ...
- (l老陈-小石头)典型用户、用户故事、用例图
一.典型用户 老陈 小石头 二.用户故事 老陈:作为一个家长,我希望能利用软件在电脑上储存一些数学题目,以便在繁忙的工作中也能帮助到孩子提高数学. 小石头:作为一个小学二年级的小学生,我希望能利用软件 ...
- WPF项目中所遇到的一些问题集
1. 没有Timer控件 解决方案: 第一步:申明一个DispatcherTimer 类的变量, private DispatcherTimer timer; //定时控件 第二步:初始化这个类 ti ...
- jQuery从无知到无所不知
说明: 本文以读书笔记的方式整理jQuery的重要知识点,言简意赅,一语中的,删繁就简,引人入胜. 本文先对jQuery强大的功能作一系统的介绍,再详细整理jQuery的选择器.过滤器.DOM操作.事 ...
- Java随笔四---Java异常
1.throw语句:Java编译器在执行throw语句时,会立即停止常规的程序执行,开始寻找能够捕获或处理异常的异常处理程序: 2.异常处理程序使用try/catch/finally编写. 3.如果当 ...
- peersim中BT网络核心代码解析
首先大概介绍BT网络运行的整体流程: 开始阶段,一个节点加入到网络中,并向tracker节点发送信息,tracker返回若干个邻居的列表 得到列表后,向每个邻居发送bitfiled信息,来获取他们的文 ...