#delphi #serial-port #hyperterminal
#delphi #последовательный порт #hyperterminal
Вопрос:
Я создаю простую программу на Delphi для отправки символа через COM-порт, используя 2 параметра, первый параметр — это номер порта, а второй параметр — это символ, который нужно отправить. Итак, если я сохраню его как p.exe , «p.exe 20 A» отправит «A» через COM20.
try
PhoneNumber := ParamStr(2);
if(StrToInt(ParamStr(1))>=10)then
CommPort := '\.COM' ParamStr(1)
else
CommPort := 'COM' ParamStr(1);
hCommFile := CreateFile(PChar(CommPort),
GENERIC_WRITE,
0,
nil,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
0);
if hCommFile=INVALID_HANDLE_VALUE then begin
ShowMessage('Unable to open ' CommPort);
end;
if WriteFile(hCommFile, PChar(PhoneNumber)^, Length(PhoneNumber),NumberWritten, nil)=false then
showmessage('Unable to send');
PurgeComm(hCommFile,PURGE_TXCLEAR);
FlushFileBuffers(hCommFile);
CloseHandle(hCommFile);
Application.Terminate;
except
PurgeComm(hCommFile,PURGE_TXCLEAR);
FlushFileBuffers(hCommFile);
Application.Terminate;
end;
И я также использую hyperterminal с тем же номером COM baudrate= 9600, flow_control= none, и это дает тот же результат. Символ отправлен правильно.
Проблема в том, что я не могу запустить свою программу (p.exe ), прежде чем я буду выполнять следующие действия каждый раз при входе в свою Windows XP:
Подключитесь через hyperterminal к указанному COM,
отключите его.
тогда мой исполняемый файл может быть запущен. В противном случае, точно так же, как вы запускаете два сеанса hyperterminal в одном и том же COM, это не сработает. У кого-нибудь есть намек на это? Я что-то пропустил в своем коде?
Комментарии:
1. 1 за проверку работоспособности с помощью Hyperterminal.
2. Итак, «не работает», вы получаете сообщение об ошибке «невозможно открыть …», «невозможно отправить» или что?
3. вам нужно использовать setcommstate для скорости передачи данных в бодах.
4. Ваш обработчик исключений считывается
hCommFile
до того, как он обязательно был записан. Если первый параметр командной строки не числовой, вы очищаете и удаляете недопустимый дескриптор. Кроме того, в случаеCreateFile
сбоя вы продолжаете использоватьhCommFile
, даже если этоInvalid_Handle_Value
.5. Какие настройки скорости передачи, четности и управления потоком (аппаратные / программные / выключенные), по вашему мнению, будут использоваться? Если вы новичок в последовательных портах, могу я предложить вам использовать компонент (TComPort или AsyncPro).
Ответ №1:
Я не вижу никаких настроек в вашем коде. Так что, возможно, вы полагаетесь на побочный эффект запуска HyperTerminal, который «запускает» порт для вас. Взгляните на эту статью, где они проходят через это: скорость передачи данных, четность и т. Д..
http://www.delphi-central.com/serial.aspx
Кажется, это полный рабочий пример. Посмотрите, сможете ли вы заставить это работать, и используйте в качестве основы для сборки.
Ответ №2:
Вам нужно использовать setcommstate для настройки скорости передачи данных и управления потоком.
Function OpenPort( Var fHandle: THandle; fPort: String): Boolean;
Const
RxBufferSize = 32;
TxBufferSize = 32;
Var
dcb : TDCB;
tms : TCOMMTIMEOUTS;
Begin
Result := False;
Try
If fHandle <> INVALID_HANDLE_VALUE Then
CloseHandle( fhandle );
Except
End;
Try
//fport must be \. URN format
fhandle := CreateFile( PChar( fPort ), GENERIC_WRITE or GENERIC_READ, FILE_SHARE_WRITE ,
Nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0 );
If ( fhandle = INVALID_HANDLE_VALUE ) Then
Begin
result := false;
exit;
End;
SetupComm( fhandle, RxBufferSize, TxBufferSize );
If pos( 'LPT', fPort ) > 0 Then
//
Else
Begin
GetCommState( fhandle, dcb );
dcb.DCBlength := sizeof( dcb );
dcb.BaudRate := cbr_9600;
dcb.Flags := 1; // binary...
if dtr_rts then
begin
dcb.flags := dcb.Flags Or $20; //DTR HANDSHAKE
dcb.Flags := dcb.Flags Or $1000; //rts handshake
dcb.Flags := dcb.Flags Or 4; //Outx_CtsFlow
dcb.Flags := dcb.Flags Or 8; //Outx_DsrFlow
dcb.Flags := dcb.Flags Or $40; //DsrSensitivity
//dcb.Flags := dcb.Flags or $100;//Outx_XonXoffFlow
//dcb.Flags := dcb.Flags or $200;//Inx_XonXoffFlow
end;
dcb.ByteSize := 8;
dcb.Parity := EVENPARITY;
dcb.StopBits := ONESTOPBIT;
SetCommState( fhandle, dcb );
GetCommTimeouts( fhandle, tms );
tms.ReadIntervalTimeout := 100;//you can change multipler values with
tms.ReadTotalTimeoutMultiplier := 100;//your values
tms.ReadTotalTimeoutConstant := 1;
SetCommTimeOuts( fhandle, tms );
End;
EscapeCommFunction( fhandle, CLRRTS Or CLRDTR Or SETRTS Or SETDTR );//for handshaking
Result := True;
Except
Result := False;
End;
End;
использование
var
fporthandle:thandle;
begin
if OpenPort(fporthandle,'\.com1') then
try
writefile(fporthandle,pchar('TEST')...);
finally
closehandle(fporthandle);
end;
Комментарии:
1. устройства связи получают DCB по умолчанию при создании
2. @Преждевременный: Точно, но, возможно, скорость передачи данных DCB в бодах по умолчанию, четность, управление потоком и т.д. — это не совсем то, что нужно операционной системе. Лучше всего явно установить этот материал и сделать его видимым для пользователя. Когда вы закончите писать все материалы пользовательского интерфейса для com-порта, четности, конфигурации управления потоком, вы можете просто скачать и использовать
TComPort
. sourceforge.net/projects/comport3. тьфу, извините, создание с нуля, я имел в виду открытие (
CreateFile(OPEN_EXISTING)
). @Warren P, да, но defaults предназначен для использования вместо explicit . OP просто нужно предварительно настроить его порт. Кстати, эта ссылка кажется мне чрезмерно сложной.