利用API函数进行串行通信(50分)

  • 主题发起人 主题发起人 MR.ZHANG
  • 开始时间 开始时间
M

MR.ZHANG

Unregistered / Unconfirmed
GUEST, unregistred user!
用DELPHI编工控软件,利用WINDOWS API 函数控制RS-232串口通信。
 
我作过一个VC的类,里面完全用API写的,要吗?
 
MR.ZHANG,
写的差不多给我份(看不懂vc)
 
sheepishest@china.com
thanx
 
其实用VCL控件很不错,我们实验室里就是用的一个COMM控件,不论是稳定性还是兼容
性都相当的棒!而且用他和我们原来在DOS下编的终端(使用标准RS-232通讯)通讯
简单易行,我们的产品已经商品化了,用户没有反应什么错误,如果要的话,我给你
Mail一个去:)
 
mikecool:
能给我一个吗?thanks a lot
xiaoflyfly@263.net
 
其实用API函数操作串口是很方便的,主要有以下几个步骤:
1、用CreateFile('COM1',GENERIC_READ or GENERIC_WRITE,
0,nil,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);打开串口。
2、利用GetCommState(hCom,dcb)和SetCommState(hCom,dcb)设置
串口状态。得用SetCommTimeouts设置串中的读写超时。
3、然后就可以用WriteFile和ReadFile对串口进行读写了。
4、最后当然是用 CloseHandle(hCom)来关闭串口了。
本人曾经编过一个用串口以自己约定的方式进行通讯的程序,需要
的话可以问我要,只是别觉得写得太差。
 
转贴!这是triton大侠帮我的,好东西不敢独享!
Windows操作系统的机制禁止应用程序直接访问计算机硬件,但它为程序员提供了一系列的标准API函数,
使得应用程序的编制更加方便并且免除了对有关硬件的调试麻烦。在Windows95/NT中,原来Windows3.X的
WM_COMMNOTIFY消息已被取消,操作系统为每个通信设备开辟了用户可定义大小的读/写缓冲区,数据进出通信
口均由操作系统后台完成,应用程序只需对读/写缓冲区操作即可。WIN95/NT中几个常用的串行通信操作函数如下:

   CreatFile  : 打开串行口
   CloseHandle : 关闭串行口
   SetupComm  : 设置通信缓冲区的大小
   ReadFile   : 读串口操作
   WriteFile  : 写串口操作
   SetCommState : 设置通信参数
   GetCommState : 获取默认通信参数
   ClearCommErro: r清除串口错误并获取当前状态
   除上述几个函数外,还要经常用到一个重要的记录DCB(设备控制块)。DCB中记录有可定义的串行口参数,设置串行口参数时必须先用GetCommState函数将系统默认值填入DCB控制块,然后才可把用户想改变的自定义值设定。在WIN95/NT中进行串行通信除了解基本的通信操作函数外,还要掌握多线程编程。线程是进程内部执行的路径,是操作系统分配CPU时间的基本实体。每个进程都由单线程开始完成应用程序的执行。串行通信需要利用多线程技术实现,其主要的处理逻辑可以表述如下:进程一开始先由主线程做一些必要的初始化工作,然后主线程根据需要在适当时候建立通信监视线程监视通信口,当指定的串行口事件发生时,向主线程发送WM_COMMNOTIFY消息(由于WIN95取消了WM_COMMNOTIFY消息,因此必须自己创建),主线程对其进行处理。若不需要WM_COMMNOTIFY消息,则主线程终止通信监视线程。多线程同时执行,将会引起对共享资源的冲突。为避免冲突,就要用同步多线程对共享资源进行访问。WIN95提供了许多保持线程同步的方法,笔者采用创建事件对象来保持线程同步。通过CraeteEvent()创建事件对象,使用SetEvent() 或PulseEvent()函数将事件对象设置成信号同步。在应用程序中,利用WaitSingleObject() 函数等待同步的触发,等到指定的事件被其它线程设置为有信号时,才继续向下执行程序。

Delphi下的具体实现方法
  Delphi的强大功能和支持多线程的面向对象编程技术,使得实现串行通信非常简单方便。它通过调用外部的API函数来实现,主要步骤如下:首先,利用CreateFile函数打开串行口,以确定本应用程序对此串行口的占有权,并封锁其它应用程序对此串口的操作;其次,通过GetCommState函数填充设备控制块DCB,再通过调用SetCommState函数配置串行口的波特率、数据位、校验位和停止位。然后,创建串行口监视线程监视串行口事件。在此基础上就可以在相应的串口上操作数据的传输;最后,用CloseHandle函数关闭串行口。具体的程序如下,本程序用Delphi3.0编制在Win95环t境下调试通过,已投入实际应用中,供广大读者参考。
