通讯串口端口的I/O地址怎么得到呢? 我要的是通讯端口的I/O地址,比如说:COM1,COM2,COM3等等的I/O地址。例如:COM1的I/O地址可能是$3f8, COM2的I/O地址可能是$2f8等,但如何用编程得到呢? 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 C中用_inp(),_outp().delphi中 i dont know WIN2000是不能直接用端口地址操作串口的 to Cgll20: 您说得对,不过我是在98中用。您知道怎么取吗?用汇编也行啊! 通过读取计算机的注册表来获取串行口的I/O地址。串行口在注册表的HKEY_LOCAL_MACHINE\hardware\devicemap\serialcomm中 你要直接和i/o打交道么?这个在w2k里就是得到了地址好象也比较困难看看一个离子 基于Windows 95/NT的串行通信机制 Windows操作系统禁止应用程序直接访问计算机硬件,但它为程序员提供了一系列标准API函数,使得应用程序的编制更加方便,并且免除了对有关硬件调试的麻烦。在Windows 95/NT中,原来Windows 3.X的WM_COMMNOTIFY消息已被取消,操作系统为每个通信设备开辟了用户可定义大小的读/写缓冲区,数据进出通信口均由操作系统后台完成,应用程序只需对读/写缓冲区操作即可。Windows 95/NT中几个常用的串行通信操作函数如下:@@0474300.JPG;表1@@ 除上述几个函数外,还要经常用到一个重要的记录DCB(设备控制块)。DCB中记录有可定义的串行口参数,设置串行口参数时必须先用GetCommState函数将系统默认值填入DCB控制块,然后才可设定用户想改变的自定义值。 在Windows 95/NT中实现串行通信除了要了解基本的通信操作函数外,还要掌握多线程编程。线程是进程内部执行的路径,是操作系统分配CPU时间的基本实体,每个进程都由单线程开始完成应用程序的执行。串行通信需要利用多线程技术实现,其主要的处理逻辑可以表述如下:进程一开始先由主线程做一些必要的初始化工作,然后主线程根据需要在适当时候建立线程监视通信口,当指定的串行口事件发生时,向主线程发送WM_COMMNOFY消息(由于Windows 95取消了WM_COMMNOTIFY消息,因此程序员必须自己创建),主线程对其进行处理。若不需要WM_COMMNOTIFY消息,则主线程终止通信监视线程。 多线程同时执行可能会引起对共享资源的冲突,为避免冲突,需要用同步多线程对共享资源进行访问。Windows 95提供了许多保持线程同步的方法,笔者采用创建事件对象来保持线程同步。通过CreateEvent()创建事件对象,使用SetEvent()或PulseEvent()函数将事件对象设置成信号同步。在应用程序中,利用WaitSingleObject()函数等待同步的触发,等到指定的事件被其它线程设置为有信号时,才继续向下执行程序。 Delphi下的具体实现方法 Delphi的强大功能和支持多线程的面向对象编程技术,使得实现串行通信非常简单方便。它通过调用外部的API函数来实现,主要步骤如下。 1. 利用CreateFile函数打开串行口,以确定本应用程序对此串行口的占有权,并封锁其它应用程序对此串口的操作; 2. 通过GetCommState函数填充设备控制块DCB,再通过调用SetCommState函数配置串行口的波特率、数据位、校验位和停止位; 3. 创建串行口监视线程监视串行口事件,在此基础上就可以在相应的串口上操作数据的传输; 4. 用CloseHandle函数关闭串行口(具体的程序如下)。本程序用Delphi3.0编写,在Windows 95环境下调试通过,已投入实际应用中,供广大读者参考。 程序: 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. NO,NO, 首先感谢各位。不过:1、我不是要串口号,串口号我有,注册表中没有串口Port的I/O地址。2、我要的是串口Port的I/O地址,不是通讯过程。 我想应该可以吧!想想设备管理器如何得到设备资源的,朝设备管理器用的API的方向考虑吧! to BlueTrees: 能否说说设备管器用的有哪些API呢? 最近机器坏了,重新安装了,MSDN还没有装,不过我想应该很容易找到了,搜索PlagPlay,Deivec,之类的关键词,应该可以找到的吧! 关于动态数组越界的2个问题? 怎么扫描指定的IP段啊 DELPHI纯API实现的部分透明时钟 网络摄像头的地址 要在程序中实现传送邮件的功能,把数据发送到指定邮箱和接收,怎么做 删除记录出错! 人气好差呀,无聊散分。。。 用Delphi,在Excel里对图片的操作(高分相送!!!) 我的数据库中有一个完全格式的时间字段'2002-09-16 13:20:55' 可是在DBGrid中只显示2002-09-16,请问各位大侠如何才能将该字段显示完全 看到斑竹zswang的代码风格,不禁想问 为什么我的showhint没有用呢? 啊!在线急!急!急!请各位帮帮忙!
串行口在注册表的HKEY_LOCAL_MACHINE\hardware\devicemap\serialcomm中
看看一个离子
基于Windows 95/NT的串行通信机制
Windows操作系统禁止应用程序直接访问计算机硬件,但它为程序员提供了一系列标
准API函数,使得应用程序的编制更加方便,并且免除了对有关硬件调试的麻烦。在Windo
ws 95/NT中,原来Windows 3.X的WM_COMMNOTIFY消息已被取消,操作系统为每个通信设备
开辟了用户可定义大小的读/写缓冲区,数据进出通信口均由操作系统后台完成,应用程序
只需对读/写缓冲区操作即可。Windows 95/NT中几个常用的串行通信操作函数如下:
@@0474300.JPG;表1@@
除上述几个函数外,还要经常用到一个重要的记录DCB(设备控制块)。DCB中记录有可
定义的串行口参数,设置串行口参数时必须先用GetCommState函数将系统默认值填入DCB
控制块,然后才可设定用户想改变的自定义值。
在Windows 95/NT中实现串行通信除了要了解基本的通信操作函数外,还要掌握多线
程编程。线程是进程内部执行的路径,是操作系统分配CPU时间的基本实体,每个进程都由
单线程开始完成应用程序的执行。串行通信需要利用多线程技术实现,其主要的处理逻辑
可以表述如下:进程一开始先由主线程做一些必要的初始化工作,然后主线程根据需要在
适当时候建立线程监视通信口,当指定的串行口事件发生时,向主线程发送WM_COMMNO
FY消息(由于Windows 95取消了WM_COMMNOTIFY消息,因此程序员必须自己创建),主线程
对其进行处理。若不需要WM_COMMNOTIFY消息,则主线程终止通信监视线程。
多线程同时执行可能会引起对共享资源的冲突,为避免冲突,需要用同步多线程对共
享资源进行访问。Windows 95提供了许多保持线程同步的方法,笔者采用创建事件对象来
保持线程同步。通过CreateEvent()创建事件对象,使用SetEvent()或PulseEvent()函数
将事件对象设置成信号同步。在应用程序中,利用WaitSingleObject()函数等待同步的触
发,等到指定的事件被其它线程设置为有信号时,才继续向下执行程序。
Delphi下的具体实现方法
Delphi的强大功能和支持多线程的面向对象编程技术,使得实现串行通信非常简单方
便。它通过调用外部的API函数来实现,主要步骤如下。
1. 利用CreateFile函数打开串行口,以确定本应用程序对此串行口的占有权,并封锁
其它应用程序对此串口的操作;
2. 通过GetCommState函数填充设备控制块DCB,再通过调用SetCommState函数配置串
行口的波特率、数据位、校验位和停止位;
3. 创建串行口监视线程监视串行口事件,在此基础上就可以在相应的串口上操作数
据的传输;
4. 用CloseHandle函数关闭串行口(具体的程序如下)。本程序用Delphi3.0编写,在
Windows 95环境下调试通过,已投入实际应用中,供广大读者参考。
程序:
unit comdemou;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialo
gs;
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_exist
ing,
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.
2、我要的是串口Port的I/O地址,不是通讯过程。