while(3S时间没有到)
{
检查串口数据
}
进行下一步 后来发现这种写法不行,定时器都不能触发了
Delay(1000);
Delay(1000);
Delay(1000);
检查串口数据 这种写法也不行,串口时间都不响应了。
8 个解决方案
#1
Delay(1000);
Delay(1000);
Delay(1000);
检查串口数据 这种写法也不行,串口事件都不响应了。
Delay(1000);
Delay(1000);
检查串口数据 这种写法也不行,串口事件都不响应了。
#2
开个线程试 试 ?
#3
你可能对于事件没什么概念。
直接放个TTimer组件,响应OnTimer事件就可以了。
直接放个TTimer组件,响应OnTimer事件就可以了。
#4
用定时器,或者线程都可以操作
#5
你的想法错了,不能用定时器。否则你的程序会出问题。
使用Win32写的动态库来读取数据,然后使用delphi调用这个动态库就可以了。
因为串口有数据的时候会产生中断,自动触发线程去读数据。
要是公司行为,你给我协议。我写动态库给你!
使用Win32写的动态库来读取数据,然后使用delphi调用这个动态库就可以了。
因为串口有数据的时候会产生中断,自动触发线程去读数据。
要是公司行为,你给我协议。我写动态库给你!
#6
我建议如下:
1,delphi中串口数据的接收用控件(如spcomm)中的触发事件来接收,不要主动查询串口;在单片机中也很少用查询方式访问串口数据;
2,在这个触发事件中设置一下标志位,当接收到数据的时候,标志位置1表示收到数据
3,放置定时器,时间为1s触发,申请一个全局变量,用以计算定时器触发的次数;
4,触发中的程序内容是检测是否有数据收到,如果有数据收到,判断数据是否满足要求;如果满足要求,转入你的其他操作,同时定时器停止,计数器清零,否则定时器计数器加1;
5,当定时器计数器达到3时,如果你的数据还不能满足要求,转入你的故障操作,然后定时器停止,计数器清零;
6,按钮代码中,先清零计数器,再清零串口数据接收标志位,然后开启定时器;
7,其实自己补充一下调试细节
1,delphi中串口数据的接收用控件(如spcomm)中的触发事件来接收,不要主动查询串口;在单片机中也很少用查询方式访问串口数据;
2,在这个触发事件中设置一下标志位,当接收到数据的时候,标志位置1表示收到数据
3,放置定时器,时间为1s触发,申请一个全局变量,用以计算定时器触发的次数;
4,触发中的程序内容是检测是否有数据收到,如果有数据收到,判断数据是否满足要求;如果满足要求,转入你的其他操作,同时定时器停止,计数器清零,否则定时器计数器加1;
5,当定时器计数器达到3时,如果你的数据还不能满足要求,转入你的故障操作,然后定时器停止,计数器清零;
6,按钮代码中,先清零计数器,再清零串口数据接收标志位,然后开启定时器;
7,其实自己补充一下调试细节
#7
98年写的接收串口数据的处理线程,你可以参考一下。
最好是用线程处理,在线程中 使用 WaitCommEvent 监控端口状态,并且进行数据读取和缓存。
hCom 是用CreateFile创建的端口句柄。
这个线程当时是挂在 ComDrv下面的,打开端口之后开始准备接收数据之后,就把这个线程跑起来。
你可以打开端口之后,跑起来这个线程,然后在主进程中等待3秒,到时间候检查缓冲区中的数据是否符合你的要求。
最好是用线程处理,在线程中 使用 WaitCommEvent 监控端口状态,并且进行数据读取和缓存。
hCom 是用CreateFile创建的端口句柄。
这个线程当时是挂在 ComDrv下面的,打开端口之后开始准备接收数据之后,就把这个线程跑起来。
你可以打开端口之后,跑起来这个线程,然后在主进程中等待3秒,到时间候检查缓冲区中的数据是否符合你的要求。
// TWaitComm
constructor TWaitComm.Create( hCom:THandle;dcb:TDCB;po:POVERLAPPED;Buf:PChar;pBufState:TPPortBufState );
begin
FhCom := hCom;
FDcb := dcb;
Fpo := po;
FState := tsRun;
Priority := tpLowest;
FPortBuf := Buf;
FpPortBufState := pBufState;
inherited Create(False);
end;
procedure TWaitComm.SetState( const State:TThreadState );
begin
FState := State;
end;
procedure TWaitComm.ProcRun;
var
dwNOBR,dwErrorFlags:DWORD;
ComStat:TCOMSTAT;
iBufFreeSize:integer;
begin
if (WaitCommEvent(FhCom, FdwEvtMask, Fpo)) then
begin
if ((FdwEvtMask and EV_RXCHAR)=EV_RXCHAR) then
begin
//等待缓冲区空闲
while FpPortBufState^.NowOprt<>opIdle do Sleep(5);
//设置缓冲区为写状态
//取缓冲区剩余空间大小
FpPortBufState^.NowOprt := opInWrite;
iBufFreeSize := PORT_BUFFER_SIZE - FpPortBufState^.Tail;
//读端口数据到缓冲区
// only try to read number of bytes in queue
ClearCommError( FhCom, dwErrorFlags, @ComStat ) ;
if (iBufFreeSize>ComStat.cbInQue) then
dwNOBR := ComStat.cbInQue
else
dwNOBR := iBufFreeSize;
ReadFile(FhCom,FPortBuf[FpPortBufState^.Tail],dwNOBR,dwNOBR,Fpo);
FpPortBufState^.Tail := FpPortBufState^.Tail + dwNOBR;
//恢复缓冲区为空闲
FpPortBufState^.NowOprt := opIdle;
end;
end;
end;
procedure TWaitComm.Execute;
begin
{ Place thread code here }
while True do
begin
case FState of
tsRun:
begin
ProcRun;
end;
tsPause:
begin
Sleep(10);
end;
tsEnd:
begin
Exit;
end;
end; // end case
end; // end while
end;
//=========================TWaitComm
#8
楼主好像没有用COM口控件,XE建议使用CPORT,D6、D7可以使用SPCOM,使用端口触发,一般不要用定时器
#1
Delay(1000);
Delay(1000);
Delay(1000);
检查串口数据 这种写法也不行,串口事件都不响应了。
Delay(1000);
Delay(1000);
检查串口数据 这种写法也不行,串口事件都不响应了。
#2
开个线程试 试 ?
#3
你可能对于事件没什么概念。
直接放个TTimer组件,响应OnTimer事件就可以了。
直接放个TTimer组件,响应OnTimer事件就可以了。
#4
用定时器,或者线程都可以操作
#5
你的想法错了,不能用定时器。否则你的程序会出问题。
使用Win32写的动态库来读取数据,然后使用delphi调用这个动态库就可以了。
因为串口有数据的时候会产生中断,自动触发线程去读数据。
要是公司行为,你给我协议。我写动态库给你!
使用Win32写的动态库来读取数据,然后使用delphi调用这个动态库就可以了。
因为串口有数据的时候会产生中断,自动触发线程去读数据。
要是公司行为,你给我协议。我写动态库给你!
#6
我建议如下:
1,delphi中串口数据的接收用控件(如spcomm)中的触发事件来接收,不要主动查询串口;在单片机中也很少用查询方式访问串口数据;
2,在这个触发事件中设置一下标志位,当接收到数据的时候,标志位置1表示收到数据
3,放置定时器,时间为1s触发,申请一个全局变量,用以计算定时器触发的次数;
4,触发中的程序内容是检测是否有数据收到,如果有数据收到,判断数据是否满足要求;如果满足要求,转入你的其他操作,同时定时器停止,计数器清零,否则定时器计数器加1;
5,当定时器计数器达到3时,如果你的数据还不能满足要求,转入你的故障操作,然后定时器停止,计数器清零;
6,按钮代码中,先清零计数器,再清零串口数据接收标志位,然后开启定时器;
7,其实自己补充一下调试细节
1,delphi中串口数据的接收用控件(如spcomm)中的触发事件来接收,不要主动查询串口;在单片机中也很少用查询方式访问串口数据;
2,在这个触发事件中设置一下标志位,当接收到数据的时候,标志位置1表示收到数据
3,放置定时器,时间为1s触发,申请一个全局变量,用以计算定时器触发的次数;
4,触发中的程序内容是检测是否有数据收到,如果有数据收到,判断数据是否满足要求;如果满足要求,转入你的其他操作,同时定时器停止,计数器清零,否则定时器计数器加1;
5,当定时器计数器达到3时,如果你的数据还不能满足要求,转入你的故障操作,然后定时器停止,计数器清零;
6,按钮代码中,先清零计数器,再清零串口数据接收标志位,然后开启定时器;
7,其实自己补充一下调试细节
#7
98年写的接收串口数据的处理线程,你可以参考一下。
最好是用线程处理,在线程中 使用 WaitCommEvent 监控端口状态,并且进行数据读取和缓存。
hCom 是用CreateFile创建的端口句柄。
这个线程当时是挂在 ComDrv下面的,打开端口之后开始准备接收数据之后,就把这个线程跑起来。
你可以打开端口之后,跑起来这个线程,然后在主进程中等待3秒,到时间候检查缓冲区中的数据是否符合你的要求。
最好是用线程处理,在线程中 使用 WaitCommEvent 监控端口状态,并且进行数据读取和缓存。
hCom 是用CreateFile创建的端口句柄。
这个线程当时是挂在 ComDrv下面的,打开端口之后开始准备接收数据之后,就把这个线程跑起来。
你可以打开端口之后,跑起来这个线程,然后在主进程中等待3秒,到时间候检查缓冲区中的数据是否符合你的要求。
// TWaitComm
constructor TWaitComm.Create( hCom:THandle;dcb:TDCB;po:POVERLAPPED;Buf:PChar;pBufState:TPPortBufState );
begin
FhCom := hCom;
FDcb := dcb;
Fpo := po;
FState := tsRun;
Priority := tpLowest;
FPortBuf := Buf;
FpPortBufState := pBufState;
inherited Create(False);
end;
procedure TWaitComm.SetState( const State:TThreadState );
begin
FState := State;
end;
procedure TWaitComm.ProcRun;
var
dwNOBR,dwErrorFlags:DWORD;
ComStat:TCOMSTAT;
iBufFreeSize:integer;
begin
if (WaitCommEvent(FhCom, FdwEvtMask, Fpo)) then
begin
if ((FdwEvtMask and EV_RXCHAR)=EV_RXCHAR) then
begin
//等待缓冲区空闲
while FpPortBufState^.NowOprt<>opIdle do Sleep(5);
//设置缓冲区为写状态
//取缓冲区剩余空间大小
FpPortBufState^.NowOprt := opInWrite;
iBufFreeSize := PORT_BUFFER_SIZE - FpPortBufState^.Tail;
//读端口数据到缓冲区
// only try to read number of bytes in queue
ClearCommError( FhCom, dwErrorFlags, @ComStat ) ;
if (iBufFreeSize>ComStat.cbInQue) then
dwNOBR := ComStat.cbInQue
else
dwNOBR := iBufFreeSize;
ReadFile(FhCom,FPortBuf[FpPortBufState^.Tail],dwNOBR,dwNOBR,Fpo);
FpPortBufState^.Tail := FpPortBufState^.Tail + dwNOBR;
//恢复缓冲区为空闲
FpPortBufState^.NowOprt := opIdle;
end;
end;
end;
procedure TWaitComm.Execute;
begin
{ Place thread code here }
while True do
begin
case FState of
tsRun:
begin
ProcRun;
end;
tsPause:
begin
Sleep(10);
end;
tsEnd:
begin
Exit;
end;
end; // end case
end; // end while
end;
//=========================TWaitComm
#8
楼主好像没有用COM口控件,XE建议使用CPORT,D6、D7可以使用SPCOM,使用端口触发,一般不要用定时器