QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 10564|回复: 7
打印 上一主题 下一主题

用C++Builder4.0编写Win 95下的串行异步通信程序

[复制链接]
字体大小: 正常 放大
韩冰        

823

主题

3

听众

4048

积分

我的地盘我做主

该用户从未签到

发帖功臣 元老勋章

跳转到指定楼层
1#
发表于 2005-1-26 13:06 |只看该作者 |倒序浏览
|招呼Ta 关注Ta
<>  </P>
- ^0 c6 g% ~8 B7 f: c* \! i) z3 `9 s: ?<>姜滨 </P>
; y( D7 \: Z$ Q7 d" b8 h<>  </P>
* e2 M3 D' M* N! T) ]& a<>  ·串口操纵的基本方法· </P>2 L" E# ~- X: v7 y' D! ^
<>  </P>  H, M; R5 N* M4 Z) z
<>  </P>; ?9 O, K6 g9 }2 @6 f
<>  在Win32下,对串口的操作就如同对文件一样打开或关闭,对串行数据的读 </P>: y& C, f& X. f5 }+ C
<>写可在用户定义的读写缓冲区中进行。具体使用的函数为: </P>) W/ D. p* J5 X9 Q+ S2 @
<>  </P>$ t/ Y3 y" `% }: K% @  j3 f3 u9 W
<>  首先用CreateFile( )打开通信串口,其中参数lpFileName指向串口逻辑名 </P>$ U% `9 K" q/ t+ y8 _% ~
<>,如“COM1”或“COM2”等,参数dwDesiredAccess定义文件的读写权限,一般 </P>
; W* `8 E( [) ]+ _<>设为GENERIC—READ|GENERIC—WRITE;参数dwShareMode定义资源共享方式,此 </P>
7 Q8 t, `, ]1 @" e<>处必须设为0,为独占方式;lpSecurityAttributes定义安全属性,Win 95下为 </P>. M2 g/ A/ X1 h2 o& s( N0 E
<>NULL;dwCreationDistribution定义文件创建方式;dwFlagsAndAttributes定义 </P>
: b% Q( B& N* S6 T& r<>文件属性和标记,应设为FILE—FLAG—OVERLAPPED,表示异步通信方式; </P>
8 D) M) b) a2 Q. m4 U  \<>hTemplateFile 指向一个模板文件的句柄,在 Windows 95下为NULL。 </P>4 m8 n* D3 i- }
<>  </P>" T- J. \$ q/ `$ ?
<>  然后用BuildCommDCB( )和SetCommState( )函数通过通信设备控制块DCB( </P>
- ^: z, V, n: g/ U4 X9 g+ ^+ u<>Device Control Block)设置串口通信参数(如波特率、停止位、数据位、校验 </P>
% o- k) L) }: M- [+ {- v& x<>位等),其中BuildCommDCB( )中的字符串参数lpDef 定义同DOS命令中MODE的参 </P>5 Y  H* [  `; I
<>数格式,关于DCB更具体的设置需要根据用户对数据流定义、握手信号及通信控 </P>
( k, |* w7 W* e; D$ }  p0 H<>制要求具体定义,参见有关Windows技术资料。用GetCommState()可以得到当前 </P># k0 g+ t  S. I# C
<>的DCB参数值。如果需要还可通过SetCommTimeouts()和GetCommTomeouts()重新 </P>% O  A2 j" {0 K# i" w6 M: V
<>设置读写的超时参数;读写缓冲区的设置使用SetupComm(),参数dwInQueue和 </P>" j# h, @6 [8 }$ ]" t
<>dwOutQueue分别定义为输入和输出缓冲区的大小。 </P>
; F! _5 T& S2 J$ P<>  </P>
0 @% s6 l: g$ ^( O, u* d" E<>  在串口初始化完毕后,还要建立与通信有关的事件对象。一般使用 </P>
- |3 g* V0 [6 N+ P. X<>CreateEvent()函数,它返回一事件句柄,其中参数lpEventAttributes指向安全 </P>
2 F: Y( I9 `. H, T; j<>属性结构地址,在Win 95(无安全属性)中为NULL;布尔参数bManualReset 定 </P>" m' \9 ~- ~! W! ]) e9 ]2 B4 A
<>义事件重置方式,true 表示手工重置,false表示自动重置(相关函数为 </P>% I, z8 W' y* k; U3 G
<P>SetEvent()和ResetEvent());参数bInitialState定义事件初始状态,true表 </P>
$ `+ m( S* ]7 O/ V0 d6 O' e8 Z<P>示发信号,否则为不发信号;lpName是为多进程设置的事件名,对于单进程定义 </P>$ b0 C' m. }8 G' V
<P>为NULL。然后用SetCommMask()定义用户程序可监视的通信事件类别。 </P>* x* w9 k; _$ r
<P>  </P>8 O7 C. L, _2 l
<P>  以上设置完成后,用户程序就可以等待通信事件的产生,一般调用函数 </P>
. h+ D# F# \3 V5 D. p<P>WaitCommEvent()监视通信事件,其中参数lpEvtMask指向产生事件的掩码地址, </P>
0 ~2 W* ]: }2 ?' d% I/ |9 N& }<P>用于判断事件产生的性质,lpOverlapped指向重叠结构地址,可简单定义为 </P>
3 F7 |# m1 p1 ]1 N% o$ l<P>NULL。对于串口事件的响应一般有四种方式:查询、同步I/O、异步I/O和事件驱 </P># \( ~' K( n* d& U; |! b& N! F
<P>动I/O,需要根据用户不同控制要求而定。查询方式占用较长的计算机时间,同 </P>9 S8 K6 [  G7 `
<P>步I/O方式直到读取完指定的字节数或超时时才返回,容易造成线程阻塞,异步 </P>
# M9 [% f% j# s' b<P>I/O用于后台处理,事件驱动是由系统通知用户程序发生的事件并进行串口操作 </P>5 j0 m9 z5 p& W# `+ v5 G
<P>。 比较而言事件驱动I/O方式较灵活。 </P>- j4 u. @) U3 I% j; z
<P>  </P>' \& E: t% k+ }, m2 W4 Y6 k* }9 k. D
<P>  当有通信事件产生时,就可用函数ReadFile()和WriteFile()直接对串口缓 </P>
! R. t0 O' l1 [3 L3 v5 \' q& I' S' E<P>冲区进行读写操作了。其中lpBuffer 指向读写缓冲区,nNumberOfBytes为要读 </P>
7 d$ t. s# P! T3 J<P>写的字节数,lpNumberOfBytes为实际读写的字节数,lpOverlapped指定同步或 </P>
9 R$ r8 [  C" l- n<P>异步操作。通信结束后,调用函数CloseHandle()将串口关闭。 </P>
: e; {1 v: u& T4 O$ }" ~% u' _4 u<P>  </P>0 ?4 z! ^5 |1 o; W
<P>  ·应用实例说明· </P>
5 f1 {, h, ?# Q<P>  </P>
( d1 G2 y& B1 H! e$ F$ R6 M* t<P>  </P>
. {4 Q' J) w% F/ T( ?1 i<P>  使用以上的API函数,笔者给出了简化后的串口初始化的实例。图1为使用C </P>
* x; U3 b, F  A: a% r<P>++ Builder 组件生成的串口通信基本参数设置的界面实例。 </P>
. y. O3 i( [7 z7 B4 `! K4 b<P>  </P>5 J- q. |7 u6 f7 A
<P>  HANDLE hcom; //定义句柄 </P>
5 ]$ f$ v) y! |# e/ k<P>  </P>
, F3 h$ b. O" S<P>  DCB dcb; </P>
0 ^& ~' K- T7 C5 A/ w2 B& M! `<P>  </P>' }5 g+ s% H8 S5 N: i6 `
<P>  OVERLAPPED e; //定义重叠结构 </P>
; Z8 C; _3 G7 z) q9 q/ Y<P>  </P>2 i, ~' J: j+ t& O# S& K4 ~
<P>  void —fastcall TForm1::OkBtnClick(TObject?Sender) </P>6 I, ]8 Q) ~- h5 e  q3 R) e# d% T
<P>  </P>& O" X* M! i( A' }8 k+ K9 d
<P>  { hcom=CreateFile("COM2",GENERIC—READ|GENERIC—WRITE,0,NULL,OPEN </P>
& d7 N3 L5 K+ I* D<P>—EXISTING, </P>
+ o$ ]+ l' ^5 z( g<P>FILE—ATTRIBUTE—NORMAL|FILE—FLAG—OVERLAPPED,NULL); //打开通讯口 </P>8 R4 j% D! T% t8 \- S, Y3 V0 T# w1 P4 J
<P>  </P>
3 B" L, Z0 i+ l# C& u: u& }<P>   BuildCommDCB("9600,O,8,1",&dcb); </P>
- i) j# Z- T) o9 ?; j: k7 J) ~<P>  </P>
% }( W" p, r% Z: K& n) p! V<P>//第一个字符串参数实际使用时由图1选择后组合,这里仅简单说明其格式 </P>
1 k- c! {1 j# R4 O5 s, K<P>  </P>; r+ o# f9 m% Y  J/ t7 g
<P>   SetCommState(hcom,&dcb); </P>% u3 a$ P  e4 P1 C0 v
<P>  </P>, `8 W3 p% {( m% G
<P>   SetupComm(hcom,512,512);//设置读写缓冲区 </P>
" I7 g3 x! T$ a5 a  B5 O' {/ v' H0 s! ?<P>  </P>
: O* t4 x: a2 a6 ?2 a<P>   e.hEvent=CreateEvent(NULL,false,false,NULL); //设置事件 </P>
, w" k' J. v2 L) w<P>  </P>
2 x/ x- g( l$ f; A) r<P>   SetCommMask(hcom,EV—RXCHAR| EV—TXEMPTY); //设置事件掩码 </P>: K0 A5 `, c* e4 H5 f& Q4 E
<P>  </P>; L2 j& }5 M9 O1 M
<P>   OkBtn-〉Enabled=false;} </P>
zan
转播转播0 分享淘帖0 分享分享0 收藏收藏0 支持支持0 反对反对0 微信微信
cjplove        

0

主题

0

听众

50

积分

升级  47.37%

该用户从未签到

新人进步奖

回复

使用道具 举报

cjplove        

0

主题

0

听众

50

积分

升级  47.37%

该用户从未签到

新人进步奖

回复

使用道具 举报

xtmlj        

0

主题

2

听众

95

积分

升级  94.74%

该用户从未签到

新人进步奖

回复

使用道具 举报

lhc_mike        

0

主题

2

听众

52

积分

升级  49.47%

该用户从未签到

新人进步奖

回复

使用道具 举报

ai8815 实名认证       

0

主题

3

听众

26

积分

升级  22.11%

该用户从未签到

自我介绍
呵呵 大家多多交流呀!!
回复

使用道具 举报

ai8815 实名认证       

0

主题

3

听众

26

积分

升级  22.11%

该用户从未签到

自我介绍
呵呵 大家多多交流呀!!
回复

使用道具 举报

8#
无效楼层,该帖已经被删除
您需要登录后才可以回帖 登录 | 注册地址

qq
收缩
  • 电话咨询

  • 04714969085
fastpost

关于我们| 联系我们| 诚征英才| 对外合作| 产品服务| QQ

手机版|Archiver| |繁體中文 手机客户端  

蒙公网安备 15010502000194号

Powered by Discuz! X2.5   © 2001-2013 数学建模网-数学中国 ( 蒙ICP备14002410号-3 蒙BBS备-0002号 )     论坛法律顾问:王兆丰

GMT+8, 2025-8-10 12:03 , Processed in 1.621570 second(s), 91 queries .

回顶部