如何监测接在串口的一个电器设备的开关信号?(100分)

  • 主题发起人 主题发起人 qj_chen
  • 开始时间 开始时间
Q

qj_chen

Unregistered / Unconfirmed
GUEST, unregistred user!
&nbsp; &nbsp;我想在串口接一个电器设备的开关信号,用来自动监测设备的开或关的状态,<br>请教我该将开关信号接在串口的哪一只脚?监测串口的哪个通信事件?能提供几段<br>代码供我学习吗?
 
串口是不能直接接电器设备的开关信号的。应该用并口。你可以用iocomp,portlib之类的控件<br>来控制,9x下也可直接写端口程序控制。你可以查一查以前的贴子有代码的。<br>
 
建议加个单片机到串行口,用串口协议来控制,兼容性好点,又可靠
 
我也想学学<br>帮你顶一下
 
&nbsp; &nbsp;我是这样设想的,用CreatFike()函数打开串口,用SetCommMask()函数指定串口事件<br>类型,当电器设备向串口的某一只脚(如RXD或DTR或DSR或RTS或CTS或DELL)发送一个电平<br>变化信号时(从高电平到低电平或从低电平到高电平),向系统发一个消息。我的设想不<br>知是否行得通?如果可行,应该使用串口的哪一只脚?在SetCommMask()函数中指定那种类<br>型的事件?(EV_BREAK或EV_RING或EV_RLSD等等)怎样写代码?<br>&nbsp; &nbsp; 请不吝赐教。<br>
 
你查查串口输出信号格式就知道不可能直接使用了。
 
谢谢诸位了,我学到不少东西。既然不能直接使用串口,那能不能变通一下,让串口自己<br>发数据给自己,也就是从TXD脚经过外接的开关到RXD脚,不断的发送数据。一旦接收到数<br>据就向系统发出消息。这样不知行否?串口的接收和发送是否能同时进行?怎样才能让串<br>口不断的发送数据?请指教。<br>
 
&nbsp; &nbsp;你的设想是可以的,计算机串口九针定义:<br>&nbsp; &nbsp; 1.DCD &nbsp;载波检测<br>&nbsp; &nbsp; 2.RXD &nbsp;接收数据<br>&nbsp; &nbsp; 3.TXD &nbsp;发送数据<br>&nbsp; &nbsp; 4.DTR &nbsp;数据终端就绪<br>&nbsp; &nbsp; 5.GND &nbsp;信号地<br>&nbsp; &nbsp; 6.DSR &nbsp;数据设备就绪<br>&nbsp; &nbsp; 7.RTS &nbsp;请求发送<br>&nbsp; &nbsp; 8.CTS &nbsp;清除发送<br>&nbsp; &nbsp; 9.RI &nbsp; 振铃指示<br>&nbsp; &nbsp; 使用SetCommMask(...,ev_rxchar)将串口事件设为接收,创建一线程监视此事件,<br>&nbsp; &nbsp;如有一个电平变化信号发送到RXD,便发送一个消息,给其他线程处理。<br>
 
