Ну что, вот и настала очередь теперь рассмотреть запись данных в асинхронном режиме. Для этого доработаем немного наш исходник из предыдущей статьи. Благодаря тому, что львиную долю работы по его подготовке мы уже выполнили, дело осталось за малым.
И так, добавим на нашу форму 1 компонент Edit и 1 компонент Button. Как Вы наверное уже догадались в Edit мы будем записывать данные, а новой кнопкой будем записывать их в буфер порта.
1) После существующего уже потока чтения, который мы объявили в предыдущей статье, объявим теперь поток записи:
MyThreadWr=class(Tthread)
private{ private declarations }
protected
procedure execute; override;
end;
в раздел глобальных переменных, добавим следующие переменные:
var
//...
//...
//...
BufferWr:array [0..255] of AnsiChar; //Массив данных AnsiChar для передачи;
MyThrWr:MyThreadWr; //Переменная потока записи;
2) Выделяем procedure execute; override; жмем Ctrl+Shift+C и в появившемся конструкторе запишем:
procedure MyThreadWr.execute;
var
flag:Bool; //Состояние передачи;
i:Integer; //Счетчик;
Bw:AnsiString; //Промежуточная переменная;
begin
PurgeComm(ComFile, Purge_TXabort or Purge_TXclear); //Очищаем передающий буфер и очереди записи;
Bw:=(Form1.Edit1.Text); //Загружаем содержимое Edit1 в переменную;
for i:=1 to Length(Bw) do //все загруженное от начала до конца
BufferWr[i]:=Ansichar(Bw[i]); //загоняем в массив
OverWrite.Hevent:=CreateEvent(Nil, True, True, Nil); {Сигнальный объект событие для ассинхронных операций;}
WriteFile(ComFile, BufferWr, SizeOf(BufferWr), Temp, @OverWrite); {Пишем в порт массив;}
Signal:=WaitForSingleObject(OverWrite.hEvent, Infinite); {Приостанавливаем поток до тех пор пока не завершится передача;}
if (Signal=Wait_Object_0) and GetOverlappedResult(ComFile, OverWrite, Temp, true) then
flag:=true
else
flag:=false;
BufferWr:=''; //Очищаем содержимое переменной буфера;
CloseHandle(OverWrite.Hevent); //Закрываем объект событие;
end;
Переменную Flag можно использовать в последствии как сигнал успеха/провала передачи;
3) Для запуска потока записи в событии OnClick Button5 запишем:
procedure TForm1.Button5Click(Sender: TObject);
begin
MyThrWr:=MyThreadWr.Create(false); //Создаем поток записи;
MyThrWr.FreeOnTerminate:=true; //Запускаем поток записи;
MyThrWr.Priority:=tpNormal; //Устанавливаем приоритет;
end;
Ну вот собственно и все, проект готов. Соединение портов можно оставить таким как я описывал в предыдущей статье, только программа терминал Вам уже не понадобится. Скопируйте из папки с проектом Win32/Debug наш экзешник, Project1.exe поместите его куда нибудь на рабочий стол, запустите его дважды, чтобы открылось 2 окна. Первый экземпляр подключите к одному порту, а второй к другому. На обоих запускайте чтение и пробуйте отправлять данные. Вот Вам и персональный минитерминальчик. Если Вы все выполняли внимательно, то процессы приема/передачи будут работать как часики. Что отправляете из первого экземпляра, будет фиксироваться во-втором и наоборот. Кстати для проверки чтения/записи можно обойтись одним экземпляром программы и одним COM - портом. Для этого необходимо "коротнуть" перемычкой ноги как описано в этой статье. Или замкнуть контакты RXD и TXD если используете конвертер. Пример будет работать. Ну а теперь кому нужно держите исходник ...)
И так, добавим на нашу форму 1 компонент Edit и 1 компонент Button. Как Вы наверное уже догадались в Edit мы будем записывать данные, а новой кнопкой будем записывать их в буфер порта.
1) После существующего уже потока чтения, который мы объявили в предыдущей статье, объявим теперь поток записи:
MyThreadWr=class(Tthread)
private{ private declarations }
protected
procedure execute; override;
end;
в раздел глобальных переменных, добавим следующие переменные:
var
//...
//...
//...
BufferWr:array [0..255] of AnsiChar; //Массив данных AnsiChar для передачи;
MyThrWr:MyThreadWr; //Переменная потока записи;
2) Выделяем procedure execute; override; жмем Ctrl+Shift+C и в появившемся конструкторе запишем:
procedure MyThreadWr.execute;
var
flag:Bool; //Состояние передачи;
i:Integer; //Счетчик;
Bw:AnsiString; //Промежуточная переменная;
begin
PurgeComm(ComFile, Purge_TXabort or Purge_TXclear); //Очищаем передающий буфер и очереди записи;
Bw:=(Form1.Edit1.Text); //Загружаем содержимое Edit1 в переменную;
for i:=1 to Length(Bw) do //все загруженное от начала до конца
BufferWr[i]:=Ansichar(Bw[i]); //загоняем в массив
OverWrite.Hevent:=CreateEvent(Nil, True, True, Nil); {Сигнальный объект событие для ассинхронных операций;}
WriteFile(ComFile, BufferWr, SizeOf(BufferWr), Temp, @OverWrite); {Пишем в порт массив;}
Signal:=WaitForSingleObject(OverWrite.hEvent, Infinite); {Приостанавливаем поток до тех пор пока не завершится передача;}
if (Signal=Wait_Object_0) and GetOverlappedResult(ComFile, OverWrite, Temp, true) then
flag:=true
else
flag:=false;
BufferWr:=''; //Очищаем содержимое переменной буфера;
CloseHandle(OverWrite.Hevent); //Закрываем объект событие;
end;
Переменную Flag можно использовать в последствии как сигнал успеха/провала передачи;
3) Для запуска потока записи в событии OnClick Button5 запишем:
procedure TForm1.Button5Click(Sender: TObject);
begin
MyThrWr:=MyThreadWr.Create(false); //Создаем поток записи;
MyThrWr.FreeOnTerminate:=true; //Запускаем поток записи;
MyThrWr.Priority:=tpNormal; //Устанавливаем приоритет;
end;
Ну вот собственно и все, проект готов. Соединение портов можно оставить таким как я описывал в предыдущей статье, только программа терминал Вам уже не понадобится. Скопируйте из папки с проектом Win32/Debug наш экзешник, Project1.exe поместите его куда нибудь на рабочий стол, запустите его дважды, чтобы открылось 2 окна. Первый экземпляр подключите к одному порту, а второй к другому. На обоих запускайте чтение и пробуйте отправлять данные. Вот Вам и персональный минитерминальчик. Если Вы все выполняли внимательно, то процессы приема/передачи будут работать как часики. Что отправляете из первого экземпляра, будет фиксироваться во-втором и наоборот. Кстати для проверки чтения/записи можно обойтись одним экземпляром программы и одним COM - портом. Для этого необходимо "коротнуть" перемычкой ноги как описано в этой статье. Или замкнуть контакты RXD и TXD если используете конвертер. Пример будет работать. Ну а теперь кому нужно держите исходник ...)
И за исходничек спасибо)! Живой!
ОтветитьУдалить