Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "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.033 c
3-1096325902
Mizanthrope
2004-09-28 02:58
2004.10.31
Сортировка записей в таблице


4-1096332243
qwant
2004-09-28 04:44
2004.10.31
Сделать дефрагментатор диска


1-1097911287
Merida
2004-10-16 11:21
2004.10.31
Заполнение таблицы при запуске.


3-1096709878
тот же
2004-10-02 13:37
2004.10.31
Как расставить DisableControls и EnableControls


8-1089988038
gdima
2004-07-16 18:27
2004.10.31
Video





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский