在线求助,com口的问题(来者有分)(100分)

  • 主题发起人 主题发起人 xxljishiben
  • 开始时间 开始时间
X

xxljishiben

Unregistered / Unconfirmed
GUEST, unregistred user!
我用 api 函数写了个com 口的读函数,<br>出现如下问题:<br>如果电脑刚刚启动后启动程序, <br> &nbsp; &nbsp;Readsuccess := ReadFile(m_hComm, &nbsp; &nbsp; &nbsp; &nbsp; //操作句柄<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;bStr[0], &nbsp; &nbsp; &nbsp; &nbsp;//数据缓冲区<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;NumberOfBytesToRead, &nbsp; //要读取的字节长度<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;iReadNum, &nbsp; &nbsp; &nbsp; &nbsp;//实际读取的字节长度<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;nil); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //overlapped buffer<br> &nbsp;则上述 api 函数长时间不返回,程序无响应。<br>如果我先用串口 调试工具打开某串口然后再关闭, 然后用我的程序调试,就能一直保持正常运行(不论我的程序开闭多少次,只要不重起电脑,就能正常运行)。<br>请各位朋友帮忙指点,或者指出我可能的错误。<br>来者有分
 
你要com有个初化呀
 
com 初始化已有,如下,不知是不是不全面或者其他的,用串口调试打开一次之后就能用了~! <br>constructor TSerialControl.Create; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;//TSerialControl类对象构造方法实现区<br>begin<br> &nbsp; &nbsp;inherited Create; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //执行父类的Create方法<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;//以下为变量初始化<br> &nbsp; &nbsp;m_hComm := DWord(-1); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //把-1赋给串口操作句柄,并声明-1为DWord类型<br> &nbsp; &nbsp;m_SerialSet.BaudRate := CBR_9600; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //波特率默认值为9600<br> &nbsp; &nbsp;m_SerialSet.ByteSize := 8; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;//数据位默认值为8<br> &nbsp; &nbsp;m_SerialSet.Parity := NOPARITY; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //校验方式默认值为无<br> &nbsp; &nbsp;m_SerialSet.StopBits := ONESTOPBIT; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;//停止位默认值1<br> &nbsp; &nbsp;m_SerialSet.TimeOuts.ReadTotalTimeoutMultiplier := 0; //超时<br> &nbsp; &nbsp;m_SerialSet.TimeOuts.ReadTotalTimeoutConstant := 0; &nbsp; //超时<br> &nbsp; &nbsp;m_SerialSet.TimeOuts.ReadIntervalTimeout := MAXDWORD; //超时<br> &nbsp; &nbsp;m_Opened := FALSE; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //串口打开结果默认值为FALSE<br>end;
 
你这叫什么初始化啊?CREATE呢?我怎么没看到啊 ?
 
创建<br> &nbsp; &nbsp;Fm_handle := CreateFile(<br> &nbsp; &nbsp; &nbsp;PChar(Fm_sCom),<br> &nbsp; &nbsp; &nbsp;GENERIC_READ or GENERIC_WRITE,<br> &nbsp; &nbsp; &nbsp;0,<br> &nbsp; &nbsp; &nbsp;nil,<br> &nbsp; &nbsp; &nbsp;OPEN_EXISTING,<br> &nbsp; &nbsp; &nbsp;FILE_FLAG_OVERLAPPED,<br> &nbsp; &nbsp; &nbsp;0);<br>读<br> &nbsp; &nbsp; &nbsp;if not ReadFile(Fm_handle, pData[0], DataLen, DWord(iReceive), @Overlapped) and<br> &nbsp; &nbsp; &nbsp; &nbsp;(GetLastError &lt;&gt; ERROR_IO_PENDING) then<br> &nbsp; &nbsp; &nbsp; &nbsp;abort;<br>写<br> &nbsp; &nbsp; &nbsp;if not WriteFile(Fm_handle, pData[0], DataLen, dWord(iWrite), @Overlapped) and<br> &nbsp; &nbsp; &nbsp; &nbsp;(GetLastError &lt;&gt; ERROR_IO_PENDING) then<br> &nbsp; &nbsp; &nbsp; &nbsp;abort;
 
to 小虾米爱吃鱼, :<br>我所说的初始化指的是使用Creatfile函数之前的配置。<br>请看清题意,我只有在刚刚开机的时候,程序运行出错,如果没有creatfile函数, 串口不可能打开的<br>function TSerialControl.OpenSerial(CommPort:string;ShareMode:Boolean=FALSE):Integer;<br>var<br> &nbsp;sCommPort:String;<br> &nbsp;dwShareMode:DWord;<br>begin<br> &nbsp;sCommPort:='//./'+CommPort; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;//串口号由函数参数CommPort传递而来<br><br> &nbsp;if self.m_Opened Then &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //串口已被打开(被本程序打开过)<br> &nbsp;begin<br> &nbsp; &nbsp;Result:=-2;<br> &nbsp; &nbsp;Exit;<br> &nbsp;end;<br><br> &nbsp;if ShareMode Then &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //串口是否采用共享方式打开<br> &nbsp;begin<br> &nbsp; &nbsp;dwShareMode:=FILE_SHARE_READ;<br> &nbsp;end else<br> &nbsp;begin<br> &nbsp; &nbsp;dwShareMode:=0;<br> &nbsp;end;<br><br> &nbsp;m_hComm := CreateFile( &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;//创建文件(串口),取得操作句柄<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;PChar(sCommPort), &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //文件名称<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;//'//./COM10',<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;GENERIC_READ or GENERIC_WRITE, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;//操作方式(读或写)<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;dwShareMode, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;//共享方式<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;nil, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;//SD<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;OPEN_EXISTING, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;//文件创建方法<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;FILE_ATTRIBUTE_NORMAL, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;//文件属性<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;0); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //handle to template file<br><br> &nbsp;if( m_hComm = INVALID_HANDLE_VALUE ) then &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //串口打开失败<br> &nbsp;begin<br> &nbsp; &nbsp;Result:=-1;<br> &nbsp; &nbsp;Exit;<br> &nbsp;end;<br><br> &nbsp;self.m_Opened:=True; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;//设置串口打开标志<br> &nbsp;Result:=0; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;//成功返回<br>end;
 
我自己认为问题应该出在前期各个参数的配置上, 或者,我的配置有遗漏, <br>我程序copy了我师兄的正常运行的unit单元,单元内主要定义了三个函数 , OpenSerial , writestring, readstring.<br>其中, readstring &nbsp;我在接收到数据后的处理上做了修改,而其他两个函数没变化<br>我确定以前的单元能够正查运行。<br>我修改的部分在 Readsuccess := ReadFile(m_hComm, &nbsp; &nbsp; &nbsp; &nbsp; //操作句柄<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;bStr[0], &nbsp; &nbsp; &nbsp; &nbsp;//数据缓冲区<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;NumberOfBytesToRead, &nbsp; //要读取的字节长度<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;iReadNum, &nbsp; &nbsp; &nbsp; &nbsp;//实际读取的字节长度<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;nil); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //overlapped buffer<br>这个api 之后, 故障发生是 这个api函数的调用不返回,所以,我猜测可能是参数的配置问题,可又一时间想不到原因,请各位朋友帮我思考一下
 
-------------------------------------------------------------------<br>如果我先用串口 调试工具打开某串口然后再关闭, 然后用我的程序调试,就能一直保持正常运行(不论我的程序开闭多少次,只要不重起电脑,就能正常运行)。<br>-------------------------------------------------------------------<br>这是因为某些状态位已经让调试工具帮你设定了,而你的程序在初始化时未做这些工作。<br><br>-------------------------------------------------------------------<br>我确定以前的单元能够正查运行。<br>-------------------------------------------------------------------<br>有时候看起来正确的东西其实亦可能具有它的偶然性,只是未暴露而已,尤其是程序的bug或defect。<br><br>跟读函数没关系,还是初始化的问题。另外,建议你使用第三方控件试试,你现在使用的这种方式如果需要细节控制可能比较困难。<br><br>以上纯属一家之言,仅供参考,如有错误,欢迎指正。
 
先谢谢 WickedladII 大哥的指点, 我也想到了是配置或者初始话的问题, 所以拿出来问大家,比如com口初始化需要注意哪几项什么的~!<br>我不能使用第三方控件,因为多数第三方控件是主动读串口的,我希望用的是我向串口写命令,然后等待命令的响应。<br>如果用主动读串口的方式,就复杂了,我得每次读到数据后,先检查上次是什么命令,然后再做处理,而且, 我用的是多线程,还得每个线程都建立一个窜口类<br>所以,希望能找到串口初始化时需要注意什么,单从学习知识的角度讲,我也愿意知道我程序不能工作的原因,而不是绕过它~!
 
你只打开了串口<br>你的那些参数应用到串口了吗<br>SetCommState<br>SetCommTimeOut等等
 
Mike1234567890 老兄说到了关键, 我又仔细检查一遍程序,发现了一个相当郁闷的错误,<br>修改了之后问题就解决了。可怜我的100分了心疼啊 。。。。。。。。。。。。。
 
多人接受答案了。
 
后退
顶部