QQ登录

只需要一步,快速开始

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

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

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

823

主题

3

听众

4048

积分

我的地盘我做主

该用户从未签到

发帖功臣 元老勋章

跳转到指定楼层
1#
发表于 2005-1-26 13:06 |只看该作者 |倒序浏览
|招呼Ta 关注Ta
<>  </P>
' u4 O1 L9 S* [- H( G<>姜滨 </P>
6 R. m9 {7 s9 H% F+ j8 D<>  </P>! e* u. T/ S, r$ O% _
<>  ·串口操纵的基本方法· </P>: ]  n/ {* X* g: P; d0 e
<>  </P>: q& a( y0 B" `& B. X7 G
<>  </P>3 Y& n+ N0 B. o* m# b
<>  在Win32下,对串口的操作就如同对文件一样打开或关闭,对串行数据的读 </P>3 s2 m$ C6 C0 O  G% h  }
<>写可在用户定义的读写缓冲区中进行。具体使用的函数为: </P>
: i+ m9 ^, S0 I* a<>  </P>/ v' F4 k$ _( e- @. S* c7 `; U+ n
<>  首先用CreateFile( )打开通信串口,其中参数lpFileName指向串口逻辑名 </P>3 `6 M& ^( e, O$ I. P$ g
<>,如“COM1”或“COM2”等,参数dwDesiredAccess定义文件的读写权限,一般 </P>, O% N: j* M; c. c
<>设为GENERIC—READ|GENERIC—WRITE;参数dwShareMode定义资源共享方式,此 </P>
3 ]! B6 Q2 ]5 T& @8 V5 o- t! y* G! i<>处必须设为0,为独占方式;lpSecurityAttributes定义安全属性,Win 95下为 </P>4 Q9 p4 C* U4 [# m- a& V, V
<>NULL;dwCreationDistribution定义文件创建方式;dwFlagsAndAttributes定义 </P>) P4 q% g5 b2 v, x
<>文件属性和标记,应设为FILE—FLAG—OVERLAPPED,表示异步通信方式; </P>7 u9 |! p5 W* z, Y2 u( q
<>hTemplateFile 指向一个模板文件的句柄,在 Windows 95下为NULL。 </P>" z8 Z) e8 E1 n% d
<>  </P>
5 R* y$ R, H% ?2 I( y% J% M: i' i<>  然后用BuildCommDCB( )和SetCommState( )函数通过通信设备控制块DCB( </P>0 f2 M$ c: f( L8 b. ]
<>Device Control Block)设置串口通信参数(如波特率、停止位、数据位、校验 </P>
' q! B& O3 z4 x, d$ q4 x<>位等),其中BuildCommDCB( )中的字符串参数lpDef 定义同DOS命令中MODE的参 </P>
3 `' A' C$ e. T5 R0 J, p4 n<>数格式,关于DCB更具体的设置需要根据用户对数据流定义、握手信号及通信控 </P># g6 t# C+ K0 t
<>制要求具体定义,参见有关Windows技术资料。用GetCommState()可以得到当前 </P>
6 z/ J3 T2 u; ]% b4 n<>的DCB参数值。如果需要还可通过SetCommTimeouts()和GetCommTomeouts()重新 </P>
8 N; A: ^4 m# |( x$ g* d<>设置读写的超时参数;读写缓冲区的设置使用SetupComm(),参数dwInQueue和 </P>% |! r& _7 N; k1 x9 Z, q
<>dwOutQueue分别定义为输入和输出缓冲区的大小。 </P>
2 Q1 B' \) P7 G/ L9 w, @<>  </P>/ e9 l- _2 D# e+ ^4 A
<>  在串口初始化完毕后,还要建立与通信有关的事件对象。一般使用 </P>
7 T) K) t1 V5 A5 |5 O2 I/ Y<>CreateEvent()函数,它返回一事件句柄,其中参数lpEventAttributes指向安全 </P>
  H4 W. z! c1 k9 E; i* b; d2 a<>属性结构地址,在Win 95(无安全属性)中为NULL;布尔参数bManualReset 定 </P>
