Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Все о Delphi > [ "Начинающим" ]
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 30.09.2011, 10:27
devochka devochka вне форума
Прохожий
 
Регистрация: 02.11.2010
Сообщения: 31
Репутация: 10
По умолчанию Com-порт

Всем здраствуйте!!! Ребята такая проблема: Делаю курсовую на тему Управление внешними устройствами ......... Задание такое нужно написать программу которая бы управляла при помощи СОМ- порта каким либо простейшим устройством!!! Знакомый мальчик спаял мне диод с ресистором , мол говорит если получится зажеч этот диод значит программа заработает и сможешь дальше больше!!!! Кучу лит-ры перечитала научилась открывать порт,а вот как эту штуку заставить гореть не могу врубиться!!!
Подскажите что мне делать, или как делать!!! Горю(((((((((((((
От меня респектик и за ранее спасибо))))))))))
Ответить с цитированием
  #2  
Старый 30.09.2011, 11:53
Аватар для Aristarh Dark
Aristarh Dark Aristarh Dark вне форума
Модератор
 
Регистрация: 07.10.2005
Адрес: Москва
Сообщения: 2,906
Версия Delphi: Delphi XE
Репутация: выкл
По умолчанию

Схему электрическую покажи приборчика который тебе друг спаял.
__________________
Некоторые программисты настолько ленивы, что сразу пишут рабочий код.

Если вас наказали ни за что - радуйтесь: вы ни в чем не виноваты.
Ответить с цитированием
  #3  
Старый 30.09.2011, 12:23
devochka devochka вне форума
Прохожий
 
Регистрация: 02.11.2010
Сообщения: 31
Репутация: 10
По умолчанию

Нет там не приборчик! Просто резистор припаяный к светодиоду потом в ком порт RS 232! сказал подключил правильно, дерзай,я у же два дня дерзаю не как не получается.
Ответить с цитированием
  #4  
Старый 30.09.2011, 15:09
Аватар для Aristarh Dark
Aristarh Dark Aristarh Dark вне форума
Модератор
 
Регистрация: 07.10.2005
Адрес: Москва
Сообщения: 2,906
Версия Delphi: Delphi XE
Репутация: выкл
По умолчанию

Цитата:
Сообщение от devochka
Нет там не приборчик! Просто резистор припаяный к светодиоду потом в ком порт RS 232! сказал подключил правильно, дерзай,я у же два дня дерзаю не как не получается.
Вот жеж люди...
Компьютер тоже просто коробочка из нее проводки идут и телевозор... А программа почему-то не пишется...

Какой светодиод, номинал резистора, как спаяны, на какие ноги разъемы COM порта?
__________________
Некоторые программисты настолько ленивы, что сразу пишут рабочий код.

Если вас наказали ни за что - радуйтесь: вы ни в чем не виноваты.
Ответить с цитированием
  #5  
Старый 30.09.2011, 16:28
chainik chainik вне форума
Начинающий
 
Регистрация: 30.06.2008
Сообщения: 140
Репутация: 8882
По умолчанию

Аж слеза прошибла.

Отдаю свой интерфейсный модуль с прибором БРС-1М.

Объясняю суть.
В лаборатории метрологии имеется прибор измеряющий давление воздуха. Требуется периодически снимать показания и отсылать в БД и накапливать их там.
Это давление используется для введения поправок при калибровке авиационных барометрических высотомеров.

Прибор имеет интарфейс СОМ.
Работает он предельно просто.
Ты отсылаешь в прибор запрос- 1 байт равный $81
В ответ прибор выдает последовательность 7 байт
из них 1байт=$DA-это байт начала последовательности.
Далее 6 байт, каждый- это 1 разряд на индикаторе, ст. разряд-первый.
и это все.
Далее все это превращается в число и укладывается в БД. (но нам это пока не надо)

Полагаю, зачет будет!!!!!!!!
Вложения
Тип файла: zip Brs_1M.zip (30.6 Кбайт, 122 просмотров)
Ответить с цитированием
  #6  
Старый 02.10.2011, 10:13
devochka devochka вне форума
Прохожий
 
Регистрация: 02.11.2010
Сообщения: 31
Репутация: 10
По умолчанию

Я нашла компонент работы с ком портом BCPort называется ,а как его на форму выложить не могу понять!!!
Ответить с цитированием
  #7  
Старый 30.09.2011, 12:25
chainik chainik вне форума
Начинающий
 
Регистрация: 30.06.2008
Сообщения: 140
Репутация: 8882
По умолчанию

Попродуй мой модуль для работы с ком-портом.
Работает в WinXP
Но для таких задач часто используют Win98.
Дело в том что она позволяет прямое обращение к портам ввода-вывода (чего не допускает WinXP)
В этом случае все сильно упрощается.

Код:
unit ComDrv32;
{-----------------------------------------------------------------------
        Интерфейсный модуль работы с COM- портом барометра БРС-1М,
        термогигрометром FLUKE через COM
        по теме Метрология
------------------------------------------------------------------------}

interface
    uses
  Windows, Messages, SysUtils, Dialogs ;

{$H+}

function OpenPort(comName:string):integer;    //открыть COM-порт
procedure ClosePort;                        //закрыть COM-порт
function SendData( DataPtr: pointer; DataSize: integer ):dword;  //запись данных в порт
function ReadData( DataPtr: pointer; DataSize: integer ):dword; //читает порт в буфер

implementation


const
  dcb_Binary              = $00000001;
  dcb_ParityCheck         = $00000002;
  dcb_OutxCtsFlow         = $00000004;
  dcb_OutxDsrFlow         = $00000008;
  dcb_DtrControlMask      = $00000030;
  dcb_DtrControlDisable   = $00000000;
  dcb_DtrControlEnable    = $00000010;
  dcb_DtrControlHandshake = $00000020;
  dcb_DsrSensivity        = $00000040;
  dcb_TXContinueOnXoff    = $00000080;
  dcb_OutX                = $00000100;
  dcb_InX                 = $00000200;
  dcb_ErrorChar           = $00000400;
  dcb_NullStrip           = $00000800;
  dcb_RtsControlMask      = $00003000;
  dcb_RtsControlDisable   = $00000000;
  dcb_RtsControlEnable    = $00001000;
  dcb_RtsControlHandshake = $00002000;
  dcb_RtsControlToggle    = $00003000;
  dcb_AbortOnError        = $00004000;
  dcb_Reserveds           = $FFFF8000;

  ComPortHandle             = 0;       // Not connected
  ComPort                   :pchar= 'COM1';  // COM 2
  ComPortBaudRate           = cbr_1200;  // 9600 bauds
  ComPortDataBits           = 8; // 8 data bits
  ComPortStopBits           = 1; // 0 stop bit
  ComPortParity             = NOPARITY;  // no parity
  ComPortHwHandshaking      = 0;  // no hardware handshaking
  ComPortSwHandshaking      = 0;  // no software handshaking
  ComPortInBufSize          = 2048;    // input buffer of 2048 bytes
  ComPortOutBufSize         = 2048;    // output buffer of 2048 bytes
  ComPortReceiveData        = nil;     // no data handler
  ComPortPollingDelay       = 50;      // poll COM port every 50ms
  OutputTimeout             = 4000;    // output timeout - 4000ms
  EnableDTROnOpen           = true;    // DTR high on connect

var
porthandle:THandle=0;
lpDCB:TDCB;
lpCommTimeouts:TCommTimeouts;
Key:byte=13;

{--------------закрыть COM-порт--------------------}
procedure ClosePort;
begin
CloseHandle(PortHandle);
PortHandle:=0;
end;

{---------------------------------------------------------
    открыть порт
    возвращает код ошибки открытия
----------------------------------------------------------}
function OpenPort(comName:string):integer;
begin
if PortHandle=0 then
    begin
    PortHandle:= CreateFile(
                                pchar(comName),
                                GENERIC_READ or GENERIC_WRITE,
                                0, // Not shared
                                nil, // No security attributes
                                OPEN_EXISTING,
//                                0,
                                FILE_ATTRIBUTE_NORMAL,
                                0 // No template
                              ) ;

Result:= GetLastError;

    with lpCommTimeouts do
        begin
        ReadIntervalTimeout := 4; // Specifies the maximum time, in milliseconds,
                                // allowed to elapse between the arrival of two
                                // characters on the communications line
        ReadTotalTimeoutMultiplier := 8; // Specifies the multiplier, in milliseconds,
                                       // used to calculate the total time-out period
                                       // for read operations.
        ReadTotalTimeoutConstant := 1000; // Specifies the constant, in milliseconds,
                                     // used to calculate the total time-out period
                                     // for read operations.
        WriteTotalTimeoutMultiplier := 0; // Specifies the multiplier, in milliseconds,
                                        // used to calculate the total time-out period
                                        // for write operations.
        WriteTotalTimeoutConstant := 0; // Specifies the constant, in milliseconds,
                                      // used to calculate the total time-out period
                                      // for write operations.
        end;    //with
    with lpDCB do
        begin
        fillchar( lpdcb, sizeof(Tdcb), 0 );
        DCBLength := sizeof(Tdcb); // dcb structure size
        BaudRate:=ComPortBaudRate;
        Flags := dcb_Binary;
        XONLim := ComPortInBufSize div 4;
        XOFFLim := 1;
        ByteSize:=ComPortDataBits;
        Parity := ComPortParity;
        StopBits := ComPortStopbits;
        XONChar := #17;
        XOFFChar := #19;
        end;    //with
//    if not SetCommState(porthandle,lpDCB) then ShowMessage('ошибка SetCommState');
    PurgeComm(porthandle,PURGE_TXABORT or PURGE_RXABORT or PURGE_TXCLEAR or PURGE_RXCLEAR);
    if not SetCommTimeouts(porthandle,lpCommTimeouts) then ShowMessage('ошибка SetCommTimeout');
    SetupComm( ComPortHandle, ComPortInBufSize, ComPortOutBufSize );
    end;
end;


{--------------------------------------------------------------------
    функция записывает строку в порт
    возвращает колич записанных байт
----------------------------------------------------------------------}
function SendData( DataPtr: pointer; DataSize: integer ):dword;
var
n:dword;
begin
PurgeComm(porthandle,PURGE_TXABORT or PURGE_RXABORT or PURGE_TXCLEAR or PURGE_RXCLEAR);
//PurgeComm(porthandle,PURGE_TXABORT or PURGE_TXCLEAR);
WriteFile(porthandle,pchar(DataPtr^),DataSize,Result,nil);
WriteFile(porthandle,Key,1,n,nil);
if n <> 1 then Result:=0;
FlushFileBuffers(porthandle);
end;

{--------------------------------------------------------------------
    функция читает данные из порта
    возвращает колич принятых байт
----------------------------------------------------------------------}
function ReadData( DataPtr: pointer; DataSize: integer ):dword;
begin
//PurgeComm(porthandle,PURGE_RXABORT or PURGE_RXCLEAR);
ReadFile(porthandle,DataPtr^,DataSize,Result,nil);
FlushFileBuffers(porthandle);
end;


end.
Ответить с цитированием
  #8  
Старый 30.09.2011, 12:39
chainik chainik вне форума
Начинающий
 
Регистрация: 30.06.2008
Сообщения: 140
Репутация: 8882
По умолчанию

и еще в догонку.
Тебе Обязательно потребуется тестовая программа.
С ее помощью ты сможешь отладить канал связи и вообще убедиться что он работает.
Я ее откопал в Инете. Чрезвычайно полезная вещь!

Не мучайся с исходником.
Я откомпилировал. См ComTestExe
Схема вызыает большие сомнения. Вряд ли ты что-то увидишь.
Процесс передачи байта очень быстрый. Ты не увидишь вспышки светодиода.
Или в твоей проге посылай TxD в цикле
Нормальное решение проблемы- соединить 2 компа через ком-порт и на них экспериментировать
Или возьми какой-нибудь прибор с интерфейсом COM
Вложения
Тип файла: zip comtest.zip (34.6 Кбайт, 240 просмотров)
Тип файла: zip ComTest_exe.zip (210.6 Кбайт, 114 просмотров)

Последний раз редактировалось chainik, 30.09.2011 в 12:59.
Ответить с цитированием
  #9  
Старый 04.10.2011, 15:35
Lucky192 Lucky192 вне форума
Прохожий
 
Регистрация: 04.10.2011
Сообщения: 28
Репутация: 1351
По умолчанию

Если нужно просто светодиодом поморгать, компоненты не нужны - и через WinApi все очень просто выходит. Вот код:
Код:
unit Unit1;
interface

uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
     Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  public
    COMHandle : cardinal;
  end;

var Form1: TForm1;

implementation

{$R *.dfm}

// Эта функция записывает в биты X, заданные в Mask значение Value.
//   т.е. если X = bxxxxxxxx; Mask = b00011100; Value = b00000010;
//   Значение X после выполнения функции станет  bxxx010xx;
procedure SetBits(var X:integer; Mask,Value:integer);
var temp:integer;
begin
  if Mask=0 then exit;
  temp:=1;
  while (Mask and temp)=0 do begin
    temp  := temp  shl 1;
    Value := Value shl 1;
  end;
  X := X and (not Mask);
  X := X or  (Value and Mask);
end;

procedure ClosePort(var Handle : cardinal);
begin
  if Handle = INVALID_HANDLE_VALUE then exit;
  CloseHandle(Handle);
  Handle := INVALID_HANDLE_VALUE;
end;

function OpenPort(const COMName:string) : cardinal;
var DCB:_DCB;
begin
  // Открытие порта
  Result := CreateFile(
                        PChar(ComName),
                        GENERIC_READ+GENERIC_WRITE,
                        0,
                        nil,
                        OPEN_EXISTING,
                        0,
                        0
                       );
  // Если удалось открыть порт - конфигурируем его
  if Result=INVALID_HANDLE_VALUE then exit;
  try
    // Запрещаем автоматическое управление линией DTR -> будем управлять вручную
    GetCommState(Result,DCB);
    SetBits(DCB.Flags,(3 shl 4),DTR_CONTROL_DISABLE);
    SetCommState(Result,DCB);
  except
    ClosePort(Result);
  end;
end;

// Управление линией DTR (нога 4 на разъеме DB9 COM порта)
function Set_DTR_Pin(Handle:cardinal; State:boolean):boolean;
const States : array [False..True] of cardinal = (CLRDTR,SETDTR);
begin
  Result := false;
  if Handle=INVALID_HANDLE_VALUE then exit;
  Result := EscapeCommFunction(Handle,States[State]); // Управление линией DTR
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  Set_DTR_Pin(COMHandle,true);
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  Set_DTR_Pin(COMHandle,false);
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  COMHandle := OpenPort('COM1');
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  ClosePort(COMHandle);
end;

end.
Приблуду со светодиодом подключать к 4 и 5 ногам COM-порта (полярность неважна - все равно обе будут ).
Ответить с цитированием
  #10  
Старый 04.10.2011, 17:33
Lucky192 Lucky192 вне форума
Прохожий
 
Регистрация: 04.10.2011
Сообщения: 28
Репутация: 1351
Лампочка Немного общей информации по порту RS232

На 9-ти контактном разъеме COM-порта всего есть 8 сигнальных линий: 5 на вход и 3 на выход. Из этих 8 линий, две отвечают за прием/передачу данных (одна линия на передачу и одна на прием). Эти две линии - это, собственно и есть основа COM-порта. Остальные 6 линий - вспомогательные, они используются не для передачи данных, а для управления процессом передачи. За передачу/прием данных отвечают функции ReadFile/WriteFile. За чтение/установку состояний вспомогательных линий в ручном режиме отвечают функции GetCommModemStatus/EscapeCommFunction (еще эти линии могут управляться аппаратно - при соответствующих настройках COM-порта).

Очевидно что для управления устройством можно использовать только выходные линии. Их всего три - это TX, DTR, RTS. Линию TX нельзя установить в фиксированное состояние - она может лишь выдавать данные, бит за битом, с установленной скоростью. За выдачу данных по линии TX отвечает функция WriteFile. Линии DTR, RTS можно переключить в фиксированное состояние: лог. 0 или 1 (Если, разумеется, не активирован какой-нибудь автоматический режим. Если активирован - состояние линий будет устанавливаться аппаратно). Максимальная скорость, переключения линий DTR,RTS может достигать нескольких десятков килогерц, поэтому на них вполне можно реализовать какой-нибудь протокол.

Вот перечень команд для установки состояния линий DTR/RTS:
Код:
EscapeCommFunction(Handle,CLRDTR); // лог.0 на линии DTR (-12В на ноге 4)
EscapeCommFunction(Handle,SETDTR); // лог.1 на линии DTR (+12В на ноге 4)
EscapeCommFunction(Handle,CLRRTS); // лог.0 на линии RTS (-12В на ноге 7)
EscapeCommFunction(Handle,SETRTS); // лог.1 на линии RTS (+12В на ноге 7)

Вот функции для передачи данных по линии TX:
Код:
var Buffer:AnsiString; BytesWritten:cardinal;
  ...
  Buffer := 'AT COMMAND'; // Строка
  Buffer := #$00#$01#$02#$03; // А так можно и бинарные данные передать.
  WriteFile(Handle,Buffer[1],length(Buffer),BytesWritten,nil);
  WriteFileEx(...); // Пример вызова этой функции намного сложнее.

P.S. Если в вашей схеме только светодиод и резистор, светодиод вполне может быть пробит при обратной полярности. Лучше вместо одного светодиода включить встречно-параллельно два светодиода разного цвета - и надежно и смотрится хорошо.
Ответить с цитированием
  #11  
Старый 04.10.2011, 19:06
chainik chainik вне форума
Начинающий
 
Регистрация: 30.06.2008
Сообщения: 140
Репутация: 8882
По умолчанию

Привожу драйвер ком- порта для Win95/Win98
Обрати внимание насколько здесь все проще.
Чтобы отослать байт ты просто отправляешь его в порт
(команды IN/OUT)
К сожалению в WinXP этот трюк уже не работает. Система не допускает прямого обращения к портам ввода/вывода. Это элемент защиты.
У меня на предприятии есть стенды с такой системой. Заменить уже не на что...

Код:
unit Port95;
{**********************************************************************
 * Description:	Port95 - very simple unit, that lets you access port	*
 * 							under Window 95,not under Windows NT.									*
 * Status:			Freeware																							*
 *							You can freely use or distribute this unit						*
 * Target:			Delphi 2 and Windows 95																*
 * Version:			1.0 (April 27, 1997																		*
 * Status:			Freeware																							*
 * Author:			Anatoly Podgoretsky																		*
 * Address:			kvk@estpak.ee																					*
 * Tips:				font Courier, tabs = 2																*
 * Problems:		Word Read/Write utulities may problems on some 				*
 *							computers or interface cards, that can't access whole	*
 *							word. To prevent it You can use slow equivalent of		*
 *							these	 procedures with suffix LS											*
 * Copyright:		Copyright (C) 1997, NPS																*
 **********************************************************************}

interface

function PortReadByte(Addr:Word)	 : Byte;
function PortReadWord(Addr:Word)	 : Word;
function PortReadWordLS(Addr:Word) : Word;
procedure PortWriteByte(Addr:Word; Value:Byte);
procedure PortWriteWord(Addr:Word; Value:Word);
procedure PortWriteWordLS(Addr:Word; Value:Word);

implementation

{****************************************************************
 * Port Read byte function																			*
 * Parameter: port address		 																	*
 * Return: 		byte value from given port 												*
 ****************************************************************}
function PortReadByte(Addr:Word) : Byte; assembler; register;
asm
	MOV	DX,AX
  IN	AL,DX
end;
{****************************************************************
 * HIGH SPEED Port Read Word function														*
 * Parameter: port address		 																	*
 * Return:	 	word value from given port 												*
 * Comment: 	may problem with some cards and computers					*
 *						that can't to access whole word, usualy it work.	*
 ****************************************************************}
function PortReadWord(Addr:Word) : Word; assembler; register;
asm
	MOV	DX,AX
  IN	AX,DX
end;
{****************************************************************
 * LOW SPEED Port Read Word function														*
 * Parameter: port address		 																	*
 * Return:	 	word value from given port 												*
 * Comment: 	work in all cases, only to adjust DELAY if need		*
 ****************************************************************}
function PortReadWordLS(Addr:Word) : Word; assembler; register;
const
	Delay = 150;		// depending of CPU speed and cards speed
asm
	MOV		DX,AX
  IN		AL,DX			// read LSB port
	MOV		ECX,Delay
@1:
	LOOP	@1				// delay between two reads
	XCHG	AH,AL
  INC		DX				// port+1
	IN		AL,DX			// read MSB port
	XCHG	AH,AL			// restore bytes order
end;
{****************************************************************
 * Port Write byte function																			*
 * Parameter: port address		 																	*
 ****************************************************************}
procedure PortWriteByte(Addr:Word; Value:Byte); assembler; register;
asm
	XCHG	AX,DX
	OUT		DX,AL
end;
{****************************************************************
 * HIGH SPEED Port Write word procedure													*
 * Comment: 	may problem with some cards and computers					*
 *						that can't to access whole word, usualy it work.	*
 ****************************************************************}
procedure PortWriteWord(Addr:word; Value:word); assembler; register;
asm
	XCHG	AX,DX
	OUT		DX,AX
end;
{****************************************************************
 * LOW SPEED Port Write Word procedure													*
 * Parameter: port address		 																	*
 * Return:	 	word value from given port 												*
 * Comment: 	work in all cases, only to adjust DELAY if need		*
 ****************************************************************}
procedure PortWriteWordLS(Addr:word; Value:word); assembler; register;
const
	Delay = 150;		// depending of CPU speed and cards speed
asm
	XCHG	AX,DX
	OUT		DX,AL			// port LSB
	MOV		ECX,Delay
@1:
	LOOP	@1				// delay between two writes
	XCHG	AH,AL
  INC		DX				// port+1
	OUT		DX,AL			// port MSB
end;

end.
Ответить с цитированием
  #12  
Старый 04.10.2011, 23:54
Lucky192 Lucky192 вне форума
Прохожий
 
Регистрация: 04.10.2011
Сообщения: 28
Репутация: 1351
По умолчанию

Цитата:
Сообщение от chainik
Привожу драйвер ком- порта для Win95/Win98
К сожалению в WinXP этот трюк уже не работает. Система не допускает прямого обращения к портам ввода/вывода. Это элемент защиты.
У меня на предприятии есть стенды с такой системой. Заменить уже не на что...
Управление аппаратными ресурсами - это основная задача всех многозадачных операционных систем. Неотъемлемой частью такого управления является изоляция программ пользовательского режима от аппаратуры (система не допускает прямого обращения к аппаратной части). Если хотите прямой доступ к аппаратным портам, к памяти, к процессору - становитесь частью ОС, пишите драйвер. Иначе из процессора вытеснят, память кусками выгрузят на диск, а к порту доступа не дадут, т.к. кто-то его уже занял...

Однако не все так плохо, и подобный трюк все-таки работает под XP. Дело в том, что привилегии для кода выполняемого в пользовательском режиме гибко настраиваются. Привилегии процесса задаются табличным способом. К каждому процессу привязан набор таблиц, отвечающих за привилегии, виртуальную память и т.д. В том числе есть и таблица, отвечающая за доступ к портам ввода-вывода (I/O Permission Map). Естественно, что по умолчанию доступ ко всей аппаратуре для приложений закрыт. Также пользовательским приложениям запрещена работа с таблицами привелегий. Но разрешена для драйверов. К счастью, такие драйвера уже давно написаны. Самый простой - это giveio.sys, он дает открывшему его приложению доступ ко всему диапазону портов ввода вывода.

Принцип работы giveio.sys простой:
1. Сначала нужно установить драйвер в систему. Это можно сделать многими способами. Например специальной утилитой (LoadDrv.exe). Еще можно загрузить драйвер прямо из программы, воспользовавшись функциями API. Это достаточно сделать один раз, в дальнейшем драйвер будет загружаться вместе с системой.
2. Нужно подключиться к драйверу giveio.sys. Драйвер обнаружит это подключение и автоматически разрешит доступ ко всем портам для вызывающего процесса. Подключение к драйверу выполняется через функцию CreateFile. В качестве имени файла нужно передать строку '\\.\giveio';
3. Все. Доступ к портам для данного процесса открыт. Можно закрывать хэндл драйвера - доступ сохраниться вплоть до завершения работы процесса.

Есть и другие подобные драйверы. С их помощью, например, можно открыть доступ не ко всем портам, а лишь к определенному диапазону. Или открыть доступ для другого процесса.

Цитата:
Сообщение от chainik
Обрати внимание насколько здесь все проще.
Чтобы отослать байт ты просто отправляешь его в порт
(команды IN/OUT)
Это обманчивая простота. Вот примеры вызова функций WinAPI для замены всех функций модуля Port95:
Код:
ReadFile(h,ByteValue,1,tmp,nil);  // function PortReadByte(Addr:Word):Byte;             
ReadFile(h,WordValue,2,tmp,nil);  // function PortReadWord(Addr:Word)	 : Word;
ReadFile(h,WordValue,2,tmp,nil);  // function PortReadWordLS(Addr:Word) : Word;
WriteFile(h,ByteValue,1,tmp,nil); // procedure PortWriteByte(Addr:Word; Value:Byte);
WriteFile(h,WordValue,2,tmp,nil); // procedure PortWriteWord(Addr:Word; Value:Word);
WriteFile(h,WordValue,2,tmp,nil); // procedure PortWriteWordLS(Addr:Word; Value:Word)
 
ReadFile(h,IntValue,4,tmp,nil);   // А такую функцию в Port95 еще добавлять надо ;)
WriteFile(h,IntValue,4,tmp,nil);  // также как и эту
Конечно, нужно еще где-то взять дескриптор h. Но и для Port95 нужно где-то взять адрес порта. Казалось бы чего уж проще - 378h, 278h - вот они (а при использовании WinAPI нужно еще CreateFile с кучей параметров вызывать, ошибки обрабатывать... фу-фу-фу!!!). Ан нет. Вот нужно нам 4 порта использовать. Есть 2 штатных (повезло - а то на новых ведь может и не быть) + ISA карта на 2 порта. Все еще просто? Усложним задачу: [в кабинете начальника] "...а еще чтоб с разными картами работало" (а вдруг карта сгорит а другой такой нет, но есть очень-очень похожая). Еще усложним: [в магазине] "Какие еще ISA-карты? Нету их в продаже и не будет, но в наличии есть PCI ( берите - последняя осталась! ) или PCIExpress или переходник USB-COM. Что будете брать?" (А в WinAPI - вот он я - уже ставлю драйвер для купленного чего-то там, меняю строчку 'COM1' на 'COM18', дописываю еще 10 строк сложного, лишнего, страшного своей бесполезностью кода... Вот-вот завершу переделки! -[ехидно потирает ручки]- )

Еще осталась неохваченной настройка COM-порта. Ее нужно писать самому, в Port95.pas этого нет. Не надеяться же на то, что порт до нас уже кто-то настроил. Какой-то особенной простоты настройки при прямом доступе к портам нет. Будем считать ничья.

Ну и конечно же, мое самое любимое: СКОРОСТЬ!!! Казалось бы - ассемблерные функции. Да там тормозить просто нечему!!! Ан нет и тут засада... Есть такая инструкция OUT. Она-то нам всю малину и испортила. Больно уж долго выполняется (быстрее скорости порта не разгонишься, а это очень медленно даже для систем 20-летней давности). А дальше оптимизировать уже некуда - и так две инструкции. Еще момент: [ситуация] оборудование попалось настырное - шлет и шлет данные непрерывным потоком на полной скорости. Скорость приема байт хоть и небольшая (каких-то 10 кГц всего), но и квант времени в системе немаленький - 18 миллисекунд. Кто-то процессор занял чуть дольше положенного - и PortReadByte не выполнялся в течении 10 мс. Хорошо что есть буфер FIFO! Целых 16 байт. На 16 мс. Мда, уже не хватает - могут быть потери данных (вот она проклятая многозадачность где боком вылезла) - надо что-то думать... А в WinAPI - дописал 100 строк сложного кода и у тебя как-то все само-собой в буфере появляется - успевай только обрабатывать.

Последний раз редактировалось Lucky192, 05.10.2011 в 04:30.
Ответить с цитированием
  #13  
Старый 05.10.2011, 01:24
chainik chainik вне форума
Начинающий
 
Регистрация: 30.06.2008
Сообщения: 140
Репутация: 8882
По умолчанию

благодарю за отличную статью.
прочитал с большим интересом.
я собственно привел этот пример только чтобы продемонстрировать
2 подхода-прямой доступ к портам (win95) и доступ через файл (WinXP)
Когда речь идет о чисто техническом применении то как правило скорости хватает с избытком, хотя риск потерятьинформацию остается.
Мы решали эту проблему передачей контрольной суммы. Если не совпала- то повторная передача пакета.
В итоге у нас до сих пор работают машины Win98. И даже (страшно сказать) DOS! И процессор 86! между прочим с работой справляются. Да и заморачиваться с многозадачностью не надо.
Переписапь ПО- руки не доходят. Да и смысла копаться в старье нет.

Однако мы увлеклись теорией, а ведь человеку надо зачет получить...

Последний раз редактировалось chainik, 05.10.2011 в 01:51.
Ответить с цитированием
  #14  
Старый 15.11.2011, 10:36
Аватар для NumLock
NumLock NumLock вне форума
Let Me Show You
 
Регистрация: 30.04.2010
Адрес: Северодвинск
Сообщения: 5,426
Версия Delphi: 7, XE5
Репутация: 59586
По умолчанию

Цитата:
Сообщение от devochka
Ребята такая проблема: Делаю курсовую на тему Управление внешними устройствами ......... Задание такое нужно написать программу которая бы управляла при помощи СОМ- порта каким либо простейшим устройством!!!

Может кто-то еще захочет поуправлять устройствами с компьютера

USB модуль Ke-USB24A

Линии ввода/вывода: 24 штуки
АЦП: 1 штука (10 бит)
Описание:
Модуль Ke-USB24A предназначен для сопряжения внешних цифровых и аналоговых устройств, датчиков и исполнительных механизмов с компьютером через шину USB. Определяется как дополнительный (виртуальный) COM порт. Модуль имеет 24 дискретные линии ввода/вывода (либо лог. 0 либо лог. 1) с возможностью настройки направления передачи данных (вход/выход) и встроенный 10-ти разрядный АЦП. Для управления модулем предусмотрен набор текстовых команд управления (KE - команды).

USB модуль Ke-USB24R

Линии ввода/вывода: 18 штук
Реле: 4 штуки
АЦП: 4 штуки
Описание:
Модуль Ke-USB24R предназначен для сопряжения внешних цифровых и аналоговых устройств, датчиков и исполнительных механизмов с компьютером через шину USB. Имеет в совем составе четыре мощных реле для управления высоковольтными цепями и нагрузками. Определяется как дополнительный (виртуальный) COM порт. Модуль имеет 18 дискретных линии ввода/вывода (либо лог. 0, либо лог. 1) с возможностью настройки направления передачи данных (вход/выход) и 4 встроенных 10-ти разрядных АЦП. Для управления модулем предусмотрен набор текстовых команд управления (KE - команды).

Ethernet модуль Jerome

Jerome
Ethernet модуль для управления внешними цепями / нагрузками и мониторинга / измерения различных параметров (напряжение, температура и т.д.) по локательной сети (LAN).
Линии ввода/вывода: 22 штуки
АЦП: 4 штуки
Счетчик импульсов: 4 штуки
ШИМ выход, USART
Web-интерфейс управления
Командный интерфейс по TCP/IP
Описание:
Модуль Jerome предназначен для управления внешними цепями/нагрузками и мониторинга / измерения различных параметров (напряжение, температура и т.д.). Главной особенностью Jerome является поддержка Ethernet. Это означает что модулем можно управлять по сетевому кабелю (витой паре). Это позволяет размещать модуль на значительном расстоянии от управляющего компьютера (сотни метров). Управление осуществляеся набором текстовых команд управления по TCP/IP протоколу или через встроенный Web-интерфейс.

Модуль имеет встроенную Web-страницу управления. Достаточно запустить любой браузер, ввести IP адрес модуля (по умолчанию 192.168.0.101) и вы получаете удобный визуализирован ный интерфейс для управления различными ресурсами модуля и мониторинга его параметров в режиме реального времени.

Есть и другие интересные приборы
__________________
Пишу программы за еду.
__________________
Ответить с цитированием
  #15  
Старый 15.11.2011, 11:33
Аватар для PhoeniX
PhoeniX PhoeniX вне форума
Always hardcore!
 
Регистрация: 04.03.2009
Адрес: СПб
Сообщения: 3,239
Версия Delphi: GCC/FPC/FASM
Репутация: 62149
По умолчанию

Вот был бы модуль с Ethernet и высоковольтными релюшками - присобачил бы под "умный дом", чтобы при поступлении сигнала с IP-камеры (с микрофоном), например, по хлопку или по движению (ну, можно даже в зависимости от времени суток) включался/выключался свет А так... Не, по USB тоже как вариант, но портов лишних нет, на и большинство компов на линуксе. Лениво костыли прикручивать
__________________
Оставайтесь хорошими людьми...
VK id2634397, ds [at] phoenix [dot] dj
Ответить с цитированием
Ответ


Delphi Sources

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра
Комбинированный вид Комбинированный вид

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 15:10.


 

Сайт

Форум

FAQ

RSS лента

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2023

ВКонтакте   Facebook   Twitter