程序:
unit comdemou;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs;
const
Wm_commNotify=Wm_User+12;
type
TForm1 = class(TForm)
procedure FormCreate(Sender: TObject);
private
Procedure comminitialize;
Procedure MsgcommProcess(Var Message:Tmessage); Message Wm_commnotify;
{ Private declarations }
public
{ Public declarations }
end;
// 线 程 声 明
TComm=Class(TThread)
protected
procedure Execute;override;
end;
var
Form1: TForm1;
hcom,Post_Event:Thandle;
lpol:Poverlapped;
implementation
{$R *.DFM}
Procedure TComm.Execute; // 线 程 执 行 过 程
var
dwEvtMask:Dword;
Wait:Boolean;
Begin
fillchar(lpol,sizeof(toverlapped),0);
While True do Begin
dwEvtMask:=0;
Wait:=WaitCommEvent(hcom,dwevtmask,lpol); // 等 待 串 行 口 事 件;
if Wait Then Begin
waitforsingleobject(post_event,infinite); // 等 待 同 步 事 件 置 位;
resetevent(post_event); // 同 步 事 件 复 位;
PostMessage(Form1.Handle,WM_COMMNOTIFY,0,0);// 发 送 消 息;
end;
end;
end;

procedure Tform1.comminitialize; // 串 行 口 初 始 化
var
lpdcb:Tdcb;
Begin
hcom:=createfile('com2',generic_read or generic_write,0,nil,open_existing,
file_attribute_normal or file_flag_overlapped,0);// 打 开 串 行 口
if hcom=invalid_handle_value then
else
setupcomm(hcom,4096,4096); // 设 置 输 入, 输 出 缓 冲 区 皆 为4096 字 节
getcommstate(hcom,lpdcb); // 获 取 串 行 口 当 前 默 认 设 置
lpdcb.baudrate:=2400;
lpdcb.StopBits:=1;
lpdcb.ByteSize:=8;
lpdcb.Parity:=EvenParity; // 偶 校 验
Setcommstate(hcom,lpdcb);
setcommMask(hcom,ev_rxchar);
// 指 定 串 行 口 事 件 为 接 收 到 字 符;
end;
Procedure TForm1.MsgcommProcess(Var Message:Tmessage);
var
Clear:Boolean;
Coms:Tcomstat;
cbNum,ReadNumber,lpErrors:Integer;
Read_Buffer:array[1..100]of char;
Begin
Clear:=Clearcommerror(hcom,lpErrors,@Coms);
if Clear Then Begin
cbNum:=Coms.cbInQue;
ReadFile(hCom,Read_Buffer,cbNum,ReadNumber,lpol);
// 处 理 接 收 数 据
SetEvent(Post_Event); // 同 步 事 件 置 位
end;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
comminitialize;
post_event:=CreateEvent(nil,true,true,nil); // 创 建 同 步 事 件;
Tcomm.Create(False); // 创 建 串 行 口 监 视 线 程;
end;
end.

 
mikecool:
能mail一份给我吗?thanks!
zw1998@sina.com.cn
 
mikecool我也要,给我送过来吧,哈哈
wind@linux.shtdu.edu.cn
 
如果能够下载的,可以到我的网站上下载

地址是
http://202.120.168.215/vcl/SPComm.zip

呵呵,我试试看给大家寄信,因为我们学校的信箱不好
常常被服务器打回来:)
如果没有收到信的话,我会给你再发一次:)
 
mikecool: 能mail一份给我吗? please quickly!!!thanks a lot!
whqiu24@163.net
 
mikecool:
能给我一个吗?thanks a lot,我急需com资料,多谢!
zjeijf@163.net
 
请发;wzbhu@263.net
 
zcy:
送给我一份吧,我现在想要一个用自己约定方式通讯的串口程序。
 
me too:Tim@edu.21cn.com
 
whpjyj,信已发出了,如果没收到,请通知我再发一次。
 
我也要!
peterwangzy@263.net
 
Crane:
我要!
能不能e-mail给我;
<a href='mailto:phf110@yeah.net'>phf110@yeah.net</a>
我会感激一辈子。
最好有你用到的API函数的说明!
 
zcy:
我现在在写一个要用到上位机(管理系统)和下位机(单片机)通信的软件。
(零调制解调器)
想用API实现希望老兄能给我一份!
<a href='mailto:phf110@yeah.net'>phf110@yeah.net</a>
谢谢!
 
后退
顶部