主体程序:
uses
......,Unit2; //unit2是线程单元var
Form1: TForm1;
ReceiveData:TReceiveData;
implementation
{$R *.dfm}procedure TForm1.FormShow(Sender: TObject);
begin
ReceiveData:=TReceiveData.Create(True);
end;procedure TForm1.Button1Click(Sender: TObject);
begin
if Not comm.PortOpen then
begin
comm.CommPort:=1;
comm.Settings:='9600,n,8,1';
comm.PortOpen:=True;
comm.InputLen:=0;
Self.Caption:='串口已打开';
end;
ReceiveData.Resume;
end;
线程单元:
procedure TReceiveData.ReadData;
begin
if (Form1.Comm.InBufferCount>0) then
begin
Form1.Memo1.Lines.Add(Form1.Comm.Input);
end;
end;procedure TReceiveData.Execute;
begin
while not terminated do
begin
Synchronize(ReadData);
end;
end;
uses
......,Unit2; //unit2是线程单元var
Form1: TForm1;
ReceiveData:TReceiveData;
implementation
{$R *.dfm}procedure TForm1.FormShow(Sender: TObject);
begin
ReceiveData:=TReceiveData.Create(True);
end;procedure TForm1.Button1Click(Sender: TObject);
begin
if Not comm.PortOpen then
begin
comm.CommPort:=1;
comm.Settings:='9600,n,8,1';
comm.PortOpen:=True;
comm.InputLen:=0;
Self.Caption:='串口已打开';
end;
ReceiveData.Resume;
end;
线程单元:
procedure TReceiveData.ReadData;
begin
if (Form1.Comm.InBufferCount>0) then
begin
Form1.Memo1.Lines.Add(Form1.Comm.Input);
end;
end;procedure TReceiveData.Execute;
begin
while not terminated do
begin
Synchronize(ReadData);
end;
end;
你最好把接受数据写在MSComm的接受事情中。
我在它的OnComm事件里写了Memo1.Lines.Add(Comm.Input);
也没反应
我不太清楚这个控件是怎么工作的,我原先的设想是实现能在收的时候也能发送的,所以开了两个线程,一个用来接收,一个用来发送数据,尽量不把这些放到主线程中,因为在以前的程序中会发现有时候会出现死机及响应时间较长的情况
只要一用线程CPU就100%,SLEEP和APPLICATION.PROCCESS……都试过了,不顶用!
begin
Form1.Memo1.Lines.Add(Form1.Comm.Input);
end;procedure TReceiveData.Execute;
begin
while not terminated do
begin
if (Form1.Comm.InBufferCount>0) then Synchronize(ReadData);
end;
end;
你的代码我试过了,cpu一样会升到100%To cqwty(笨小孩):
下面是我的代码,报错procedure TReceiveData.Execute;
begin
if Not Unit1.CommCreated then
begin
comm:=TMSComm.Create(nil); //此句报错,提示说"尚未调用CoInitialize"
comm.Parent:=nil;
comm.CommPort:=1;
comm.Settings:='9600,n,8,1';
comm.PortOpen:=True;
comm.InputLen:=0;
Unit1.CommCreated:=True;
end; while not Terminated do
begin
if Comm.InBufferCount>0 then
Synchronize(ReadData);
end;
end;
while not terminated do
begin
Synchronize(ReadData);
Sleep(30); <-------加上这句就不是100%了 包爽
end;
end;
关键是要处理好读写事件。一般把 MSComm的 RThreshold和InputLen设置为相同的值
TForm1.MSComm1OnComm(Sender:TObject);
var v:variant; s:string; Len,i:integer; b:byte;
begin
Len:=MSComm1.InputLen;
while MSComm1.InbufferCount>=Len do
begin
v:=MSComm1.Input;
try
s:='';
for i:=0 to Len-1 do
begin
b:=v[i];
s:=s+Chr(b);
end;
Memo1.Lines.Add(s);
except
end;
end;
end;
由于串口事件的发生都是ms级的,所以上述处理不会导致CPU100%的,实际好像不占用CPU一样.除非你把波特率设置的非常非常High,并且不断的读写数据
再完善点,开头可以加上先判断MSComm1.CommEvent的具体值,再进行相应处理。
我现在的程序最多有10个串口(用了Moxa卡的),数据的读都是那么干的(RThreshold=InputLen=1)
一Sleep,消息处理就暂停了,消息累计多的话,程序会翘的
请问怎么CoInitialize?avenir(avenir):
我猜你的代码本来是vb里的,你给的在delphi里运行不起来,我改了一下
var
v:string;
s:string;
Len,i:integer;
b:char;
begin
Len:=MSComm1.InputLen;
while MSComm1.InbufferCount>=Len do
begin
v:=MSComm1.Input;
try
for i:=1 to Len do
begin
b:=v[i];
s:=s+v;
end;
except end;
end;//while
Memo1.Lines.Add(s);
end;还有,我简化了一下,你看行不行
Len:=MSComm1.InputLen;
while MSComm1.InbufferCount>=Len do
begin
v:=MSComm1.Input;
s:=s+v;
end;//while
Memo1.Lines.Add(s);
没有try有时会触发异常,原因是 V:=MSComm1.Input有时读不到内容,具体怎么造成的不太清楚,可能跟MSComm的读写有关。 当读不到内容时, b:=v[0]会触发异常的所以省去try,当InputLen>1时,不知道是否会有想不到的事发生。
此外 s:=s+v 呵呵,我一直不知道这么用。我一直把数据都当成二进制数来处理,一般的过程就是
while Commxxx.InputLen>0 do
begin
v:=MSComm1.Input;
try b:=v[0]; 。处理b; except end;
end;
begin
if Not Unit1.CommCreated then
begin
CoInitialize(null);
comm:=TMSComm.Create(nil); //此句报错,提示说"尚未调用CoInitialize"
comm.Parent:=nil;
comm.CommPort:=1;
comm.Settings:='9600,n,8,1';
comm.PortOpen:=True;
comm.InputLen:=0;
Unit1.CommCreated:=True;
end; while not Terminated do
begin
if Comm.InBufferCount>0 then
Synchronize(ReadData);
end;
end;
另外记住,当你线程结束的时候要CoUninitialize;
OK
at+cmgf=?
+CMGF: (0,1) 可用程序来做这些操作,程序中却显示
at+cmgf=
?
+CMG
F: (0,1)这是怎么回事?
begin
if (Form1.Comm.InBufferCount>0) then
begin
Form1.Memo1.Lines.Add(Form1.Comm.Input);
end
else
sleep(10); //没有数据时延时等待
end;
uses
......,Unit2; //unit2是线程单元var
Form1: TForm1;
ReceiveData:TReceiveData;
implementation
{$R *.dfm}procedure TForm1.FormShow(Sender: TObject);
begin
ReceiveData:=TReceiveData.Create(false); //false
end;procedure TForm1.Button1Click(Sender: TObject);
begin
if Not comm.PortOpen then
begin
comm.CommPort:=1;
comm.Settings:='9600,n,8,1';
comm.PortOpen:=True;
comm.InputLen:=0;
Self.Caption:='串口已打开';
end;
//ReceiveData.Resume; //屏蔽它
end;
线程单元:
procedure TReceiveData.ReadData;
begin
if (Form1.Comm.InBufferCount>0) then
begin
Form1.Memo1.Lines.Add(Form1.Comm.Input);
end;
end;procedure TReceiveData.Execute;
begin
while not terminated do
begin
if IsWork then //这里用类中的全局状态
Synchronize(ReadData);
Sleep(10); //释放cpu 资源
end;
end;////////////////增加全局的状态
TReceiveData=class(TThread)
public
isWork :boolean; //////允许任务进行工作