QQ登录

只需要一步,快速开始

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

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

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

823

主题

3

听众

4048

积分

我的地盘我做主

该用户从未签到

发帖功臣 元老勋章

跳转到指定楼层
#
发表于 2005-1-26 13:06 |只看该作者 |正序浏览
|招呼Ta 关注Ta
<>  </P>! @& f/ C: W; I9 C: [$ ~3 @. O
<>姜滨 </P>
  T. H" q8 s7 Y# h5 v' n<>  </P>
) g' z2 }7 {& A. L$ w& W, ^<>  ·串口操纵的基本方法· </P>' d! D& F$ W4 I
<>  </P>
5 C% L" X9 _8 Q4 [<>  </P>
6 z" x" s5 K/ d! a* f<>  在Win32下,对串口的操作就如同对文件一样打开或关闭,对串行数据的读 </P>' {1 a; ^- X' U8 l, X
<>写可在用户定义的读写缓冲区中进行。具体使用的函数为: </P>- `9 A5 p, J$ J2 a7 [/ t) U
<>  </P>- l8 f9 d/ [# R1 R& q7 g9 T
<>  首先用CreateFile( )打开通信串口,其中参数lpFileName指向串口逻辑名 </P>& k4 l  k$ |$ c/ Z# a/ n5 m$ b
<>,如“COM1”或“COM2”等,参数dwDesiredAccess定义文件的读写权限,一般 </P>, c& [7 ^" I) d5 y+ b
<>设为GENERIC—READ|GENERIC—WRITE;参数dwShareMode定义资源共享方式,此 </P>
" _, c; d) d* h  ^+ Z, ~- q<>处必须设为0,为独占方式;lpSecurityAttributes定义安全属性,Win 95下为 </P>3 U# h( C4 z, D; g
<>NULL;dwCreationDistribution定义文件创建方式;dwFlagsAndAttributes定义 </P>2 q5 w6 t4 L" E4 \
<>文件属性和标记,应设为FILE—FLAG—OVERLAPPED,表示异步通信方式; </P>
8 i5 w& K% A& H6 _( O<>hTemplateFile 指向一个模板文件的句柄,在 Windows 95下为NULL。 </P>  u! b& b. D0 F) B& q# r) K
<>  </P>
4 Q  w/ s0 J# `" d3 b<>  然后用BuildCommDCB( )和SetCommState( )函数通过通信设备控制块DCB( </P>; e2 ]5 Z& E7 E2 O: u! h) t# H2 C- J
<>Device Control Block)设置串口通信参数(如波特率、停止位、数据位、校验 </P>% t) Z& F2 f4 x/ @2 e, }- Y5 B  D
<>位等),其中BuildCommDCB( )中的字符串参数lpDef 定义同DOS命令中MODE的参 </P>
$ F1 R8 x! @$ P5 h9 ?, b$ c, r+ h<>数格式,关于DCB更具体的设置需要根据用户对数据流定义、握手信号及通信控 </P>
1 `' i$ [8 T2 r& {! r, ]2 ]/ V& N<>制要求具体定义,参见有关Windows技术资料。用GetCommState()可以得到当前 </P>! F4 L6 r) ^; }% C' h+ h
<>的DCB参数值。如果需要还可通过SetCommTimeouts()和GetCommTomeouts()重新 </P>0 c* z+ f) ?% ^, T- ^
<>设置读写的超时参数;读写缓冲区的设置使用SetupComm(),参数dwInQueue和 </P>
1 L9 M9 h( u/ F8 ?9 ^! }" n5 j6 |<>dwOutQueue分别定义为输入和输出缓冲区的大小。 </P>- S3 Y9 u3 H5 {9 k. F) j6 q- c
<>  </P>
/ M) W, b2 O5 l6 w2 Q<>  在串口初始化完毕后,还要建立与通信有关的事件对象。一般使用 </P>
2 N9 i  l) y( X; v<>CreateEvent()函数,它返回一事件句柄,其中参数lpEventAttributes指向安全 </P>
8 r2 p- E0 d9 k, @<>属性结构地址,在Win 95(无安全属性)中为NULL;布尔参数bManualReset 定 </P>/ g# u6 q) a8 F" A$ ^( D+ [
<>义事件重置方式,true 表示手工重置,false表示自动重置(相关函数为 </P>
1 O! g- b& Z' z# R<P>SetEvent()和ResetEvent());参数bInitialState定义事件初始状态,true表 </P>9 {9 d/ }" ?& P3 b' d
<P>示发信号,否则为不发信号;lpName是为多进程设置的事件名,对于单进程定义 </P>
' V* J' t2 Z2 H+ H- @" j* }2 C<P>为NULL。然后用SetCommMask()定义用户程序可监视的通信事件类别。 </P>
$ U' e8 f- k% o$ g! Y* V<P>  </P>% i$ P# |9 a2 ^: I! }- ~/ u
<P>  以上设置完成后,用户程序就可以等待通信事件的产生,一般调用函数 </P>' @5 U( x0 G+ o- ~8 C. y
<P>WaitCommEvent()监视通信事件,其中参数lpEvtMask指向产生事件的掩码地址, </P>
5 T# ^  _8 Y! f* W6 M, y: H2 R<P>用于判断事件产生的性质,lpOverlapped指向重叠结构地址,可简单定义为 </P>
' a; O2 ], j3 Z0 c& b2 @+ z5 x<P>NULL。对于串口事件的响应一般有四种方式:查询、同步I/O、异步I/O和事件驱 </P>
& ?- m* I# U$ `<P>动I/O,需要根据用户不同控制要求而定。查询方式占用较长的计算机时间,同 </P>$ L# y2 \, H9 u- S( C
<P>步I/O方式直到读取完指定的字节数或超时时才返回,容易造成线程阻塞,异步 </P>
: Y; I$ e# q& a9 `' @# @* M<P>I/O用于后台处理,事件驱动是由系统通知用户程序发生的事件并进行串口操作 </P>, g; o3 |6 `! {  T, H
<P>。 比较而言事件驱动I/O方式较灵活。 </P>  C) \. y0 q, r# J
<P>  </P>% l9 h% F8 X2 Z  L6 U8 J
<P>  当有通信事件产生时,就可用函数ReadFile()和WriteFile()直接对串口缓 </P>
8 {# W1 p5 A. G3 [( v<P>冲区进行读写操作了。其中lpBuffer 指向读写缓冲区,nNumberOfBytes为要读 </P>* w, X  k3 \/ B- n
<P>写的字节数,lpNumberOfBytes为实际读写的字节数,lpOverlapped指定同步或 </P>
3 ~6 h% r2 W6 e# v<P>异步操作。通信结束后,调用函数CloseHandle()将串口关闭。 </P>* H5 T" o6 N$ u7 U, \; \* F
<P>  </P>
* u) k6 H1 I  B; Y% c# e<P>  ·应用实例说明· </P>" ]7 s9 s7 \0 J1 V% B
<P>  </P>
+ X# R& r7 ^' v$ g6 J<P>  </P># h; r) H/ g# j  O0 u! F
<P>  使用以上的API函数,笔者给出了简化后的串口初始化的实例。图1为使用C </P>
: R5 O8 ~2 e3 |0 k  h6 c7 S<P>++ Builder 组件生成的串口通信基本参数设置的界面实例。 </P>- e3 N2 `) g9 z
<P>  </P>4 z* i, D2 R3 l$ x9 ]' o
<P>  HANDLE hcom; //定义句柄 </P>
4 v; D; ?2 x6 Q4 L<P>  </P>! a3 R( m: f* s1 k$ t
<P>  DCB dcb; </P>
# b+ y$ Y) ]2 c  T1 o<P>  </P>2 p/ c5 w3 `* f
<P>  OVERLAPPED e; //定义重叠结构 </P>& S% _, _% s1 B% U: n8 b
<P>  </P>, k9 v# _* R0 A8 M- q* `) m$ L9 N& O
<P>  void —fastcall TForm1::OkBtnClick(TObject?Sender) </P>
2 L1 y8 W8 K6 {+ B* B- N<P>  </P>( \" Q( {( M. S, Q7 q8 C
<P>  { hcom=CreateFile("COM2",GENERIC—READ|GENERIC—WRITE,0,NULL,OPEN </P>/ V' f- q6 B& w
<P>—EXISTING, </P>
6 Y( g* l% j0 S0 u<P>FILE—ATTRIBUTE—NORMAL|FILE—FLAG—OVERLAPPED,NULL); //打开通讯口 </P>  [* c4 t0 Y9 T
<P>  </P>
% g1 y- Q1 ?8 T* J<P>   BuildCommDCB("9600,O,8,1",&dcb); </P>
5 g+ y% \0 e% ~7 I<P>  </P>) Q, Y! \4 \* d3 Y/ k  K( b& D3 B
<P>//第一个字符串参数实际使用时由图1选择后组合,这里仅简单说明其格式 </P>
6 c* |' t- a! v<P>  </P>
3 K* ]; k3 m# t- T; l  Z<P>   SetCommState(hcom,&dcb); </P>
2 x" _; y% |8 d<P>  </P>  S% W$ X! E$ n& M3 T! e/ n/ h+ U
<P>   SetupComm(hcom,512,512);//设置读写缓冲区 </P>/ ?% S5 }1 I; N& c6 @  @
<P>  </P>/ c7 x3 N: r4 d* P( T
<P>   e.hEvent=CreateEvent(NULL,false,false,NULL); //设置事件 </P>' j+ y& _7 A" c9 b6 x
<P>  </P>; \9 k2 _+ b& I! J7 b. W* t
<P>   SetCommMask(hcom,EV—RXCHAR| EV—TXEMPTY); //设置事件掩码 </P>2 M( h9 w% S1 \
<P>  </P>4 _5 R" K! T1 B1 A
<P>   OkBtn-〉Enabled=false;} </P>
zan
转播转播0 分享淘帖0 分享分享0 收藏收藏0 支持支持0 反对反对0 微信微信
ai8815 实名认证       

0

主题

3

听众

26

积分

升级  22.11%

该用户从未签到

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

使用道具 举报

ai8815 实名认证       

0

主题

3

听众

26

积分

升级  22.11%

该用户从未签到

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

使用道具 举报

xtmlj        

0

主题

2

听众

95

积分

升级  94.74%

该用户从未签到

新人进步奖

回复

使用道具 举报

lhc_mike        

0

主题

2

听众

52

积分

升级  49.47%

该用户从未签到

新人进步奖

回复

使用道具 举报

cjplove        

0

主题

0

听众

50

积分

升级  47.37%

该用户从未签到

新人进步奖

回复

使用道具 举报

cjplove        

0

主题

0

听众

50

积分

升级  47.37%

该用户从未签到

新人进步奖

回复

使用道具 举报

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

qq
收缩
  • 电话咨询

  • 04714969085
fastpost

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

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

蒙公网安备 15010502000194号

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

GMT+8, 2026-6-14 12:12 , Processed in 0.470603 second(s), 91 queries .

回顶部