看看是否可行?<br>unit Unit1;<br><br>interface<br><br>uses<br>&nbsp; Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,<br>&nbsp; Dialogs, StdCtrls;<br><br>const<br>&nbsp; WM_CommNotify=WM_User+100; &nbsp;<br><br>type<br>&nbsp; TForm1 = class(TForm)<br>&nbsp; &nbsp; procedure FormCreate(Sender: TObject);<br>&nbsp; private<br>&nbsp; &nbsp; { Private declarations }<br>&nbsp; &nbsp; procedure Comminitialize;<br>&nbsp; &nbsp; procedure MsgCommProcess(var Message:Tmessage); Message Wm_CommNotify;<br>&nbsp; public<br>&nbsp; &nbsp; { Public declarations }<br>&nbsp; end;<br>&nbsp; TComm=Class(TThread)<br>&nbsp; protected<br>&nbsp; &nbsp; procedure Execute;override;<br>&nbsp; end;<br><br>var<br>&nbsp; Form1: TForm1;<br><br>implementation<br><br>{$R *.dfm}<br>var<br>&nbsp; hCom,Post_Event:THandle;<br>&nbsp; lpOL:POverlapped;<br><br>procedure TForm1.Comminitialize; //串行口初始化;<br>var<br>&nbsp; lpDCB:TDcb;<br>begin<br>&nbsp; hCom:=CreateFile('COM2',Generic_Read or Generic_Write,0,nil,Open_Existing,<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;File_Attribute_Normal or File_Flag_Overlapped,0); //打开串行口;<br>&nbsp; if hCom=Invalid_handle_Value then<br>&nbsp; else &nbsp;begin<br>&nbsp; &nbsp; setupcomm(hcom,4096,4096); //设置输入,输出缓冲区皆为4096字节;<br>&nbsp; &nbsp; getcommstate(hcom,lpdcb); &nbsp;//获取串行口当前默认设置;<br>&nbsp; &nbsp; lpDCB.baudrate:=2400;<br>&nbsp; &nbsp; lpDCB.StopBits:=1;<br>&nbsp; &nbsp; lpDCB.ByteSize:=8;<br>&nbsp; &nbsp; lpDCB.Parity:=EvenParity; &nbsp;//偶校验;<br>&nbsp; &nbsp; SetCommState(hcom,lpdcb);<br>&nbsp; &nbsp; SetCommMask(hcom,ev_rxchar);//指定串行口事件为接收到字符;<br>&nbsp; end;<br>end;<br><br>procedure TForm1.FormCreate(Sender: TObject);<br>begin<br>&nbsp; Comminitialize;<br>&nbsp; Post_Event:=CreateEvent(nil,true,true,nil); //创建同步事件;<br>&nbsp; TComm.Create(False); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;//创建串行口监视线程;<br>end;<br>{ TComm }<br><br>procedure TComm.Execute;<br>var<br>&nbsp; dwEvtMask:Dword;<br>&nbsp; Wait:Boolean;<br>begin<br>&nbsp; FillChar(lpOL,SizeOf(TOverlapped),0);<br>&nbsp; while True do<br>&nbsp; begin<br>&nbsp; &nbsp; dwEvtMask:=0;<br>&nbsp; &nbsp; Wait:=WaitCommEvent(hcom,dwevtmask,lpol); &nbsp; &nbsp; &nbsp;//等待串行口事件;<br>&nbsp; &nbsp; if Wait then<br>&nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; WaitForSingleObject(Post_Event,INFINITE); &nbsp; &nbsp;//等待同步事件置位;<br>&nbsp; &nbsp; &nbsp; ResetEvent(Post_Event); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;//同步事件复位;<br>&nbsp; &nbsp; &nbsp; PostMessage(Form1.Handle,WM_COMMNOTIFY,0,0); //发送消息;<br>&nbsp; &nbsp; end;<br>&nbsp; end;<br>end;<br><br>procedure TForm1.MsgCommProcess(var Message:Tmessage);<br>begin<br>&nbsp; ShowMessage('......'); //设备打开或关闭;<br>end;<br><br>end.
 
如果你的这个串口还用来和这个下位机通讯的话,<br>那么他上电的时候发一报文你就可以知道了。<br>如果这个串口只是用来检测该装置是不是开了<br>那么你只要把他的RTS和电源中一个电平相当的<br>地方连起来,当他上电的时候你就可以检测到RTS信号了。
 
按cook先生的提示检测RTS的电平,直接用“御键飞天”提供的程序行吗?是否需要将<br>&nbsp; SetCommMask(hcom,ev_rxchar);//指定串行口事件为接收到字符;<br>改为指定接收串行口的其他事件?请提供一些例子吧,我对串口编程一无所知啊!<br>
 
我没有具体做过,只是提供给你一个解决办法<br>因为我用串口的时候都是用全双工,rts是半双工的时候用的到,<br>其实最简单的还是下位机打开的时候发一报文
 

Similar threads

D
回复
0
查看
2K
DelphiTeacher的专栏
D
D
回复
0
查看
2K
DelphiTeacher的专栏
D
后退
顶部