понедельник, 18 июня 2018 г.

COM порт (RS-232) Асинхронный обмен данными. Запись данных ч.5 (практика).

Ну что, вот и настала очередь теперь рассмотреть запись данных в асинхронном режиме. Для этого доработаем немного наш исходник из предыдущей статьи. Благодаря тому, что львиную долю работы по его подготовке мы уже выполнили, дело осталось за малым.
И так, добавим на нашу форму 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 комментарий:

Примечание. Отправлять комментарии могут только участники этого блога.