数学建模社区-数学中国

标题: 用C++Builder4.0编写Win 95下的串行异步通信程序 [打印本页]

作者: 韩冰    时间: 2005-1-26 13:06
标题: 用C++Builder4.0编写Win 95下的串行异步通信程序
<>  </P>5 |3 ]( U3 y" P7 ]& q' _
<>姜滨 </P>
; }$ k- ]7 @& N8 ]<>  </P>
2 X9 l0 k* T0 ?1 ^7 M<>  ·串口操纵的基本方法· </P>" k, q5 {' c. y" N6 a
<>  </P>5 o$ b( t9 N! G' `" M; u+ l' }
<>  </P>! e& l" Z- h7 w# p* `
<>  在Win32下,对串口的操作就如同对文件一样打开或关闭,对串行数据的读 </P>- @" f: i% v, t0 g
<>写可在用户定义的读写缓冲区中进行。具体使用的函数为: </P>
+ f0 p/ V" B5 n2 a1 R4 v: ?& t; s/ c<>  </P>4 Q0 u+ `. V. l
<>  首先用CreateFile( )打开通信串口,其中参数lpFileName指向串口逻辑名 </P>7 F( n. b- D4 P% b% }
<>,如“COM1”或“COM2”等,参数dwDesiredAccess定义文件的读写权限,一般 </P>
) z/ v) C8 K( N" ~<>设为GENERIC—READ|GENERIC—WRITE;参数dwShareMode定义资源共享方式,此 </P>5 ^/ s* `' [5 m
<>处必须设为0,为独占方式;lpSecurityAttributes定义安全属性,Win 95下为 </P>+ {: f$ ]' g$ E% V2 `/ J. Q
<>NULL;dwCreationDistribution定义文件创建方式;dwFlagsAndAttributes定义 </P>
) Y5 u- s# @' @8 s" i<>文件属性和标记,应设为FILE—FLAG—OVERLAPPED,表示异步通信方式; </P>
0 q& }7 E1 ^4 }7 j1 ]0 k<>hTemplateFile 指向一个模板文件的句柄,在 Windows 95下为NULL。 </P>/ I& K0 M9 q. w& w) I2 S
<>  </P>
5 U' N& F1 g. R<>  然后用BuildCommDCB( )和SetCommState( )函数通过通信设备控制块DCB( </P>" f4 T& I# V( A6 S. F+ S0 J
<>Device Control Block)设置串口通信参数(如波特率、停止位、数据位、校验 </P>! ^% i: H6 d) d5 f+ p, R7 _: d; h2 }( P2 _
<>位等),其中BuildCommDCB( )中的字符串参数lpDef 定义同DOS命令中MODE的参 </P>
3 Y. e6 {0 K( H7 D& o<>数格式,关于DCB更具体的设置需要根据用户对数据流定义、握手信号及通信控 </P>
2 a% K2 p8 s* }  Z<>制要求具体定义,参见有关Windows技术资料。用GetCommState()可以得到当前 </P>
9 g* l6 J' K1 L7 E8 {<>的DCB参数值。如果需要还可通过SetCommTimeouts()和GetCommTomeouts()重新 </P>
! L5 u0 b# \. Z# i* q, Y<>设置读写的超时参数;读写缓冲区的设置使用SetupComm(),参数dwInQueue和 </P>
+ C) K) [# Q2 }6 V( p! c2 _2 B<>dwOutQueue分别定义为输入和输出缓冲区的大小。 </P>( I" J9 J+ Z' R
<>  </P>
" e( j# e  J+ ^- V0 Y<>  在串口初始化完毕后,还要建立与通信有关的事件对象。一般使用 </P>
4 b+ ~5 \$ q+ d% m% A; R& K<>CreateEvent()函数,它返回一事件句柄,其中参数lpEventAttributes指向安全 </P>
2 m+ W( @( ^% R<>属性结构地址,在Win 95(无安全属性)中为NULL;布尔参数bManualReset 定 </P>
* l* J9 u! n: b<>义事件重置方式,true 表示手工重置,false表示自动重置(相关函数为 </P>
+ U% @) \' D4 o# L<P>SetEvent()和ResetEvent());参数bInitialState定义事件初始状态,true表 </P>
3 D4 _4 T$ P" I6 w' |* N9 ^# g<P>示发信号,否则为不发信号;lpName是为多进程设置的事件名,对于单进程定义 </P>6 b3 ^% ^4 O" m% W' O  j6 F
<P>为NULL。然后用SetCommMask()定义用户程序可监视的通信事件类别。 </P>! p! c7 o$ t0 m- }1 m' F9 |
<P>  </P>
' W1 }1 }" b2 s+ I; o<P>  以上设置完成后,用户程序就可以等待通信事件的产生,一般调用函数 </P>
: V# T! Q0 B3 j, l0 Y2 k* d* C$ b<P>WaitCommEvent()监视通信事件,其中参数lpEvtMask指向产生事件的掩码地址, </P>3 j* L/ T5 d' ^2 p  p! j4 K
<P>用于判断事件产生的性质,lpOverlapped指向重叠结构地址,可简单定义为 </P>
- h( s$ A  e% r% P6 Z<P>NULL。对于串口事件的响应一般有四种方式:查询、同步I/O、异步I/O和事件驱 </P>
3 f  C: A2 z7 H/ U<P>动I/O,需要根据用户不同控制要求而定。查询方式占用较长的计算机时间,同 </P>) x4 s) P1 j9 u* c$ t; L4 a
<P>步I/O方式直到读取完指定的字节数或超时时才返回,容易造成线程阻塞,异步 </P>
% j! y  s8 t- j2 Q5 D9 _( ]' b1 `7 n: `<P>I/O用于后台处理,事件驱动是由系统通知用户程序发生的事件并进行串口操作 </P>3 B! z3 f/ r7 G; ~7 q
<P>。 比较而言事件驱动I/O方式较灵活。 </P>
, f- }/ W3 ]& n* P+ v+ d<P>  </P>
  I0 C, ^! }4 |6 m' S" E" }<P>  当有通信事件产生时,就可用函数ReadFile()和WriteFile()直接对串口缓 </P>
