社区
网络及通讯开发
帖子详情
在c++builder中如何读取串口数据??
xyf
2003-07-14 08:59:40
谢谢了,我应该用哪个api函数???
...全文
608
4
打赏
收藏
在c++builder中如何读取串口数据??
谢谢了,我应该用哪个api函数???
复制链接
扫一扫
分享
转发到动态
举报
AI
作业
写回复
配置赞助广告
用AI写文章
4 条
回复
切换为时间正序
请发表友善的回复…
发表回复
打赏红包
shally5
2003-07-14
打赏
举报
回复
CBuilder程序员BBS论坛
原有信息:
序 号:33
标 题:技巧:用C++Builder4.0编写Win 95下的串行异步通信程序
发信人:陈俊明
时 间:2000-1-31 12:53:29
阅读次数:11
详细信息:
用C++Builder4.0编写Win 95下的串行异步通信程序
姜滨
·串口操纵的基本方法·
在Win32下,对串口的操作就如同对文件一样打开或关闭,对串行数据的读写可在用户定义的读写缓冲区中进行。具体使用的函数为:
首先用CreateFile( )打开通信串口,其中参数lpFileName指向串口逻辑名,如“COM1”或“COM2”等,参数dwDesiredAccess定义文件的读写权限,一般设为GENERIC—READ|GENERIC—WRITE;参数dwShareMode定义资源共享方式,此处必须设为0,为独占方式;lpSecurityAttributes定义安全属性,Win 95下为NULL;dwCreationDistribution定义文件创建方式;dwFlagsAndAttributes定义文件属性和标记,应设为FILE—FLAG—OVERLAPPED,表示异步通信方式;hTemplateFile 指向一个模板文件的句柄,在 Windows 95下为NULL。
然后用BuildCommDCB( )和SetCommState( )函数通过通信设备控制块DCB(Device Control Block)设置串口通信参数(如波特率、停止位、数据位、校验位等),其中BuildCommDCB( )中的字符串参数lpDef 定义同DOS命令中MODE的参数格式,关于DCB更具体的设置需要根据用户对数据流定义、握手信号及通信控制要求具体定义,参见有关Windows技术资料。用GetCommState()可以得到当前的DCB参数值。如果需要还可通过SetCommTimeouts()和GetCommTomeouts()重新设置读写的超时参数;读写缓冲区的设置使用SetupComm(),参数dwInQueue和 dwOutQueue分别定义为输入和输出缓冲区的大小。
在串口初始化完毕后,还要建立与通信有关的事件对象。一般使用CreateEvent()函数,它返回一事件句柄,其中参数lpEventAttributes指向安全属性结构地址,在Win 95(无安全属性)中为NULL;布尔参数bManualReset 定义事件重置方式,true 表示手工重置,false表示自动重置(相关函数为SetEvent()和ResetEvent());参数bInitialState定义事件初始状态,true表示发信号,否则为不发信号;lpName是为多进程设置的事件名,对于单进程定义为NULL。然后用SetCommMask()定义用户程序可监视的通信事件类别。
以上设置完成后,用户程序就可以等待通信事件的产生,一般调用函数WaitCommEvent()监视通信事件,其中参数lpEvtMask指向产生事件的掩码地址,用于判断事件产生的性质,lpOverlapped指向重叠结构地址,可简单定义为NULL。对于串口事件的响应一般有四种方式:查询、同步I/O、异步I/O和事件驱动I/O,需要根据用户不同控制要求而定。查询方式占用较长的计算机时间,同步I/O方式直到读取完指定的字节数或超时时才返回,容易造成线程阻塞,异步I/O用于后台处理,事件驱动是由系统通知用户程序发生的事件并进行串口操作。 比较而言事件驱动I/O方式较灵活。
当有通信事件产生时,就可用函数ReadFile()和WriteFile()直接对串口缓冲区进行读写操作了。其中lpBuffer 指向读写缓冲区,nNumberOfBytes为要读写的字节数,lpNumberOfBytes为实际读写的字节数,lpOverlapped指定同步或异步操作。通信结束后,调用函数CloseHandle()将串口关闭。
·应用实例说明·
使用以上的API函数,笔者给出了简化后的串口初始化的实例。图1为使用C++ Builder 组件生成的串口通信基本参数设置的界面实例。
HANDLE hcom; //定义句柄
DCB dcb;
OVERLAPPED e; //定义重叠结构
void —fastcall TForm1::OkBtnClick(TObjectSender)
{ hcom=CreateFile("COM2",GENERIC—READ|GENERIC—WRITE,0,NULL,OPEN—EXISTING,
FILE—ATTRIBUTE—NORMAL|FILE—FLAG—OVERLAPPED,NULL); //打开通讯口
BuildCommDCB("9600,O,8,1",&dcb);
//第一个字符串参数实际使用时由图1选择后组合,这里仅简单说明其格式
SetCommState(hcom,&dcb);
SetupComm(hcom,512,512);//设置读写缓冲区
e.hEvent=CreateEvent(NULL,false,false,NULL); //设置事件
SetCommMask(hcom,EV—RXCHAR| EV—TXEMPTY); //设置事件掩码
OkBtn-〉Enabled=false;}
返回
shally5
2003-07-14
打赏
举报
回复
用Pcomm Pro 开发串行通信程序
用C + +Builder 在Win9x 下 开 发 串 行 通 信 程 序 是 程 序 员 们 经 常 遇 到 却 又 令 人 头 痛 的 事 情, 不 但 要 理 解 许 多 复 杂 的API 函 数, 还 要 掌 握 多 线 程 编 程。 令 人 欣 慰 的 是 有 一 些 公 司 专 门 为C + +Builder 开 发 了 编 写 串 行 通 信 程 序 的 开 发 工 具, 例 如MOXA 公 司 的Pcomm( 该 软 件 可 在http:\\www.moxa.com.tw 下 载), 因 而 帮 我 们 解 决 了 串 行 编 程 这 一 难 题。
----下 面 结 合 一 个 具 体 的 例 子 来 说 明 串 行 通 信 程 序 的 开 发。 本 程 序 的 编 程 环 境 是Win98 和C + +Builder3.0。 这 个 编 程 示 例 的 功 能 比 较 强, 它 具 有 发 送 数 据 和 自 动 接 收 数 据 的 双 重 功 能。 在 它 的 基 础 上 稍 加 修 改, 即 可 以 让 用 户 选 定 进 行 传 输 的 通 信 端 口, 并 设 定 这 个 端 口 的 相 关 参 数, 包 括 波 特 率、 数 据 位、 停 止 位、 奇 偶 校 验 和 流 量 控 制 等。
一、 Pcomm 的 设 置
----启 动C + +Builder3.0, 点 击File/New Application, 建 立 一 个 项 目 文 件, 修 改 表 单 的Name 属 性 为Comm, 然 后 存 盘, 命 名 项 目(Project) 为CommTest, 命 名 单 元(Unit) 为Comm。
----Pcomm Library 是 一 个 动 态 连 接 库(DLL) 文 件, 当 使 用C + +Builder 编 译 器 编 译PComm.dll 库 时, 我 们 必 须 告 诉C + +Builder 的 编 译 器 怎 样 找 到 这 些 函 数(sio_xxx())。
----因 此 我 们 用PComm Pro 在Borland C + +Builder 中 开 发 一 个 串 行 程 序 时, 必 须 做 到 以 下 两 点:
假 如 你 的Pcomm Pro 是 安 装 在c:\Program files( 缺 省 安 装 目 录) 目 录 下, 把c:\Program files \ Pcomm Pro \ Lib 下 的Pcommb.lib 文 件 加 入 到C + +Builder 的View 菜 单 中Project Manager 的 项 目 中, 使 之 成 为 项 目 的 一 个 单 元(unit)。
把 #include "c:\Program files\PcommPro\Lib\PComm.h" 包 含 在 你 的Comm.cpp 中。
二、 表 单 及 属 性 的 设 置
----如 图1 中 表 单 所 示:
----依 照 图1 中 主 界 面 来 添 加 控 件, 并 依 照 表1 中 的 设 置 来 设 置 各 控 件 的Name 和Caption 属 性。
----该 通 信 程 序 的 工 作 原 理 为 中 断 方 式, 即 当 输 入 缓 存 内 有 数 据 时, 就 会 触 发Pcomm 的 中 断 函 数sio_cnt_irq (Port, *CntIrq, count), 再 由 它 启 动 中 断 服 务 程 序CntIrq(), 然 后 由 数 据 接 收 函 数sio_read (port, ibuf, len) 来 接 收 数 据 并 做 其 他 相 应 的 处 理; 至 于 函 数 Open ()、Sent ()、Close () 则 分 别 为 打 开 按 钮、 发 送 按 钮、 关 闭 按 钮 的click 事 件 函 数;SendData、 ReceiveData 分 别 为 发 送 数 据 编 辑 框 和 接 收 数 据 编 辑 框 相 对 应 的 字 符 串 变 量。
三、 主 程 序 的 编 制
----双 击 表 单 上 的Button 控 件, 就 会 产 生 相 应 的 事 件, 如 双 击" 打 开" 按 钮, 就 会 产 生Open() 事 件 函 数。 在 这 些 函 数 中 添 加 代 码, 以 及Pcomm Pro 的 串 行 控 制 函 数, 就 能 实 现 对 串 口 事 件 的 处 理。 其 中 一 个 需 要 注 意 的 问 题 是SendData 和ReceiveData 都 为 AnsiString 字 符 串, 而Pcomm Pro 的 函 数 所 需 发 送 和 接 收 的 字 符 串 都 为 char 型, 因 此 要 正 确 使 用Pcomm 函 数, 还 要 注 意 字 符 串 转 换。AnsiString 字 符 串 可 通 过c_str() 函 数 转 换 为char 型, 而char 行 字 符 串 转 换 为 AnsiString 则 比 较 简 单。 可 用AnsiString(char) 把char 型 强 制 转 换 为AnsiString 型。 程 序 主 要 代 码 如 下 所 示:
void __fastcall TComm::Open (TObject *Sender)
// 串 口 打 开 函 数
{
int i;
sio_open (port); // 打 开 串 口
sio_ioctl (port, B2400, P_NONE | BIT_7 | STOP_1 );
// 设 置 串 口 参 数
// 包 括 波 特 率、数 据 位、停 止 位、奇 偶 校 验
void __stdcall ( *p)(int);
p=cntirq;
i=sio_cnt_irq(port, *p,1);// 设 置 中 断 函 数
}
// - - - - - - - - - - - - - - - - -
void __fastcall TComm::Sent (TObject *Sender)
// 数 据 发 送 函 数
{
char *SendData=new char[20];
SendData=SentEdit ->Text.c_str();
// 把SendEdit 中 的AnsiString 型 字
符 串 转 换 为char 型
sio_write(port,SendData,20); // 发 送 数 据
}
// - - - - - - - - - - - - - - - - -
void __fastcall TComm::Close (TObject *Sender)
// 串 口 关 闭 函 数
{
sio_close (port); // 关 闭 串 口
}
// - - - - - - - - - - - - - - - - -
void __stdcall cntirq(int port)
// 中 断 服 务 函 数( 手 工 生 成 函 数)
{
char ibuf[20];
AnsiString ReceiveData[20];
sio_read (port,ibuf, 20); // 接 收 数 据
ReceiveData = Ansistring(ibuf);
//char 字 符 串 转 换AnsiString 型 字 符 串
ReceiveEdit ->Text=ReceiveData;
// 显 示 接 受 到 的 字 符 串
}
----在 程 序 中, 我 们 使 用 了 一 些sio_xxx() 型 的 函 数, 它 们 都 是Pcomm pro 自 带 的 串 行 通 信 函 数( 函 数 的 具 体 用 法 可 以 参 考Pcomm pro 的 帮 助), 通 过 这 些 函 数, 我 们 可 以 对 串 行 端 口 进 行 设 置。
----sio_open(port) 和sio_close(port) 为 打 开 串 口 和 关 闭 串 口 函 数, 参 数port 可 设 置 具 体 操 作 的 串 口;sio_ ioctl(int port, int baud, int mode) 为 串 口 控 制 函 数, 可 设 置 串 口 的 波 特 率、 数 据 位、 停 止 位、 奇 偶 校 验; 至 于sio_write(port) 和sio_read(port), 则 为 读 串 口 和 写 串 口 函 数;sio_cnt_irq(int port,VOID (CALLBACK *func)(int port), int count) 为 中 断 函 数, 当 串 口 有 数 据 时, 就 触 发 该 函 数, 然 后 该 函 数 就 会 启 动 其 中 断 服 务 程 序VOID (CALLBACK *func)(int port)( 为 一 函 数 指 针), 这 里 是 调 用cntirq() 函 数 接 收 数 据, 该 函 数 需 要 程 序 员 手 工 生 成。
----由 此 我 们 可 以 看 出, 只 要 我 们 对 程 序 稍 加 修 改, 在 表 单 上 再 添 加 一 些 控 件, 使 得sio_xxx() 这 些 函 数 的 参 数 可 以 由 用 户 界 面 输 入, 就 可 以 做 到 由 用 户 选 定 进 行 数 据 传 输 的 通 信 端 口, 并 设 定 这 个 端 口 的 相 关 参 数, 包 括 波 特 率、 数 据 位、 停 止 位、 奇 偶 校 验 和 流 量 控 制 等
[CB技巧集][返回首页]
我不懂电脑
2003-07-14
打赏
举报
回复
ReadFile
wangxiangsjz
2003-07-14
打赏
举报
回复
可以用SPComm控件。
C++Builder
串口
通信程序
C++Builder
实例一个
串口
通信程序,包括界面的设计和
串口
通信函数的设计
C++ Builder
串口
组件
很好,很稳定的
串口
组件!!!使用过好几个
串口
组件,这个最好用了,大家分享一下!!!
C++ Builder 访问 USB 口的方法
C++ Builder 访问 USB 口的方法
xe10
c++builder
串口
控件
xe10
c++builder
串口
控件
C++ builder 编写的
串口
工具
C++ builder 编写的
串口
工具使用MSComm 控件编写
网络及通讯开发
1,317
社区成员
8,874
社区内容
发帖
与我相关
我的任务
网络及通讯开发
C++ Builder 网络及通讯开发
复制链接
扫一扫
分享
社区描述
C++ Builder 网络及通讯开发
社区管理员
加入社区
获取链接或二维码
近7日
近30日
至今
加载中
查看更多榜单
社区公告
暂无公告
试试用AI创作助手写篇文章吧
+ 用AI写文章