Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2004.10.31;
Скачать: CL | DM;

Вниз

Помогите решить проблему работы с 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 вся ветка

Текущий архив: 2004.10.31;
Скачать: CL | DM;

Наверх




Память: 0.49 MB
Время: 0.027 c
1-1097827100
Unknown user
2004-10-15 11:58
2004.10.31
Пустые значения


1-1097589504
sten
2004-10-12 17:58
2004.10.31
read only для combobox


14-1097258049
GanibalLector
2004-10-08 21:54
2004.10.31
ГИМН КАЗАНТИПА


6-1093338639
Дмитрий Ботвин
2004-08-24 13:10
2004.10.31
Получение списка файлов с ftp-сервера


9-1088578445
zorik
2004-06-30 10:54
2004.10.31
Реверси и другие