Форум: "WinAPI";
Текущий архив: 2004.10.31;
Скачать: [xml.tar.bz2];
ВнизПомогите решить проблему работы с COM портом. Найти похожие ветки
← →
dt75 (2004-09-26 18:40) [0]Добрый день.
Помогите решить проблему работы с COM портом. Есть устройство, подключенное к COM порту. Устройству периодически (в зависимости от действий пользователя) передаются пакеты данных различной длины с разными интервалами времени. Устройство отвечает на принятые пакеты и периодически отсылает свои пакеты. Проблема состоит в том, что при приеме данных от устройства программа стопорится и не дает производить ни каких действий пока не получит данные из порта. Поскольку при любом действия пользователя происходит отправка данных в порт, программа совсем перестает шевелиться.
Для работы с портом пробовал использовать компонент «XCOMDRV», отслеживать событие «XCommCommEven» получены данные, тормозит. Пробовал, как во многих примерах работы с модемом читать входной буфер сразу после отправке данных, полный ступор программы. Пробовал организовывать поток для приема данных, результат тот же, полное застопоривание программы.
Буду, благодарен любым советам и примерам.
← →
jack128 © (2004-09-26 20:33) [1]dt75 (26.09.04 18:40)
Как работает этот > «XCOMDRV» - не знаю, но то что и при использовании доп. потока у тя программа стопорится - это ты явно где то стормозил.. Код в студию.
← →
GanibalLector © (2004-09-26 20:43) [2]А может у твоего XCOMDRV вовсе нет таймаутов???И поэтому ступор.
← →
dt75 (2004-09-26 21:45) [3]Re: .. Код в студию.
........................
unit ComPort;
interface
uses Windows, SysUtils, Classes, Unit1, MasterM;
type
TCommThread = class(TThread)
private
{ Private declarations }
procedure QueryPort;
protected
procedure Execute; override;
end;
var
CommThread:TCommThread; //поток, в котором будет работать процедура опроса порта
hCommFile : THandle;
procedure OpenCOMPort();
procedure CloseCOMPort();
implementation
//инициализация потока
procedure StartComThread;
begin
CommThread:=TCommThread.Create(False);
//проверяем получилось или нет
if CommThread = nil then
begin
//ошибка, все выключаем и выходим
SysErrorMessage(GetLastError);
Form1.ComboBox1.Text := DateTimeToStr(Now) + ". Не могу запустить службу";
Exit;
end;
Form1.ComboBox1.Text := DateTimeToStr(Now) + ". Служба опроса порта запущена";
end;
//******************************************************************************
//запустим процедуру опроса порта в нашем потоке
procedure TCommThread.Execute;
begin
repeat
QueryPort;//процедура опроса порта будет производиться пока поток не будет прекращен
until Terminated;
end;
//******************************************************************************
//процедура опроса порта
procedure TCommThread.QueryPort;
var
BytesRead : cardinal; //количество считанных байт
begin
//читаем буфер из Com-порта
if ReadFile(hCommFile, BufInStr, SizeOf(BufInStr), BytesRead, nil) then
begin
Form1.ComboBox1.Text := DateTimeToStr(Now) + ". Приняты данные";
Form1.ComboBox1.Items.Add(Form1.ComboBox1.Text);
Form2.StatusBar1.Panels[3].Text := "Принято "+ IntToStr(BytesRead)+" байт";
if CheckSumIn then
begin
if BufInStr[4] = $80 then VisMMS;
if BufInStr[4] = $61 then Form2.Edit11.Text := IntToStr(BufInStr[7]);
end
else
begin
Form1.ComboBox1.Text := DateTimeToStr(Now) + ". Ошибка контрольной суммы";
Form1.ComboBox1.Items.Add(Form1.ComboBox1.Text);
end;
end
else
begin
Form1.ComboBox1.Text := DateTimeToStr(Now) + ". Не могу прочесть данные";
Form1.ComboBox1.Items.Add(Form1.ComboBox1.Text);
end;
end;
//******************************************************************************
//Инициализируем порт
procedure OpenCOMPort();
begin
hCommFile := CreateFile(PChar("\\.\"+ ComPortName),
GENERIC_READ or GENERIC_WRITE,
FILE_SHARE_READ or FILE_SHARE_WRITE,
nil, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL, 0);
if hCommFile<>INVALID_HANDLE_VALUE then
begin
Form1.ComboBox1.Text := DateTimeToStr(Now) + ". " + "Порт "+ ComPortName +" открыт.";
Form1.ComboBox1.Items.Add(Form1.ComboBox1.Text);
Form1.N4.Enabled := True;
Form1.N3.Enabled := False;
Form1.N2.Enabled := False;
StartComThread;;
end
else
begin
Form1.ComboBox1.Text := DateTimeToStr(Now) + ". Не могу окрыть порт";
end;
end;
//******************************************************************************
//закрыть порт
procedure CloseCOMPort();
begin
CommThread.Free;
CloseHandle(hCommFile);
Form1.ComboBox1.Text := DateTimeToStr(Now) + ". " + "Порт "+ ComPortName +" закрыт.";
Form1.ComboBox1.Items.Add(Form1.ComboBox1.Text);
Form1.N4.Enabled := False;
Form1.N3.Enabled := True;
Form1.N2.Enabled := True;
end;
end.
← →
jack128 © (2004-09-27 00:50) [4]dt75 (26.09.04 21:45) [3]
CommThread:=TCommThread.Create(False);
//проверяем получилось или нет
if CommThread = nil then
Лишнее. Конструктор либо возвращат объект, либо гнерит исключение
dt75 (26.09.04 21:45) [3]
if ReadFile(hCommFile, BufInStr, SizeOf(BufInStr), BytesRead, nil)
Надеюсь BuInStr - статический массив?
dt75 (26.09.04 21:45) [3]
Form1.ComboBox1.Text := DateTimeToStr(Now) + ". Приняты данные";
Внимательно читаем хелп по TThread.Synchronize
И что то я не вижу, чтоб устанавливались параметры чтения и таймауты..
← →
GanibalLector © (2004-09-27 01:23) [5]Ну,что я говорил.Где таймауты???
Нужно что-то типа :
function SetRxTime(Handle:THandle; const TimeC,TimeM:Integer):Boolean;
var
TOut:TCommTimeouts;
begin
if (TimeC=0) AND (TimeM=0) then
TOut.ReadIntervalTimeout := MAXDWORD
else TOut.ReadIntervalTimeout := 0;
TOut.ReadTotalTimeoutMultiplier := TimeM;
TOut.ReadTotalTimeoutConstant := TimeC;
TOut.WriteTotalTimeoutMultiplier := 0;
TOut.WriteTotalTimeoutConstant := 0;
Result:=SetCommTimeOuts(Handle, TOut);
end;
И,соответственно,проверять приход на таймаут.
← →
dt75 (2004-09-27 03:01) [6]Всем спасибо, нашел свой глюк, стоило только начать с кем-то обсуждать. Глюк был совсем в другой части кода, отныне ни каких компонентов только чистый API чтоб потом чужие баги не выискивать.
А по поводу параметров чтения и таймаутов, у меня устройство живет не на чистом COM порту, а на такой специальной железяки, которая называется XPort – это переходник с изернета на уарт, для компьютера он является виртуальным COM портом. Но железка статическая и настраивается своей софтиной. По этому параметры чтения и таймауты являются жестко предопределенными, и менять их из программы нет смысла.
Еще раз спасибо.
← →
GanibalLector © (2004-09-27 03:15) [7]Господин,а синхронизация???Нельзя в потоке обращаться к визуальным компонентам.
Страницы: 1 вся ветка
Форум: "WinAPI";
Текущий архив: 2004.10.31;
Скачать: [xml.tar.bz2];
Память: 0.48 MB
Время: 0.05 c