4 V' O/ b' v2 E" I/ ]) e7 M<>义事件重置方式,true 表示手工重置,false表示自动重置(相关函数为 </P>1 @# {1 Y1 J0 S
<P>SetEvent()和ResetEvent());参数bInitialState定义事件初始状态,true表 </P>
0 |* g8 S4 l/ Y<P>示发信号,否则为不发信号;lpName是为多进程设置的事件名,对于单进程定义 </P>
' R7 k7 s$ y# E4 l/ X1 R<P>为NULL。然后用SetCommMask()定义用户程序可监视的通信事件类别。 </P>
$ y" q, I) o( |2 G. _- n0 ~<P>  </P>
! x- ~. L6 c7 S$ @3 K<P>  以上设置完成后,用户程序就可以等待通信事件的产生,一般调用函数 </P>1 b* t8 g: h4 P! d5 x
<P>WaitCommEvent()监视通信事件,其中参数lpEvtMask指向产生事件的掩码地址, </P>9 j& I: f8 z; ]0 ]9 I; u$ B- S
<P>用于判断事件产生的性质,lpOverlapped指向重叠结构地址,可简单定义为 </P>
( x9 c9 U% @6 N3 E4 e<P>NULL。对于串口事件的响应一般有四种方式:查询、同步I/O、异步I/O和事件驱 </P>6 ]# X9 e  h6 B5 \1 K8 M
<P>动I/O,需要根据用户不同控制要求而定。查询方式占用较长的计算机时间,同 </P>
; ^0 @8 G+ L9 x' O2 C& A; x<P>步I/O方式直到读取完指定的字节数或超时时才返回,容易造成线程阻塞,异步 </P>
6 Q0 t  f: B( i  j: |; r% F<P>I/O用于后台处理,事件驱动是由系统通知用户程序发生的事件并进行串口操作 </P>  O4 S# u0 G4 i3 j- Q
<P>。 比较而言事件驱动I/O方式较灵活。 </P>% V6 e& J( z% Z+ N; h
<P>  </P>0 W1 b- w; d5 r& u! I! n
<P>  当有通信事件产生时,就可用函数ReadFile()和WriteFile()直接对串口缓 </P>; Q8 i5 v7 f3 }; n* N+ D
<P>冲区进行读写操作了。其中lpBuffer 指向读写缓冲区,nNumberOfBytes为要读 </P>+ J5 F4 s4 L7 q- U( H1 G0 C
<P>写的字节数,lpNumberOfBytes为实际读写的字节数,lpOverlapped指定同步或 </P>: l* n8 k2 d1 O2 K6 d! ]/ b
<P>异步操作。通信结束后,调用函数CloseHandle()将串口关闭。 </P>
  d( Q8 ?6 Q, A' j<P>  </P>
' b1 Z: F& a) T+ i+ r8 ]; d0 `<P>  ·应用实例说明· </P>3 h( w: a: ~7 {2 n
<P>  </P>
, ?' p4 f* {+ q: b0 S$ F<P>  </P>& Q* u4 c+ y; }9 u; e4 n- Y
<P>  使用以上的API函数,笔者给出了简化后的串口初始化的实例。图1为使用C </P>( Y; u" P6 I  x  e
<P>++ Builder 组件生成的串口通信基本参数设置的界面实例。 </P>/ `' t/ e+ }% n5 b+ q( |8 O
<P>  </P>
! a- N2 l- t1 t! W3 p8 W<P>  HANDLE hcom; //定义句柄 </P>1 x6 b6 M4 U5 o! j' X: f8 v8 e5 X
<P>  </P>& F4 E1 q1 ^, k- T
<P>  DCB dcb; </P>1 U. E8 N3 T/ w9 `3 m  |
<P>  </P>5 U0 k' y/ P  I9 a
<P>  OVERLAPPED e; //定义重叠结构 </P>6 p8 s. \3 B+ J4 k
<P>  </P>. v7 i$ E# o* s; f9 b
<P>  void —fastcall TForm1::OkBtnClick(TObject?Sender) </P>
. r, H/ b& Q6 o' @4 s& z5 V* m<P>  </P>0 s1 U2 a; ~$ g; D
<P>  { hcom=CreateFile("COM2",GENERIC—READ|GENERIC—WRITE,0,NULL,OPEN </P>
$ _2 r$ Z; i7 _! @# `<P>—EXISTING, </P>
( |3 L# t/ v; a3 o- q<P>FILE—ATTRIBUTE—NORMAL|FILE—FLAG—OVERLAPPED,NULL); //打开通讯口 </P>
0 y9 {5 B6 a" ~3 O<P>  </P>  w1 f* o% I* t
<P>   BuildCommDCB("9600,O,8,1",&dcb); </P>
* Y8 U4 M  I: p" j5 y% S! m, N<P>  </P>: O( q4 M  w# y1 w& f! j8 I
<P>//第一个字符串参数实际使用时由图1选择后组合,这里仅简单说明其格式 </P>
# @. f( a# k- Z4 p# }- C+ U" @, l<P>  </P>2 T7 A- }2 _& n- p4 [% c
<P>   SetCommState(hcom,&dcb); </P>
: M, v, q+ k& N5 Q% r% K: w<P>  </P>
& I* L+ q5 x: J8 M+ G8 R) I<P>   SetupComm(hcom,512,512);//设置读写缓冲区 </P>5 q$ H$ g3 |/ G$ F) v& j! f& |* A  S# K
<P>  </P>
- @! L8 u5 [' ~, @<P>   e.hEvent=CreateEvent(NULL,false,false,NULL); //设置事件 </P>
$ R" q4 v' X& Z. _! ^<P>  </P>
4 f, s' N. U- d$ t7 A<P>   SetCommMask(hcom,EV—RXCHAR| EV—TXEMPTY); //设置事件掩码 </P>
: |. N" Q- k% j3 s# Q<P>  </P>
1 z1 y; \( Y/ N+ p0 F) n<P>   OkBtn-〉Enabled=false;} </P>
zan
转播转播0 分享淘帖0 分享分享0 收藏收藏0 支持支持0 反对反对0 微信微信
cjplove        

0

主题

0

听众

50

积分

升级  47.37%

该用户从未签到

新人进步奖

回复

使用道具 举报

cjplove        

0

主题

0

听众

50

积分

升级  47.37%

该用户从未签到

新人进步奖

回复

使用道具 举报

lhc_mike        

0

主题

2

听众

52

积分

升级  49.47%

该用户从未签到

新人进步奖

回复

使用道具 举报

xtmlj        

0

主题

2

听众

95

积分

升级  94.74%

该用户从未签到

新人进步奖

回复

使用道具 举报

ai8815 实名认证       

0

主题

3

听众

26

积分

升级  22.11%

该用户从未签到

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

使用道具 举报

ai8815 实名认证       

0

主题

3

听众

26

积分

升级  22.11%

该用户从未签到

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

使用道具 举报

您需要登录后才可以回帖 登录 | 注册地址

qq
收缩
  • 电话咨询

  • 04714969085
fastpost

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

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

蒙公网安备 15010502000194号

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

GMT+8, 2026-7-17 18:13 , Processed in 0.425956 second(s), 86 queries .

回顶部