! V. b# x7 ^* n- J<P>冲区进行读写操作了。其中lpBuffer 指向读写缓冲区,nNumberOfBytes为要读 </P>9 v* o5 x/ h) t1 T$ Y
<P>写的字节数,lpNumberOfBytes为实际读写的字节数,lpOverlapped指定同步或 </P>
8 A% u7 i3 N& R% {8 e- z. C<P>异步操作。通信结束后,调用函数CloseHandle()将串口关闭。 </P>% E" w; K" Q5 v* `- _& ]' S1 n
<P>  </P>) L1 }9 r8 n- C" P
<P>  ·应用实例说明· </P>
7 ]* P" s- F9 L% o# M<P>  </P>
" P) E6 ]: z; A6 \4 V+ M: j<P>  </P>
6 U- Z) l3 g5 X; F! l" Y- D) {$ a<P>  使用以上的API函数,笔者给出了简化后的串口初始化的实例。图1为使用C </P>" ^# j5 n8 z! |* s7 i
<P>++ Builder 组件生成的串口通信基本参数设置的界面实例。 </P>
4 j( p6 ]0 C  a2 i. [<P>  </P>
7 J2 ]1 N' S6 v<P>  HANDLE hcom; //定义句柄 </P>( J! i# W7 q) B0 x
<P>  </P>
& m. `1 }) ^  }) k<P>  DCB dcb; </P>5 h2 I7 x. x( r
<P>  </P>
+ d4 E4 k/ t. f" K0 C( @<P>  OVERLAPPED e; //定义重叠结构 </P>8 G! }5 L  |. p
<P>  </P>
3 ^# t0 z1 h7 B/ u  W5 ?2 `<P>  void —fastcall TForm1::OkBtnClick(TObject?Sender) </P>
3 U1 |  w3 q0 \) C<P>  </P>  g) V8 K- o0 B$ ^9 x6 o4 `
<P>  { hcom=CreateFile("COM2",GENERIC—READ|GENERIC—WRITE,0,NULL,OPEN </P>
& S8 U+ }9 L4 J, U! Z9 D7 ]& T<P>—EXISTING, </P>
5 T' G9 A" C# H! s! d<P>FILE—ATTRIBUTE—NORMAL|FILE—FLAG—OVERLAPPED,NULL); //打开通讯口 </P>
9 u, ]* B8 a" z. r" ^<P>  </P>. V4 g/ E3 a6 M3 O% z' i
<P>   BuildCommDCB("9600,O,8,1",&dcb); </P>
, R% O2 n$ ]% T4 i( w<P>  </P>
2 `, c" ~' z! ?; ~4 {( W<P>//第一个字符串参数实际使用时由图1选择后组合,这里仅简单说明其格式 </P>0 x( _0 h- R& O( H" z2 K
<P>  </P>
  c* l2 ]3 m6 \# k0 ^<P>   SetCommState(hcom,&dcb); </P>
$ l, z; p, Y% {2 i1 n<P>  </P>
6 z% b; g6 \7 L8 e, f% W2 r8 W<P>   SetupComm(hcom,512,512);//设置读写缓冲区 </P>- p! |/ {2 T6 Y* R
<P>  </P>; X- H) s/ f( M8 a9 k6 ?3 u
<P>   e.hEvent=CreateEvent(NULL,false,false,NULL); //设置事件 </P>: ^/ F+ Y- e+ z( f
<P>  </P>
* a5 j3 ~- [. R) h<P>   SetCommMask(hcom,EV—RXCHAR| EV—TXEMPTY); //设置事件掩码 </P>
1 t# b1 X$ v/ e  F; U<P>  </P>
: f! S* a& K/ D$ i; t) e4 B<P>   OkBtn-〉Enabled=false;} </P>
作者: cjplove    时间: 2005-1-31 23:43
<>强啊,顶</P>
作者: cjplove    时间: 2005-1-31 23:43
<>不错呢</P>
作者: lhc_mike    时间: 2005-3-9 09:33
又是转的吧?
作者: xtmlj    时间: 2005-3-12 19:24

作者: ai8815    时间: 2010-8-6 11:07
这个程序看着怎么有点怪呢
作者: ai8815    时间: 2010-8-6 11:08
我用VB编过,好像是比c build简单呢   个人觉得




欢迎光临 数学建模社区-数学中国 (http://www.madio.net/) Powered by Discuz! X2.5