关于读入数据到缓的问题

liupeng33 2007-09-19 12:49:58
在BCB6中,如何从串口设备中读数据并存入缓存,然后再统一将这些数据写入文件?
...全文
56 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
i_love_pc 2007-09-19
  • 打赏
  • 举报
回复
1.api函数
2.串口控件
大伟 2007-09-19
  • 打赏
  • 举报
回复

//功能: 发送字符串
//输入: idComm 设备描述字
// szBuf 字符串
// nLen 字符串长度
//返回: CommSend 成功/失败
bool CommSend(HANDLE idComm, unsigned char *lpBuf, DWORD dwToWrite)
{
OVERLAPPED osWrite = {0};
DWORD dwWritten;
DWORD dwRes;
bool fRes;

//为数据传送建立一个OVERLAPPED构造hEvent。在退出之前必须关闭,以避免Handle泄漏

osWrite.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
if (osWrite.hEvent == NULL)
return FALSE; //建立OVERLAPPED Event Handle发生错误

//发布写操作
if (!WriteFile(idComm, lpBuf, dwToWrite, &dwWritten, &osWrite))
{
if (GetLastError() != ERROR_IO_PENDING) {
fRes = FALSE; //写操作失败,但没有延时。报告错误。
} else {
//写操作进行中
dwRes = WaitForSingleObject(osWrite.hEvent, INFINITE); //等待写操作发出信号,不发生超时信号
//dwRes = WaitForSingleObject(osWrite.hEvent, 500); //等待写操作发出信号,不发生超时信号
switch (dwRes) {
case WAIT_OBJECT_0: //写操作发出信号
if (!GetOverlappedResult(idComm, &osWrite, &dwWritten, FALSE))
fRes = FALSE; //写操作错误
else {
if (dwWritten != dwToWrite) {
//写操作超时,可做中断或重试处理。如果重试,发送没有送完的数据;
//如果中断,报告错误
fRes = FALSE;
} else
fRes = TRUE; //成功地完成写操作
}
break;

default:
fRes = FALSE; //可能是Overlapped Event Handle的问题
break;
}
}
} else {
//写操作立即完成
if (dwWritten != dwToWrite) {
//写操作超时,可做中断或重试处理。如果重试,发送没有送完的数据;
//如果中断,报告错误
fRes = FALSE;
} else
fRes = TRUE; //成功地完成写操作

}

CloseHandle(osWrite.hEvent);
return fRes;
}
//---------------------------------------------------------------------------
//功能: 接收字符串
/*输入: idComm 设备描述字
szBuf 接收缓冲区
nLen 接收长度*/
//返回: CommReceive 实际接受长度

DWORD CommReceive(HANDLE idComm, UCHAR *lpBuf, DWORD dwRead)
{
DWORD dwRes;
BOOL fWaitingOnRead = FALSE;
OVERLAPPED osReader = {0};
DWORD fRes;
COMMTIMEOUTS timeOutsOrg, timeOutsNew;

fRes = 0;
//为数据传送建立一个OVERLAPPED构造hEvent。在退出之前必须关闭,以避免Handle泄漏
osReader.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);

if (osReader.hEvent == NULL)
return 0; //建立OVERLAPPED Event Handle发生错误

if (!GetCommTimeouts(idComm, &timeOutsOrg)) { //取回超时参数到timeOutsOrg
CloseHandle(osReader.hEvent);
return 0;
}

//设定超时参数
timeOutsNew.ReadIntervalTimeout = 0; //二个字符之间的间隔
timeOutsNew.ReadTotalTimeoutMultiplier = 0; //因子。读操作时,该值乘上字符数
timeOutsNew.ReadTotalTimeoutConstant = READ_TIMEOUT; //常数。读操作时,该值加到因子与字符数的乘积上
timeOutsNew.WriteTotalTimeoutMultiplier = 0; //因子。写操作时,该值乘上字符数
timeOutsNew.WriteTotalTimeoutConstant = 0; //常数。写操作时,该值加到因子与字符数的乘积上

if (!SetCommTimeouts(idComm, &timeOutsNew)) { //置新的超时参数
CloseHandle(osReader.hEvent);
return 0;
}

