社区
C++ Builder
帖子详情
如何从串口读数据?(100)
Sammi52
2003-09-29 12:42:55
磁卡阅读器将磁卡数据输出到计算机的串口,如何写代码从串口读取数据呢?
...全文
227
7
打赏
收藏
如何从串口读数据?(100)
磁卡阅读器将磁卡数据输出到计算机的串口,如何写代码从串口读取数据呢?
复制链接
扫一扫
分享
转发到动态
举报
写回复
配置赞助广告
用AI写文章
7 条
回复
切换为时间正序
请发表友善的回复…
发表回复
打赏红包
路人丁
2003-10-11
打赏
举报
回复
给不给都无所谓,现在已经不做工控了
Sammi52
2003-09-29
打赏
举报
回复
由于答者的回答过于复杂,其实实现很简单,所以本贴不给到顶,请见谅!
Sammi52
2003-09-29
打赏
举报
回复
wgrabob1(红客男孩) :WINIO是什么东东?怎么用?
wgrabob1
2003-09-29
打赏
举报
回复
有个叫WINIO的东东还不错
路人丁
2003-09-29
打赏
举报
回复
C++ Builder 编程文集
用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() 这 些 函 数 的 参 数 可 以 由 用 户 界 面 输 入, 就 可 以 做 到 由 用 户 选 定 进 行 数 据 传 输 的 通 信 端 口, 并 设 定 这 个 端 口 的 相 关 参 数, 包 括 波 特 率、 数 据 位、 停 止 位、 奇 偶 校 验 和 流 量 控 制 等
路人丁
2003-09-29
打赏
举报
回复
·应用实例说明·
使用以上的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;}
用C++ Builder编程实现串行通信
(武汉 刘纪锋)
用C++ Builder来编写串行通信程序, 我们需要用到几个Windows API函数,而不象在DOS 下那样直接操作串口和中断芯片.这几个函数有OpenFile, CloseFile, GetCommState, SetCommState等,Microsoft的Visual Basic中有一个OCX控件MSComm32,在VB用它做串行通信设备很方便, 将它装入Builder 3中, 它的Input和Ouput属性是Unknown, 即 Builder 3不认识MSComm32的这两个属性, 我们升级到Borland的C++ Builder 4.0,在 Object Inspector中将不再看到这两个属性, 但它们仍然存在, 这两个属性的类型是 OleVariant,也就是Ole万能变量,使用这种类型的方法如下:
在要发送数据时,我们声明一个发送数据缓冲区,然后重置它的大小,填充它的元素,发送它,例如:
buff[200];//请声明为全局变量
OleVariant TxBuff;//声明一个OleVariant变量
Txbuff=VarArrayCreat(OPENARRAY(int,(0,n)),varByte);//重置它的大小,为0~n,int 为n的类型。
//varByte为TxBuff每一个元素的类型。
for(int i=0;i<n+1;i++)Txbuff.PutElement(buf[i],i);
//填充元素其中buff为你定义的一个固定数组,其中有你要发的数据
MsComm1->Output=TxBuff;//发送数据,MSComm1为你方在窗体上的一个MSComm32控件。接收数据时请看下面的例子:
int buff[200];//声明一个存储接收数据的缓冲区,全局变量
int ByteNum;//收到的字节数
int BuffPtr;//接收缓冲区的指针,请声明为全局变量,
OleVariant RxBuff;//一个用于接收的OleVariant变量。
if(MSComm1-> InBuffCount>0)RxBuff=Communica1->Input;//如果缓冲区有多于一个字节的数据
ByteNum=RxBuff.ArrayHighBound(1);//将实际读的字节数取出
for(int i=0;i<=ByteNum;i++){buff[BuffPtr++]=RxBuff.GetElement(i);}//将接收数据读入自己的缓冲区。
在Object Inspector的Event标签中只有一个事件OnComm, 这个事件在MSComm32控件接收到数据时会被调用,但你必须设置TThreshold属性,这是一个门槛,表示收到几个字节就发送通知消息,如果为零,就不发送通知消息,这样你的OnComm函数就不会得到执行,TThreshold是发送门槛,不要忘记Setting。
另外值得注意的是MSComm32的OnComm事件不是很准确,有时会丢失,你不能过分依赖这个事件,否则,经常发生的不是发不出数据,就是接收不到数据,最好的办法是使用一个定时控件,需要的时候就区读MSComm32控件的缓冲区。
路人丁
2003-09-29
打赏
举报
回复
给你一篇文章看看
注意看CreateFile, ReadFile, WriteFile三个函数!
用C++ Builder 4.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()将串口关闭。
C#
串口
通信(彻底解决C#
串口
通信中的数据丢失问题)
以网上某位大虾的源码为版本,沿用了其可用的代码部分。对其余欠妥部分进行了改造。不要资源分,是大家不用为积分而烦恼。出来混都不容易,希望大家相互照应!
VB
串口
通信源码210个
026、VB
串口
编程实现完整的多费率电表读数软件 027、VB
串口
程序,,是一个
串口
使用例程,对初学者有用,特别是工控类的 028、VB
串口
传输文本,实现2台PC间的通信,类似简单的聊天工具 029、VB
串口
的一个电子称的项目 030、...
STM32使用DMA从
串口
读数据
到内存
使用DMA从
串口
读数据
到内存和从内存搬数据到
串口
一样,只是要注意所使用的DMA通道不一样。 当配置好后,如果
串口
上有数据传输,DMA就自动把数据搬到内存中。 当工作在正常模式,DMA搬运了设定长度的数据后,会产生...
linux怎么查看系统可用
串口
,linux
串口
驱动详解 如何查看linux下
串口
是否可用?
串口
名称等?...
linux
串口
驱动该怎么写是的,
串口
设备也是字符设备呀 但是一般serial 0会被当作console。linux下
串口
驱动如何实现?用驱动程序啊 不过现在一般都能自动安装如何查看linux下
串口
是否可用?
串口
名称等?查看
串口
是否...
python树莓派
串口
通信实例_python如何读取
串口
数据 python读取
串口
数据代码示例...
python如何读取
串口
数据?本篇文章小编给大家分享一下python读取
串口
数据代码示例,文章代码介绍的很详细,小编觉得挺...其中用的树莓派是3代B+,zigbee每隔三秒钟从
串口
输出数据。下面是python
串口
通信,但是不是li...
C++ Builder
13,822
社区成员
102,680
社区内容
发帖
与我相关
我的任务
C++ Builder
C++ Builder相关内容讨论区
复制链接
扫一扫
分享
社区描述
C++ Builder相关内容讨论区
社区管理员
加入社区
获取链接或二维码
近7日
近30日
至今
加载中
查看更多榜单
社区公告
暂无公告
试试用AI创作助手写篇文章吧
+ 用AI写文章