求一用API进行串口读写操作的程序(CreateFile,ReadFile,WriteFile函数的应用)
大家好,能满足小弟的这点儿要求吗?我的邮箱是zbcgsx@163.net,希望能有一点儿注释!谢谢,我真的很急呐! 问题点数:100、回复次数:4Top
1 楼songhtao(三十年孤独)回复于 2002-05-03 18:49:59 得分 0
建议用MSComm控件,api较麻烦Top
2 楼zbc(修身养息,百战不怠)回复于 2002-05-03 19:43:48 得分 0
不是,现在我最主要的是要学习Api的编写啊Top
3 楼hotxu(hotxu)回复于 2002-05-04 11:20:53 得分 100
头文件:
//---------------------------------------------------------------------------
#ifndef UnitCommH
#define UnitCommH
#define BLOCK_LENGTH 1024
#include "UnitMain.h"
class TCommunication:public TObject
{
public:
HANDLE hCom;
__fastcall TCommunication();
virtual __fastcall ~TCommunication();
bool __fastcall ComInitialization(AnsiString DevicePort,
int BaudRate,int ByteSize, int Parity, int StopBits);
char * __fastcall ReceiveProcess();
BOOL __fastcall WriteCommBlock(LPSTR lpBlock,DWORD nMaxLength);
private:
//接收缓冲区
char Buffer[BLOCK_LENGTH+1];
//接收缓冲区计数器,加1计数器
DWORD BufferOffset;
//分别为读、写重叠数据结构
OVERLAPPED osRead,osWrite;
DWORD __fastcall ReadCommBlock(LPSTR lpBlock,DWORD nMaxLength);
};
//---------------------------------------------------------------------------
#endif
Top
4 楼hotxu(hotxu)回复于 2002-05-04 11:22:05 得分 0
实现文件:
//---------------------------------------------------------------------------
#pragma hdrstop
#include "UnitMain.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
__fastcall TCommunication::TCommunication()
{
}
//---------------------------------------------------------------------------
__fastcall TCommunication::~TCommunication()
{
}
//---------------------------------------------------------------------------
//初始化串行口
bool __fastcall TCommunication::ComInitialization(AnsiString DevicePort,
int BaudRate,int ByteSize, int Parity, int StopBits)
{
//串行通信设备的控制(配置)块数据结构
DCB dcb;
//串行通信设备的超时参数数据结构
COMMTIMEOUTS CommTimeOuts;
//创建串行通信设备句柄
BOOL fSuccess;
hCom = CreateFile(DevicePort.c_str(),
GENERIC_READ | GENERIC_WRITE,
0, //必须以opened w/exclusive-access
NULL, //无安全属性
OPEN_EXISTING, //必须用OPEN_EXISTING
FILE_FLAG_OVERLAPPED, //重叠I/O操作
NULL //对通信设备必须是NULL
);
//创建句柄失败...
if (hCom == INVALID_HANDLE_VALUE) {
MessageBox(NULL,"打开通信设备文件失败!","错误",MB_OK);
return false;
}
// 设置串行口内部输入(接收),输出(发送)缓冲区长度
if(!SetupComm(hCom,BLOCK_LENGTH,BLOCK_LENGTH))
{
MessageBox(NULL,"设置串行口内部输入、输出缓冲区长度操作异常!","错误",MB_OK);
return false;
}
//获取串行口默认控制(配置)块数据结构
fSuccess = GetCommState(hCom, &dcb);
if (!fSuccess) {
MessageBox(NULL,"获取通信设备控制块数据结构操作异常!","错误",MB_OK);
return false;
}
//填充要改变的串行口控制(配置)块数据结构的有关成员,其它不变...
dcb.BaudRate = BaudRate;//波特率,由调用者设置,系函数自变量
dcb.ByteSize = ByteSize;//字长
dcb.Parity = Parity; //奇偶校验
dcb.StopBits = StopBits;//停止位
dcb.fInX = TRUE; //允许输入(接收)Xon/Xoff流量控制
dcb.fOutX = TRUE; //允许输出(发送)Xon/Xoff流量控制
dcb.XonLim = BLOCK_LENGTH/4; //接收时发出Xon时的门限值
dcb.XoffLim = BLOCK_LENGTH/4;//接收时发出Xoff时的门限值
dcb.fRtsControl=RTS_CONTROL_DISABLE;
//用改变后的控制(配置)块数据结构设置串行口
fSuccess = SetCommState(hCom, &dcb);
if (!fSuccess) {
MessageBox(NULL,"设置通信设备控制块数据结构操作异常!","错误",MB_OK);
return false;
}
//获取串行口超时参数
GetCommTimeouts(hCom, &CommTimeOuts);
CommTimeOuts.ReadIntervalTimeout = 0xFFFFFFFF;
CommTimeOuts.WriteTotalTimeoutConstant = 5000;
//用改变后的超时参数的数据结构设置串行口超时参数
SetCommTimeouts(hCom, &CommTimeOuts);
//初始化接收重叠数据结构
memset(&osRead, 0, sizeof(OVERLAPPED));
//初始化发送重叠数据结构
memset(&osWrite, 0, sizeof(OVERLAPPED));
//为接收操作的重叠结构建立信号事件,手工复位方式,初始状态FALSE
osRead.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
//为发送操作的重叠结构建立信号事件,手工复位方式,初始状态FALSE
osWrite.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
//接收缓冲区Buffer(非内部接收缓冲区)计数器清0
BufferOffset=0;
return true;
}
//---------------------------------------------------------------------------
//接收1个或连续若干个字符,接收字符串至接收缓冲区Buffer
char * __fastcall TCommunication::ReceiveProcess()
{
DWORD nLength;
do
{
if((nLength=ReadCommBlock((LPSTR)(Buffer+BufferOffset),BLOCK_LENGTH))>0)
{
BufferOffset+=nLength;
}
}
while(nLength>0);
if(BufferOffset>0)
{
//收到字符后,将接收缓冲区变换成0结尾的ASCZ码串
*(Buffer+BufferOffset)=0;
BufferOffset=0;
return Buffer;
}
return NULL;
}
//---------------------------------------------------------------------------
//从内部接收缓冲区读取(接收)若干字符
DWORD __fastcall TCommunication::ReadCommBlock(LPSTR lpBlock,DWORD nMaxLength)
{
//串行口状态信息数据结构,可了解内部输入、输出缓冲区中缓存的字节数
COMSTAT ComStat;
BOOL fReadStat;
DWORD dwErrorFlages,dwLength;
//获取串行口状态信息数据结构,获取出错信息并清除出错标志
ClearCommError(hCom,&dwErrorFlages,&ComStat);
//在入口参数指定长度,与串行口内部接收字符数间,取较小者作为将要接收的字符数
dwLength=(((DWORD)nMaxLength<ComStat.cbInQue)?(DWORD)nMaxLength:ComStat.cbInQue);
if(dwLength>0)
{
//以重叠方式接收指定字符,函数立即返回
fReadStat=ReadFile(hCom,lpBlock,dwLength,&dwLength,&osRead);
if(!fReadStat)
{
//属重叠方式操作在后台进行的情况...
if(GetLastError()==ERROR_IO_PENDING)
{
//等待1s,若接收事件处于信号态,说明重叠方式操作完成,超时...
if(WaitForSingleObject(osRead.hEvent,1000)==WAIT_TIMEOUT)
dwLength=0;
}
else dwLength=0;//异常情况
}
}
return dwLength;
}
//---------------------------------------------------------------------------
//发送指定长度的字符串
BOOL __fastcall TCommunication::WriteCommBlock(LPSTR lpBlock,DWORD nMaxLength)
{
BOOL fWriteStat;
DWORD dwBytesWritten;
//写入块长度为0时,立即返回,返回值false
if(nMaxLength==0)return false;
//逐个发送循环
for(DWORD i=0;i<nMaxLength;i++)
{
//向指定串口写入当前字符,因为重叠方式,函数会不等操作完成立即返回
fWriteStat = WriteFile(hCom, lpBlock+i, 1, &dwBytesWritten, &osWrite);
//字符发送重叠操作期间...
if (!fWriteStat && (GetLastError() == ERROR_IO_PENDING))
{
//等待1s期间,字符发送完成(即事件为有信号态)的情况,超时为异常情况
if (WaitForSingleObject(osWrite.hEvent, 1000)==WAIT_TIMEOUT)
return false;
}
}
return TRUE;
}
//---------------------------------------------------------------------------
Top