//如果没有未完成的读操作,则发布另一个
if (!fWaitingOnRead) {
//发布读操作
if (!ReadFile(idComm, lpBuf, dwRead, &dwRead, &osReader))
if (GetLastError() != ERROR_IO_PENDING) //读操作是否被延迟?
fRes = 0; //通讯发生错误,报告错误。
else
fWaitingOnRead = TRUE;
else
fRes = dwRead; //读操作立即完成
}
if (fWaitingOnRead) {
dwRes = WaitForSingleObject(osReader.hEvent, READ_TIMEOUT);
switch (dwRes) {
case WAIT_OBJECT_0: //读操作完成
if (!GetOverlappedResult(idComm, &osReader, &dwRead, FALSE))
fRes = 0; //通讯发生错误,报告错误。
else
fRes = dwRead; //成功地完成读操作,返回读入的字节数
fWaitingOnRead = FALSE; //复位标志以便另一个操作可以发布
break;
case WAIT_TIMEOUT:
//读操作还未完成,fWaitingOnRead标志没有被改变。不发布另一个读操作,直到上一
//个完成。此时,可以做一些后台作业
fRes = 0;
break;
default:
fRes = 0; //建立OVERLAPPED Event Handle发生错误
break;
}
}
SetCommTimeouts(idComm, &timeOutsOrg);//恢复原超时参数
CloseHandle(osReader.hEvent);//关闭Handle
return fRes;
}
//---------------------------------------------------------------------------

举例:
char cShowVga1[]={0x40,0x31,0x2c,0x53,0x31,0x0d};

ComOpen(iPort);
if (!CommSend(idComm, cShowVga1, sizeof(cShowVga1)))
{
return;
}
if (CommReceive(idComm, cBuff, 6) == 6)
{
bVideo = true;
}
CommExit(idComm);
大伟 2007-09-19
  • 打赏
  • 举报
回复
//Contrl_COM.cpp
#include "Contrl_COM.h"
//---------------------------------------------------------------------------

//功能:打开指定串口
//输入:nPort   串口号(1,2,3,4)
//返回:CommInit 设备描述字
//HANDLE CommInit(long nPort)
HANDLE CommInit(LPCTSTR nPort)
{
char szPort[32];
HANDLE idComm;
idComm = CreateFile(nPort,
GENERIC_READ | GENERIC_WRITE,
0,
0,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,
0);
if(idComm == INVALID_HANDLE_VALUE)
return NULL;
return idComm;
}
//---------------------------------------------------------------------------
//功能:转换串口参数串到DCB中
//输入:szSettings[] 串口参数,例:"19200,N,8,1"
//返回:DCB 设备控制串
bool SzToDcb(char szSettings[],char SetN[],char Set8[],char Set1[],DCB *dcb)
{
AnsiString szBaud=szSettings;
AnsiString szDataBit=Set8;
AnsiString szParity=SetN;
AnsiString szStopBit=Set1;

DWORD nBaud;
BYTE nByte;
BYTE nParity;
BYTE nStop;

if (szBaud == "110")
nBaud = CBR_110;
else if (szBaud == "300")
nBaud = CBR_300;
else if (szBaud == "600")
nBaud = CBR_600;
else if (szBaud == "1200")
nBaud = CBR_1200;
else if (szBaud == "2400")
nBaud = CBR_2400;
else if (szBaud == "4800")
nBaud = CBR_4800;
else if (szBaud == "9600")
nBaud = CBR_9600;
else if (szBaud == "14400")
nBaud = CBR_14400;
else if (szBaud == "19200")
nBaud = CBR_19200;
else if (szBaud == "38400")
nBaud = CBR_38400;
else if (szBaud == "56000")
nBaud = CBR_56000;
else if (szBaud == "57600")
nBaud = CBR_57600;
else if (szBaud == "115200")
nBaud = CBR_115200;
else if (szBaud == "128000")
nBaud = CBR_128000;
else if (szBaud == "256000")
nBaud = CBR_256000;
else
return FALSE;

if (szParity == "E")
nParity = EVENPARITY;
else if (szParity == "M")
nParity = MARKPARITY;
else if (szParity == "N")
nParity = NOPARITY;
else if (szParity == "O")
nParity = ODDPARITY;
else if (szParity == "S")
nParity = SPACEPARITY;
else
return FALSE;

if (szDataBit == "4")
nByte = 4;
else if (szDataBit == "5")
nByte = 5;
else if (szDataBit == "6")
nByte = 6;
else if (szDataBit == "7")
nByte = 7;
else if (szDataBit == "8")
nByte = 8;
else
return FALSE;

if (szStopBit == "1")
nStop = ONESTOPBIT;
else if (szStopBit == "1.5")
nStop = ONE5STOPBITS;
else if (szStopBit == "2")
nStop = TWOSTOPBITS;
else
return FALSE;


dcb->BaudRate = nBaud;

dcb->Parity = nParity;

dcb->ByteSize = nByte;

dcb->StopBits = nStop;

//dcb->fRtsControl = RTS_CONTROL_ENABLE;
//dcb->fOutxCtsFlow = TRUE;

//dcb->fInX = TRUE;
//dcb->fOutX = TRUE;

return TRUE;
}
//---------------------------------------------------------------------------

