QQ登录

只需要一步,快速开始

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

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

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

823

主题

3

听众

4048

积分

我的地盘我做主

该用户从未签到

发帖功臣 元老勋章

跳转到指定楼层
1#
发表于 2005-1-26 13:06 |只看该作者 |倒序浏览
|招呼Ta 关注Ta
<>  </P>
2 i, I0 G  H% w! C! P<>姜滨 </P>
6 H2 b! c1 x8 M( E<>  </P>" d# j! V5 |8 v/ B; W
<>  ·串口操纵的基本方法· </P>% W, R5 S& \7 v! k1 g2 T$ `' r
<>  </P>5 o3 R5 d5 U. z( s/ R4 Z6 ^6 L
<>  </P>
' g- ~+ W2 T% D/ {* ^( z<>  在Win32下,对串口的操作就如同对文件一样打开或关闭,对串行数据的读 </P>
# W1 B: |( I; ?- a/ f; V+ o' o<>写可在用户定义的读写缓冲区中进行。具体使用的函数为: </P>
$ {- H4 U/ C6 n8 F4 u! ~<>  </P>7 M( Y. ~" h' ?; t! c  y" Q& i) |
<>  首先用CreateFile( )打开通信串口,其中参数lpFileName指向串口逻辑名 </P>
% _( p8 ]! }. C4 {$ M0 U<>,如“COM1”或“COM2”等,参数dwDesiredAccess定义文件的读写权限,一般 </P>
5 R8 n7 z& v5 ~( y<>设为GENERIC—READ|GENERIC—WRITE;参数dwShareMode定义资源共享方式,此 </P>  W# N  l0 _! s
<>处必须设为0,为独占方式;lpSecurityAttributes定义安全属性,Win 95下为 </P>) d' I# D% i7 ~
<>NULL;dwCreationDistribution定义文件创建方式;dwFlagsAndAttributes定义 </P>( O! q/ ]- q2 e+ l1 ?# u6 {
<>文件属性和标记,应设为FILE—FLAG—OVERLAPPED,表示异步通信方式; </P>3 @: k+ F# a1 p- m/ q/ B
<>hTemplateFile 指向一个模板文件的句柄,在 Windows 95下为NULL。 </P>  Z) e2 Z: z' ~- N
<>  </P>
. v0 L: ?& T2 t" C+ w: r- L<>  然后用BuildCommDCB( )和SetCommState( )函数通过通信设备控制块DCB( </P>7 i& f. \' F" `
<>Device Control Block)设置串口通信参数(如波特率、停止位、数据位、校验 </P>2 r' ^0 s0 B; R; l5 I8 ^! x: r
<>位等),其中BuildCommDCB( )中的字符串参数lpDef 定义同DOS命令中MODE的参 </P>
; c0 R6 ^: n- F<>数格式,关于DCB更具体的设置需要根据用户对数据流定义、握手信号及通信控 </P>
) J- m4 a  v$ j3 Y+ ]<>制要求具体定义,参见有关Windows技术资料。用GetCommState()可以得到当前 </P>
$ n. |% J. [6 e5 D' M<>的DCB参数值。如果需要还可通过SetCommTimeouts()和GetCommTomeouts()重新 </P>  X  K) h0 L, |3 l1 h! R  ?3 q
<>设置读写的超时参数;读写缓冲区的设置使用SetupComm(),参数dwInQueue和 </P>- h/ _5 @! \3 k
<>dwOutQueue分别定义为输入和输出缓冲区的大小。 </P>+ z( `/ M' S* Q+ W
<>  </P>- F) b9 |6 i) G3 r4 @
<>  在串口初始化完毕后,还要建立与通信有关的事件对象。一般使用 </P>
- x$ P: k! p7 A& t% L  F: _1 j<>CreateEvent()函数,它返回一事件句柄,其中参数lpEventAttributes指向安全 </P>
; c: `! S2 j- V<>属性结构地址,在Win 95(无安全属性)中为NULL;布尔参数bManualReset 定 </P>
9 _- @1 f! }4 E% _8 J% I0 y, n<>义事件重置方式,true 表示手工重置,false表示自动重置(相关函数为 </P>" X- P7 `! n! ]4 M
<P>SetEvent()和ResetEvent());参数bInitialState定义事件初始状态,true表 </P>0 D, a- |9 }& x, U
<P>示发信号,否则为不发信号;lpName是为多进程设置的事件名,对于单进程定义 </P>/ L& v- }' ]7 j% |1 N" y
<P>为NULL。然后用SetCommMask()定义用户程序可监视的通信事件类别。 </P>& Z% S' Z) |- P2 K1 R
<P>  </P>
& H& S4 I, a2 \3 Q2 Z<P>  以上设置完成后,用户程序就可以等待通信事件的产生,一般调用函数 </P>
' w7 i% K0 W1 f. A<P>WaitCommEvent()监视通信事件,其中参数lpEvtMask指向产生事件的掩码地址, </P>& U4 }2 h5 E0 [) f/ C2 i
<P>用于判断事件产生的性质,lpOverlapped指向重叠结构地址,可简单定义为 </P>' j2 x! \9 N& ?1 D. H
<P>NULL。对于串口事件的响应一般有四种方式:查询、同步I/O、异步I/O和事件驱 </P>1 R, B: z) Y# U  \9 Q
<P>动I/O,需要根据用户不同控制要求而定。查询方式占用较长的计算机时间,同 </P>
9 c' b9 U& \& B; f2 h<P>步I/O方式直到读取完指定的字节数或超时时才返回,容易造成线程阻塞,异步 </P>
. E8 [) A: w  J/ w& M: y<P>I/O用于后台处理,事件驱动是由系统通知用户程序发生的事件并进行串口操作 </P>! k" M' z3 G4 S2 e! C/ e$ T( b
<P>。 比较而言事件驱动I/O方式较灵活。 </P>2 r: [' x5 ^6 a2 b* H( n5 N" V
<P>  </P># @6 ]% H: J: ?  V" X$ k
<P>  当有通信事件产生时,就可用函数ReadFile()和WriteFile()直接对串口缓 </P>
- U7 n# \8 g  j( G" P: u<P>冲区进行读写操作了。其中lpBuffer 指向读写缓冲区,nNumberOfBytes为要读 </P>
$ g; W1 E4 f- |1 \- A+ S! z7 s4 i<P>写的字节数,lpNumberOfBytes为实际读写的字节数,lpOverlapped指定同步或 </P>
* l+ V% }8 s  F$ i- o% g' D<P>异步操作。通信结束后,调用函数CloseHandle()将串口关闭。 </P>+ u4 v/ \0 n7 u: _9 z% t
<P>  </P>4 d4 M# q1 I% Z2 C
<P>  ·应用实例说明· </P>
8 g+ {4 z) o5 D: i2 V$ N<P>  </P>3 C5 w; o5 y" x& Q
<P>  </P>
' c2 Y0 K( k. C<P>  使用以上的API函数,笔者给出了简化后的串口初始化的实例。图1为使用C </P>1 D  m" Q, @7 F
<P>++ Builder 组件生成的串口通信基本参数设置的界面实例。 </P>
# j" ^% r1 y, n% C5 c<P>  </P>  e4 D* D! |0 ?: Q
<P>  HANDLE hcom; //定义句柄 </P>' Z  Z% H, O6 w
<P>  </P>
! F/ u, B/ b6 |+ s6 @- \<P>  DCB dcb; </P>
$ N  \6 n9 s  V0 N4 P<P>  </P>) ^+ m9 \6 i' [* ~. o
<P>  OVERLAPPED e; //定义重叠结构 </P>
9 ]/ d4 Z0 {. m) Y7 C" x1 ~<P>  </P>
9 i4 c) a( z+ s$ H* ~9 Z7 Z<P>  void —fastcall TForm1::OkBtnClick(TObject?Sender) </P>& _+ r- j0 w! R, x3 O$ w
<P>  </P>, F/ V+ M4 C1 o9 U) R  ~1 c4 u- Q
<P>  { hcom=CreateFile("COM2",GENERIC—READ|GENERIC—WRITE,0,NULL,OPEN </P>
. _$ ?: ~; \; i- o, @7 E+ W<P>—EXISTING, </P>6 K7 s. @; w5 f0 q/ V8 z+ B+ z$ h
<P>FILE—ATTRIBUTE—NORMAL|FILE—FLAG—OVERLAPPED,NULL); //打开通讯口 </P>
8 a( k0 c* j6 G2 j<P>  </P>
- D8 ~8 J: \' M; _! L<P>   BuildCommDCB("9600,O,8,1",&dcb); </P>
7 N- i% x& a: O/ |<P>  </P>
8 h0 e: |6 |, J1 u* A2 X" ?$ _  d4 e<P>//第一个字符串参数实际使用时由图1选择后组合,这里仅简单说明其格式 </P>
2 H% [9 ^% v4 [& q; q8 o% D: b<P>  </P>
8 v: {0 l' o, J  V: s& {7 A1 r<P>   SetCommState(hcom,&dcb); </P>6 z" ]0 A/ [. r; L
<P>  </P>
  r( m- [! _; M/ Z<P>   SetupComm(hcom,512,512);//设置读写缓冲区 </P>
7 e. n2 ?3 @$ j2 B, X<P>  </P>
1 I  i$ _2 X! r<P>   e.hEvent=CreateEvent(NULL,false,false,NULL); //设置事件 </P>
3 J/ O9 V# D/ ?; ~& F<P>  </P>- E8 [- p# D" d' s' s% J. c
<P>   SetCommMask(hcom,EV—RXCHAR| EV—TXEMPTY); //设置事件掩码 </P>! `: c# J4 u/ b' e
<P>  </P>. z7 t* b1 w3 ]& m9 v, @" Z$ X
<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, 2026-1-16 03:33 , Processed in 0.962789 second(s), 91 queries .

回顶部