Программа состоит из неплохого передатчика последовательных импульсов, и двух простых контрольных приёмников для изучения принципа работы устройства. Передатчик основан на программируемом цикле счётчика:
for i:= 1 to N do где N - это число указывающее счётчику сколько раз надо повторять цикл. Например такой код: for i:= 1 to 10 do begin ButtonPin2; end; - десять раз устанавливает / снимает логическую 1 на ножке Pin2 LPT разъёма. А именно: пять раз устанавливает 1 и пять раз 0 . Поэтому, если нам требуется отправить десять единиц (положительных импульсов), необходимо число циклов умножить на два : for i:= 1 to N*2 do где N = 10. Таким способом, мы программируем передатчик, следовательно он работает безошибочно. Скорость передачи регулируем традиционно - задержкой Sleep(миллисекунд). Приёмники импульсов - только учебные и не отличаются точностью приёма, уж очень много факторов на них влияет. Но на низких скоростях работают вполне удовлетворительно, чего вполне достаточно для изучения алгоритма. Если в передатчике включен режим "Авто" - происходит автоматическая (в основном, но иногда сбоит) коррекция ошибок приёма. В общем, можно соединить два компьютера и проверить на практике, установив соответствующие биты и др. настройки. Но, попрактиковаться можно и сразу, внутри программы, как настроено всё по умолчанию. Алгоритм таков: когда передатчик начинает передачу, например числа 10, он отсчитывает импульсы по Pin14 с помощью команды ButtonPin14. Одновременно появляется контрольный сигнал (назовём его CLK) на Pin16. Тогда приёмник, с помощью уже известного нам, простейшего счётчика импульсов, считает эти посылки, одновременно подтверждая принятый сигнал лог.1 передачей импульса по Pin2 ( при практической реализации можете сменить на входной - в приёмном коде передатчика, естественно). Передатчик,если включен "Авто", принимает эти импульсы во время передачи. По окончании передачи снимается сигнал CLK и Pin16 переводится в лог. ноль. При этом приёмник заканчивает отсчёт и включает таймер, который сбрасывает счетчики в ноль и фиксирует LOG. Передатчик также проверяет, соответствует ли, полученное число переданному, и если нет - уменьшает скорость, начинает передачу заново, и так до тех пор, пока скорость станет таковой, при которой число передаётся без ошибок. Это простейший алгоритм, разработанный специально для изучения начинающими. Здесь всё зависит от системных ресурсов, и работа в win9x и winXP - существенно отличается. В целом, в программе имеется еще много сложных взаимосвязей, а времени у меня не имеется, поэтому скачайте готовый исходник и изучите, следуя комментариям, там еще много полезных настроек, которые с успехом Вы можете применять в своих программах, как разберётесь. |
{--------------- Программа LPT SEND : смотрим код ---------------} {Универсальный переключатель - используйте в своих программах} function TForm1.Bits : boolean ; //--отслеживает переключения бит (1-2-4-8-16-32-64-128) Var d : boolean; bit : byte; begin bit := StrToInt(ComboBox3.Text); //-- переключатель бит (согласно отдельно взятому Pin) d := true; {and - не инвертируется } d := d and ((bit) = ((bit) and Lpt.ReadPort(GetCurrentPort,GetCurrentRegister))) ; {Предусмотр. автоматическая инверсия инверсных бит рег. контроля - это: Pin1, Pin14, Pin17} if (ComboBox2.Text = 'КОНТРОЛЯ') then if (bit = 1) or (bit = 2) or (bit = 8)then d := not d ; //-- "or" - значит "или" {Предусмотр. автоматическая инверсия инверсных бит входного рег. - это: Pin11} if (ComboBox2.Text = 'ВХОДЫ') then if (bit = 128) then d := not d ; { если выбран инверсный режим - инвертируем вручную всё} if CheckBox1.Checked = true then d := not d ; Bits := d; end; function TForm1.CLK : boolean ; //-- позволяет инвертировать сигнал CLK Var d : boolean; b : integer; begin b := StrToInt(ComboBox5.Text); //-- установка бита d := true; d := d and (b = (b and Lpt.ReadPort(GetCurrentPort,2))) ; if CheckBox3.Checked = false then CLK := d else CLK := not d; end; procedure TForm1.Timer1Timer(Sender: TObject); //-- таймер индикации begin SpeedButton1.Enabled := Bits; //-- управляем контрольным светодиодом (встроенный в SpeedButton1) SpeedButton3.Enabled := CLK; //-- управляем контрольным светодиодом CLK if CLK = false then begin SpeedButton6.Enabled := (CLK xor Bits) or (CLK and Bits) ; //-- зажигаем если неправильно настроенны биты RX end; end; {Добавлена полезная проц. PinInfo, информ. о структуре LPT регистров и соотв.Pin} procedure TForm1.PinInfo ; begin if ComboBox2.Text = 'ДАННЫХ' then begin if ComboBox3.Text = '1' then StaticText1.Caption := ' Bit 2* = 1 : Pin2'; if ComboBox3.Text = '2' then StaticText1.Caption := ' Bit 2* = 2 : Pin3'; if ComboBox3.Text = '4' then StaticText1.Caption := ' Bit 2* = 4 : Pin4'; if ComboBox3.Text = '8' then StaticText1.Caption := ' Bit 2* = 8 : Pin5'; if ComboBox3.Text = '16' then StaticText1.Caption := ' Bit 2* = 16 : Pin6'; if ComboBox3.Text = '32' then StaticText1.Caption := ' Bit 2* = 32 : Pin7'; if ComboBox3.Text = '64' then StaticText1.Caption := ' Bit 2* = 64 : Pin8'; if ComboBox3.Text = '128'then StaticText1.Caption := ' Bit 2* = 128 : Pin9'; end; if ComboBox2.Text = 'КОНТРОЛЯ' then begin if ComboBox3.Text = '1' then StaticText1.Caption := ' Bit 2* = 1 : Pin1' else if ComboBox3.Text = '2' then StaticText1.Caption := ' Bit 2* = 2 : Pin14' else if ComboBox3.Text = '4' then StaticText1.Caption := ' Bit 2* = 4 : Pin16' else if ComboBox3.Text = '8' then StaticText1.Caption := ' Bit 2* = 8 : Pin17' else StaticText1.Caption := ' Не поддерживает ' ; end; if ComboBox2.Text = 'ВХОДЫ' then begin if ComboBox3.Text = '8' then StaticText1.Caption := ' Bit 2* = 8: Pin15' else if ComboBox3.Text = '16' then StaticText1.Caption := ' Bit 2* = 16: Pin13' else if ComboBox3.Text = '32' then StaticText1.Caption := ' Bit 2* = 32: Pin12' else if ComboBox3.Text = '64' then StaticText1.Caption := ' Bit 2* = 64: Pin10' else if ComboBox3.Text = '128'then StaticText1.Caption := ' Bit 2* = 128: Pin11' else StaticText1.Caption := ' Не поддерживает ' ; end; end; procedure TForm1.ComboBox3Change(Sender: TObject); begin PinInfo; //-- вызываем процедуру при переключении бит end; procedure TForm1.ComboBox2Change(Sender: TObject); begin PinInfo; //-- вызываем процедуру при переключении регистров end; procedure TForm1.SpeedButton2Click(Sender: TObject); //-- кнопка "передача" begin Edit1.Text := '0'; //-- обновить индикатор TX; //-- включ. передачу end; procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction); //-- прерываем циклы begin StopRX := true; StopTX := true; end; {Внешний высокоскоростной приёмник "RX2" (Запустите вторую копию программы )} procedure TForm1.RX2; //-- режим приёмника 2 Var a : integer; begin Edit3.Text := '0'; StopRX := false; //--флаг стоп / старт While not StopRX do //--бесконечный цикл, пока флаг стоп не поднят: begin a := 0; { -------------- Счётчик импульсов1 (Биты задаются Bits )--------------} if Edit3.Tag = 0 then //-- TAG = 0 : метка начала отсчета begin if Bits = true then begin //-- собственно счётчик a := a + 1; //-- фиксируем импульс Edit3.Text := IntToStr(StrToInt(Edit3.Text)+1); // -- принимаем импульсы end; Edit3.Tag :=1; //-- TAG = 1 : метка конца отсчета if a = 1 then ButtonPin2; // -- подтверждаем приём импульса, с помощью Рin2 end; if Bits = false then Edit3.Tag := 0; //-- разреш. отсчёт след. импульса { -------------- Счётчик импульсов2 <CLK> (Pin16 )--------------------------} if Edit4.Tag = 0 then begin if CLK = true then Edit4.Text := IntToStr(StrToInt(Edit4.Text)+1); Edit4.Tag :=1; end; if CLK = false then Edit4.Tag := 0; { --------------------------------------------------------------------------} Sleep(TrackBar1.Position); //--приложение засыпает на заданный интервал Application.ProcessMessages; //--Обработка всей очереди сообщений end; end; procedure TForm1.SpeedButton4Click(Sender: TObject); //-- кнопка "СТОП" передачи Var a,b : integer; begin if SpeedButton4.Tag = 0 then //-- если кнопка не заблокирована тогда: begin a := StrToInt(Edit1.Text) ; //-- преобразуем b := StrToInt(Edit2.Text) ; //-- преобразуем StopTX := not StopTX; //-- "СТОП" передачи Edit2.Text := IntToStr(b-a); //-- устан. оставш. число для послед. передачи SpeedButton4.Tag := 1; //-- заблокировать дальнейшее применения кнопки end else MessageBeep(MB_ICONEXCLAMATION); end; procedure TForm1.Timer3Timer(Sender: TObject); //-- таймер сброса и ведения LOG begin if CLK = false then //-- добавляем лог begin RichEdit1.Lines.Add (FormatDateTime('hh:mm:ss', time()) +' Принят код ' + Edit3.Text); Edit3.Text := '0'; Timer3.Enabled := false; end; end; procedure TForm1.Edit4Change(Sender: TObject); begin Timer3.Enabled := true; //-- таймер сброса и ведения LOG - включить end; procedure TForm1.TX; //-- Передатчик последовательных импульсов Pin14 Var a,b,c,d, i : integer; begin { автоматич. конролир. настройки бит по умолчанию } if CheckBox4.Checked = true then begin if Pin16 = true then ButtonPin16; if Pin14 = false then ButtonPin14; if Pin2 = true then ButtonPin2; end; {Собственно передатчик импульсов} d := 0 ; Timer2.Enabled := false ; //-- отключ. таймер после автокоррекции Edit1.Text := '0'; //-- обновить индикатор Edit6.Text := '0'; //-- обновляем SpeedButton4.Tag := 0; //-- разрешаем кнопку "Стоп" a := StrToInt(Edit1.Text) ; //-- преобразуем b := StrToInt(Edit2.Text) ; //-- преобразуем c := StrToInt(ComboBox4.Text); //-- преобразуем Gauge1.MaxValue := b; //-- настраиваем индикатор передачи (в %) Gauge1.ForeColor := clBlue; //-- показ. StopTX := false ; //-- флаг стоп / старт for i:= 1 to b*2 do //-- цикл передачи (Внимание : задаётся Edit2 !) begin if StopTX = true then exit; //-- если наж. "Стоп" - прекращаем передачу ButtonPin14; //-- начинаем передачу импульсов Pin14 (передача 1 / 0) if Pin14 = true then a := a + 1; // -- контроль (подсчёт) переданных данных (лог. 1) Edit1.Text:= IntToStr(a); //-- выводим результ. подсчёта Gauge1.Progress := a; //-- показ. переданное в % {Передаём сигнал управления CLK - лог. 1} Lpt.WritePort (GetCurrentPort,2,(c or Lpt.ReadPort( (GetCurrentPort) ,2) )); if a = b then //-- если цикл пройден : begin {Снимаем сигнал управления CLK - xor лог. 1 = 0} Lpt.WritePort (GetCurrentPort,2,(c xor Lpt.ReadPort( (GetCurrentPort) ,2) )); Gauge1.ForeColor := clScrollBar; //-- убираем отработ. проценты индикатора ТХ end; {Используем повтор передачи, снижая скорость автоматически если ошибка приёма} if CheckBox2.Checked = true then //-- вкл. автокоррекцию скорости передачи begin if Pin2 = true then //-- считаем ипульсы подтверждения приёма begin Edit6.Text := IntToStr(StrToInt(Edit6.Text)+1); //-- счётчик импульсов d := StrToInt(Edit6.Text); //-- преобразуем и присваиваем end; {Если цикл передачи окончен, сигнал упр. отключён} if CLK = false then if (d <> a) and( d <> b) then //-- если данные не совпадают: begin {Увеличиваем задержку - уменьшаем скорость ТХ посылок} TrackBar2.Position := TrackBar2.Position + 15 ; //-- на нужное значение Label7.Caption := 'Контроль Данные Бит CLK Управление Задержка : '+ IntToStr(TrackBar2.Position); //-- выводим значение задержки Timer2.Enabled := true; //-- вкл. таймер повтора ТХ end else begin //-- если данные совпали - отключаем систему beep; Edit6.Text := '0'; if d = b then Timer2.Enabled := false; end; end; Sleep(TrackBar2.Position); //--приложение засыпает на заданный интервал Application.ProcessMessages; //--Обработка всей очереди сообщений end; end; {Простой внутренний контрольный приёмник "RX1"} procedure TForm1.Timer4Timer(Sender: TObject); Var a : integer; begin a := 0; { -------------- Счётчик импульсов1 (Биты задаются Bits )--------------} if Edit3.Tag = 0 then //-- TAG = 0 : метка начала отсчета begin if Bits = true then begin //-- собственно счётчик a := a + 1; //-- фиксируем импульс Edit3.Text := IntToStr(StrToInt(Edit3.Text)+1); // -- принимаем импульсы end; Edit3.Tag :=1; //-- TAG = 1 : метка конца отсчета if a = 1 then ButtonPin2; // -- подтверждаем приём импульса, с помощью Рin2 end; if Bits = false then Edit3.Tag := 0; //-- разреш. отсчёт след. импульса { -------------- Счётчик импульсов2 (CLK )----------------------------} if Edit4.Tag = 0 then begin if CLK = true then Edit4.Text := IntToStr(StrToInt(Edit4.Text)+1); Edit4.Tag :=1; end; if CLK = false then Edit4.Tag := 0; { ---------------------------------------------------------------------} end; procedure TForm1.RadioButton1Click(Sender: TObject); //-- переключатель RX1 begin Timer4.Enabled := true; StopRX := true; Edit3.Text := '0'; end; procedure TForm1.RadioButton2Click(Sender: TObject); //-- переключатель RX2 begin Timer4.Enabled := false; RX2; Edit3.Text := '0'; end; procedure TForm1.RadioButton3Click(Sender: TObject); //-- переключатель OFF begin Timer4.Enabled := false; StopRX := true; Edit3.Text := '0'; end; procedure TForm1.TrackBar1Change(Sender: TObject); //-- показ задержки begin if TrackBar1.Position = 0 then Edit3.Color := clyellow else Edit3.Color := clInfoBk; Label6.Caption := 'Задержка RX2 м.сек : ' + IntTOStr(TrackBar1.Position); end; procedure TForm1.SpeedButton5Click(Sender: TObject); begin RichEdit1.Lines.SaveToFile('RX_Lod.txt'); //-- сохраняем в файл end; procedure TForm1.TrackBar2Change(Sender: TObject); //-- показ. задержку begin Label7.Caption := 'Контроль Данные Бит CLK Управление Задержка : '+ IntToStr(TrackBar2.Position); end; procedure TForm1.Timer2Timer(Sender: TObject); //-- таймер повтора передачи Var b,d : integer; begin b := StrToInt(Edit2.Text) ; //-- преобразуем d := StrToInt(Edit6.Text) ; //-- преобразуем SpeedButton2.Click ; if (d = b) then //-- отключ. автоматически Timer2.Enabled := false ; end; end.
end;
****** Валерий Ковтун US4LEH http://valery-us4leh.narod.ru О сайте Вернуться на Шаг5. Системы автоматизации процессов: Digital Avto Tuning - программа автоматической подстройки кода Вернуться на XP LPT Вернуться на главную страницу Чтобы открыть ссылку в новом окне - удерживайте клавишу Shift Программа PortControl V3+ Программа PinRegistrator D1+ --> Гостевая книга --> Обратная связь |