//功能:将DCB中的多个参数转换成复合字符串
//输入:dcb 设备控制块
//返回:szSettings 参数字符串。例:"19200,N,8,1"
bool DcbToSz(DCB dcb, char *szSettings)
{
AnsiString szData;
char szComm[32];

itoa(dcb.BaudRate, szComm, 10); //速率
szData = szComm;
szData = szData + ',';

if (dcb.Parity == EVENPARITY) //偶校验
szData = szData + "E,";
else if (dcb.Parity == MARKPARITY) //标记校验
szData = szData + "M,";
else if (dcb.Parity == NOPARITY) //无校验
szData = szData + "N,";
else if (dcb.Parity == ODDPARITY) //奇校验
szData = szData + "O,";
else if (dcb.Parity == SPACEPARITY) //空格校验
szData = szData + "S,";

itoa(dcb.ByteSize, szComm, 10); //数据位长度
szData = szData + szComm + ",";

if (dcb.StopBits == ONESTOPBIT) //1 bit停止位
szData = szData + "1";
else if (dcb.StopBits == ONE5STOPBITS) //1.5 bit停止位
szData = szData + "1.5";
else if (dcb.StopBits == TWOSTOPBITS) //2 bit停止位
szData = szData + "2";

memcpy(szSettings,szData.c_str(),szData.Length());

return TRUE;
}
//---------------------------------------------------------------------------

//功能:关闭指定串口
//输入:idComm 设备描述字
//返回:CommExit 成功/失败
void CommExit(HANDLE idComm)
{
if (idComm != NULL)
CloseHandle(idComm);
idComm = NULL;
}
//---------------------------------------------------------------------------
//功能:置串口参数
//输入:idComm 设备描述字
// szSettings 串口参数,例:"19200,N,8,1"
//返回:ommSetup 成功/失败
bool CommSetup(HANDLE idComm, char *szSettings,char *SetN,char *Set8,char *Set1)
{
DCB dcb;

if (!GetCommState(idComm, &dcb)) //取当前设备控制块
return FALSE;

if (!SzToDcb(szSettings,SetN,Set8,Set1,&dcb)) //转换参数串到DCB中
return FALSE;

if (!SetCommState(idComm, &dcb)) //置新的设备控制块
return FALSE;

return TRUE;
}
//---------------------------------------------------------------------------
//功能:取串口参数
//输入:idComm 设备描述字
//返回:CommStatus 成功/失败
// szSettings 串口参数,例:"19200,N,8,1"
bool CommStatus(HANDLE idComm, char *szSettings)
{
DCB dcb;
if (!GetCommState(idComm, &dcb)) //取当前设备控制块
return FALSE;
if (!DcbToSz(dcb, szSettings)) //转换设备控制块中的参数到字符串
return FALSE;
return TRUE;
}
//---------------------------------------------------------------------------

大伟 2007-09-19
  • 打赏
  • 举报
回复
//Contrl_COM.h

//---------------------------------------------------------------------------
#include <vcl.h>
#include <dir.h>
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>

#define READ_TIMEOUT 3000

#ifndef Contrl_COMH
#define Contrl_COMH
//---------------------------------------------------------------------------
#endif

//功能:打开指定串口
//输入:nPort   串口号(1,2,3,4)
//返回:CommInit 设备描述字
//HANDLE CommInit(long nPort)
HANDLE CommInit(LPCTSTR nPort);
//功能:转换串口参数串到DCB中
//输入:szSettings[] 串口参数,例:"19200,N,8,1"
//返回:DCB 设备控制串
bool SzToDcb(char szSettings[],char SetN[],char Set8[],char Set1[],DCB *dcb);
//功能:将DCB中的多个参数转换成复合字符串
//输入:dcb 设备控制块
//返回:szSettings 参数字符串。例:"19200,N,8,1"
bool DcbToSz(DCB dcb, char *szSettings);
//功能:关闭指定串口
//输入:idComm 设备描述字
//返回:CommExit 成功/失败
void CommExit(HANDLE idComm);
//功能:置串口参数
//输入:idComm 设备描述字
// szSettings 串口参数,例:"19200,N,8,1"
//返回:ommSetup 成功/失败
bool CommSetup(HANDLE idComm, char *szSettings,char *SetN,char *Set8,char *Set1);
//功能:取串口参数
//输入:idComm 设备描述字
//返回:CommStatus 成功/失败
// szSettings 串口参数,例:"19200,N,8,1"
bool CommStatus(HANDLE idComm, char *szSettings);
//功能: 发送字符串
//输入: idComm 设备描述字
// szBuf 字符串
// nLen 字符串长度
//返回: CommSend 成功/失败
bool CommSend(HANDLE idComm, unsigned char *lpBuf, DWORD dwToWrite);
//功能: 接收字符串
/*输入: idComm 设备描述字
szBuf 接收缓冲区
nLen 接收长度*/
//返回: CommReceive 实际接受长度

DWORD CommReceive(HANDLE idComm, UCHAR *lpBuf, DWORD dwRead);

13,825

社区成员

发帖
与我相关
我的任务
社区描述
C++ Builder相关内容讨论区
社区管理员
  • 基础类社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