win api 读串口(50分)

  • 主题发起人 主题发起人 mouse_ingrief
  • 开始时间 开始时间
M

mouse_ingrief

Unregistered / Unconfirmed
GUEST, unregistred user!
我用win api <br>进行串口读写,首先,打开串口<br>&nbsp; com:=createfile('com2',generic_read or generic_write,0,nil,open_existing,0,0);<br>&nbsp; if com&lt;&gt;invalid_handle_value then<br>&nbsp; begin<br>&nbsp; &nbsp; setupcomm(com,4096,4096);<br>&nbsp; &nbsp; <br>&nbsp; &nbsp; fdcb.BaudRate :=baud_9600;<br>&nbsp; &nbsp; fdcb.Parity :=oddparity;<br>&nbsp; &nbsp; fdcb.StopBits :=onestopbit;<br>&nbsp; &nbsp; fdcb.ByteSize :=8;<br>&nbsp; &nbsp; <br>&nbsp; &nbsp; setcommstate(com,fdcb);<br>&nbsp; &nbsp; <br>&nbsp; &nbsp; tm.ReadIntervalTimeout :=2000;<br>&nbsp; &nbsp; tm.ReadTotalTimeoutMultiplier :=10;<br>&nbsp; &nbsp; tm.ReadTotalTimeoutConstant :=1000;<br>&nbsp; &nbsp; setcommtimeouts(com,tm);<br>&nbsp; end;<br>接着读串口<br>if readFile(com,buffer,1,s,nil) then<br>&nbsp; &nbsp; edit1.Text :=strpas(buffer);<br>&nbsp; closehandle(com);<br>结果是什么都读不出来,为什么。<br>如果是写<br>&nbsp; buffer:='qwertyuiop';<br>&nbsp; if WRITEFILE(com,buffer,10,s,nil) then<br>&nbsp; edit1.Text :=inttostr(s);<br>变量s的值切实是buffer的字节数。这是不是说明已经写到串口了,但是之后再读,<br>还是什么都没有读出来。到底是为什么?什么地方错了?[:(][:(]
 
現在有好多控件用﹐為什么要自己寫呢?
 
用控件吧,读串口要用多线程监视串口状态,自己写比较麻烦
 
控件很麻烦,况且,我只是读一下串口,功能单一,用win api 比较省事儿,直观。<br>
 
&nbsp;如果是读串口,即使只有一个串口也要专门写一个多线程监视串口,因为串口收数据<br>是被动的,你读串口的时候不一定串口就接收到数据了,读数据还是用控件方便。如果<br>一定要用API,可以到大富翁上搜索一下以前的帖子,很多例子的
 
to mouse_ingrief:<br><br>asm<br>out ..<br>end<br><br>这样更省事
 
to knmfkr:<br>&nbsp; &nbsp; Win2k不支持汇编
 
你应该先GetCommState(com,fdcb)<br>然后再进行设置,设置完后再SetCommState(com,fdcb)
 
use DeviceIoControl function;<br>The DeviceIoControl function sends a control code directly to a specified device driver, <br>causing the corresponding device to perform the corresponding operation.
 
to mouse_ingrief:<br><br>Win2k应该支持dll吧!!<br><br>把<br>asm<br>out ..//只要知道地址就可以了!!!<br>end<br>搞成dll就可以了<br>
 
也在学习中。。。你参考一下吧。<br>//打开串口<br>function TMainForm.Opencom:Boolean;<br>var<br>&nbsp; cc:TCOMMCONFIG;<br>&nbsp; Temp:string;<br>begin<br>&nbsp; Temp:='COM'+inttostr(rgcom.ItemIndex+1); &nbsp; &nbsp; &nbsp; &nbsp; // 选择所要打开的COM<br>&nbsp; hComm:=CreateFile(PChar(Temp), GENERIC_READ or GENERIC_WRITE,<br>&nbsp; &nbsp; &nbsp; &nbsp;0, nil, OPEN_EXISTING, 0, 0); // 打开COM<br>&nbsp; if (hComm = INVALID_HANDLE_VALUE) then begin &nbsp;// 如果COM 未打开<br>&nbsp; &nbsp; MessageBox (0, '打开通信端口错误!!','',MB_OK);<br>&nbsp; &nbsp; Result:=False;<br>&nbsp; &nbsp; exit;<br>&nbsp; end;<br>&nbsp; ShowMessage('成功打开端口'+temp);<br><br>&nbsp; GetCommState(hComm,cc.dcb); // 得知目前COM 的状态<br>&nbsp; cc.dcb.BaudRate:=CBR_9600; // 设置波特率为9600<br>&nbsp; cc.dcb.ByteSize:=8; &nbsp;// 字节为 8 bit<br>&nbsp; cc.dcb.Parity:=EVENPARITY; // Parity 为 None<br>&nbsp; cc.dcb.StopBits:=TWOSTOPBITS; // 2 个Stop bit<br><br>&nbsp; if not SetCommState(hComm, cc.dcb) then begin// 设置COM 的状态<br>&nbsp; &nbsp; MessageBox (0, '通信端口设置错误!!!','',MB_OK);<br>&nbsp; &nbsp; CloseHandle(hComm);<br>&nbsp; &nbsp; Result:=False;<br>&nbsp; &nbsp; exit;<br>&nbsp; end;<br>&nbsp; Result:=True;<br>end;<br>//发命令<br>if EdtSend.Text='' then<br>&nbsp; &nbsp; &nbsp; exit;<br>&nbsp; &nbsp; if (hComm=0) then exit; //检查Handle值<br>// &nbsp;Temp:=EdiSend.Text ;//取得传送的字符串<br>&nbsp; //实际的传送动作<br>// &nbsp;WriteFile(hComm,PChar(Temp)^,Length(Temp), lrc, nil); // 送出数据<br>&nbsp; &nbsp; StrToBuffer(EdtSend.Text);<br>&nbsp; &nbsp; if not WriteFile(hComm,buffer,nn,nBytesRead,nil)then<br>&nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; showmessage('write error');<br>&nbsp; &nbsp; &nbsp; exit;<br>&nbsp; &nbsp; end;<br>&nbsp; &nbsp; Sleep(sleepTime);<br>&nbsp; &nbsp; temp:='';<br>&nbsp; &nbsp; for i:=1 to nn do<br>&nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; temp:=temp+copy(EdtSend.Text,i*2-1,2)+' ';<br>&nbsp; &nbsp; end;<br>&nbsp; &nbsp; reRes.Lines.Add (SHead+' '+temp);<br>&nbsp; &nbsp; ReceiveData;<br><br>&nbsp; &nbsp; EdtSend.SetFocus;<br>&nbsp; end<br>&nbsp; else<br>&nbsp; &nbsp; showmessage('端口没有打开!');<br>//收命令<br>// 接收COM 的数据接收COM 的数据,并将数据显示于Memo1 上<br>procedure TMainForm.ReceiveData;<br>var<br>&nbsp; inbuff: array[0..2047] of Byte;<br>&nbsp; nBytesRead, dwError:LongWORD ;<br>&nbsp; cs:TCOMSTAT;<br>&nbsp; sTmp:string;<br>&nbsp; i:integer;<br>begin<br>&nbsp; &nbsp;ClearCommError(hComm,dwError,@CS); &nbsp;//取得状态<br>&nbsp; &nbsp; &nbsp; &nbsp;// 数据是否大于我们所准备的Buffer<br>&nbsp; &nbsp;if cs.cbInQue &gt; sizeof(inbuff) then begin<br>&nbsp; &nbsp; &nbsp;PurgeComm(hComm, PURGE_RXCLEAR); &nbsp;// 清除COM 数据<br>&nbsp; &nbsp; &nbsp;exit;<br>&nbsp; &nbsp;end;<br>&nbsp; fillchar(inbuff,sizeof(inbuff),0);<br>&nbsp; &nbsp;ReadFile(hComm, inbuff,cs.cbInQue,nBytesRead,nil); // 接收COM 的数据<br><br>&nbsp; &nbsp;//转移数据到变量中<br>&nbsp; &nbsp;sTmp:='';<br>&nbsp; for i:=1 to cs.cbInQue do &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //*******?<br>&nbsp; begin<br>&nbsp; &nbsp; sTmp:=sTmp+IntToHex(inbuff[i-1],2)+' ';<br>&nbsp; end;<br><br>&nbsp; reRes.Lines.Add (RHead+' '+sTmp); <br>&nbsp;<br><br>end;<br><br>
 
还是使用MSCOMM控件最方便!
 
建议用控件,比较方便,而且直观,容易理解。<br>用api,麻烦自己不说,以后出现什么异常的时候也难查找原因。
 
这种问题还是用控件好些,别人已经封装过的东西我们还要重复一遍本身就是浪费,况且我<br>们自己做的不见得比别人做的更好!比如,MSCOMM就是微软封装的。
 
多人接受答案了。
 

Similar threads

I
回复
0
查看
789
import
I
I
回复
0
查看
652
import
I
S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
后退
顶部