社区
C++ Builder
帖子详情
关于读入数据到缓的问题
liupeng33
2007-09-19 12:49:58
在BCB6中,如何从串口设备中读数据并存入缓存,然后再统一将这些数据写入文件?
...全文
91
4
打赏
收藏
关于读入数据到缓的问题
在BCB6中,如何从串口设备中读数据并存入缓存,然后再统一将这些数据写入文件?
复制链接
扫一扫
分享
举报
写回复
配置赞助广告
用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);
C++
数据
读入
优化
C++
数据
读入
优化C++中
读入
数据
有许多函数,如scanf、cin,那么如何提高
读入
和输出的效率呢?1、
读入
优化 下面是正负数
读入
优化模板1:#include<cctype> inline int read() { int X=0,f=0; char ch=0; while(!isdigit(ch)) {f|=ch=='-';ch=getchar();} ...
关于codeblocks
读入
文件的
问题
第一次接触从C语言的文件
读入
,有个
问题
难住我好半天,下面以一个
读入
成绩的
数据
复盘一下。 第一步,建立‘文件
读入
’项目,这个上一篇博客已经有讲,不再重复。 第二步,建立
数据
文件txt,**记住这个文件放的位置要和你的写的路径一致,像这个程序我直接把txt文件放在C语言的根目录**下,用函数fopen打开也是。 第三步,写入主函数,代码如下 `#include <stdio.h> #include <stdlib.h> int main (void) { FILE *fp;//定义头文件
MOM(一)
数据
读入
一、
读入
文件介绍 1、rwg 第一个数代表rwg的个数 下面几行的前两个数字 表示相邻两个element 的编号。2、element (即一个三角形面片) 第一个数为 element 的个数,后面为顶点坐标坐标。 二、
读入
剖分
数据
读取 element 信息时,创建了一个3D 矩阵,每一层都表示一个 element ,而一个 element 由3个顶点组成,每个顶点由3个不同方...
pytorch
数据
读入
在机器学习和深度学习中,
数据
读入
是一个非常重要的步骤。PyTorch提供了非常灵活的
数据
读取方式,主要是通过Dataset和DataLoader两个类来完成的。
使用scanf循环
读入
数据
使用scanf循环
读入
数据
循环
读入
数字 #include<stdio.h> int main(){ int n; while(scanf("%d",&n) != EOF){ printf("%d",n); } return 0; } 循环
读入
字符串 #include<stdio.h> int main(){ char str[...
C++ Builder
13,871
社区成员
102,696
社区内容
发帖
与我相关
我的任务
C++ Builder
C++ Builder相关内容讨论区
复制链接
扫一扫
分享
社区描述
C++ Builder相关内容讨论区
社区管理员
加入社区
获取链接或二维码
近7日
近30日
至今
加载中
查看更多榜单
社区公告
暂无公告
试试用AI创作助手写篇文章吧
+ 用AI写文章