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

Delphi Sources



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

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 30.03.2015, 11:15
sforce sforce вне форума
Прохожий
 
Регистрация: 30.03.2015
Сообщения: 4
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию Передать двоичный код в COM

Добрый день. Помогите, пожалуйста, по следующему вопросу.
У меня данные типа string отправляются на com порт с помощью следующей процелуры:

Код:
Procedure WriteStrToPort(Str:String);
Var
ByteWritten:cardinal;
MyBuff:Array[0..1023] Of Char;
Begin

FillChar(MyBuff,SizeOf(MyBuff),#0);
Str:=Str+#13#10;
StrPCopy(MyBuff,Str);
If Not WriteFile(hPort,MyBuff,Length(Str),ByteWritten,Nil) Then
Begin
SysErrorMessage(GetLastError);
fmMain.btnStop.Click;
Exit;
End;
End;

Все работает, но мне необходимо отправить команду в двоичном виде, со следующими условиями

Цитата:
Длина посылки от компьютера к компаратору фиксированная – 4 байта.
Состав посылки:
SOM=0x01 – заголовок
CMD – команда
DAT0 – данные, если нужны
DAT1 – данные, если нужны
EOF=0x1a – конец посылки
Таким образом, минимальная длина посылки – 3 байта.
Необходимая команда GETCOUNT - 0x3a

Подскажите, как необходимо изменить код?
Ответить с цитированием
  #2  
Старый 30.03.2015, 11:46
CynicRus CynicRus вне форума
Прохожий
 
Регистрация: 26.02.2013
Сообщения: 30
Версия Delphi: Lazarus, XE 3.
Репутация: 10
По умолчанию

Код:
function Write(const Buffer: array of Byte;
 NumberOfBytesToWrite: Cardinal): Cardinal;
begin
 Result := 0;
 if FPortHandle <> INVALID_HANDLE_VALUE then
 begin
   WriteFile(hPort, Buffer, NumberOfBytesToWrite, Cardinal(Result),
     @OverlappedWrite);
 end;
end;

Где OverlappedWrite - TOverlapped.
Соответствтенно забиваешь свои в массив байт и высылаешь в порт.
Ответить с цитированием
Этот пользователь сказал Спасибо CynicRus за это полезное сообщение:
sforce (16.04.2015)
  #3  
Старый 30.03.2015, 13:04
sforce sforce вне форума
Прохожий
 
Регистрация: 30.03.2015
Сообщения: 4
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию

Код:
buffer[0]:=0x01;
buffer[1]:=0x3a;
buffer[2]:=0x1a;

Так?
Ответить с цитированием
  #4  
Старый 30.03.2015, 14:16
Аватар для Aristarh Dark
Aristarh Dark Aristarh Dark вне форума
Модератор
 
Регистрация: 07.10.2005
Адрес: Москва
Сообщения: 2,906
Версия Delphi: Delphi XE
Репутация: выкл
По умолчанию

1. Убери из своей процедуры записи в порт (Procedure WriteStrToPort(Str:String) ; ) строку 8.
2. Вызывай так: WriteStrToPort(#$01#$3A#$1A);
3. Profit
__________________
Некоторые программисты настолько ленивы, что сразу пишут рабочий код.

Если вас наказали ни за что - радуйтесь: вы ни в чем не виноваты.
Ответить с цитированием
Этот пользователь сказал Спасибо Aristarh Dark за это полезное сообщение:
sforce (16.04.2015)
  #5  
Старый 30.03.2015, 14:55
CynicRus CynicRus вне форума
Прохожий
 
Регистрация: 26.02.2013
Сообщения: 30
Версия Delphi: Lazarus, XE 3.
Репутация: 10
По умолчанию

Цитата:
Сообщение от sforce
Код:
buffer[0]:=0x01;
buffer[1]:=0x3a;
buffer[2]:=0x1a;

Так?

Ну да. (10 символов)
Ответить с цитированием
  #6  
Старый 30.03.2015, 15:10
icWasya icWasya вне форума
Местный
 
Регистрация: 09.11.2010
Сообщения: 499
Репутация: 10
По умолчанию

И уточните, хотя бы для себя, какая версия Дельфи, и String - это AnsiString или WideString ?
Ответить с цитированием
  #7  
Старый 16.04.2015, 14:58
sforce sforce вне форума
Прохожий
 
Регистрация: 30.03.2015
Сообщения: 4
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию

Спасибо, вроде отсылает. Теперь следующая проблема)
Устройство, с которым связан компьютер через COM отправляет ответ. И программа его принимает, правда почему-то стабильно через раз (то принимает - то не принимает). НО я так понимаю не может корректно отобразить. Потому что количество принятых байт увеличивается, а memo пополняется лишь одним пробелом. С другим устройством, где передавались данные обычной строкой и без запросов, все работало нормально.
Код такой:
Код:
Procedure TCommThread.Execute;
Begin
Repeat
QueryPort;//процедура опроса порта будет производиться пока поток не будет прекращен
Until Terminated;
End;

Procedure TCommThread.QueryPort;
Var
MyBuff:Array[0..1023] Of Char;//буфер для чтения данных
ByteReaded:cardinal; //количество считанных байт
Str:String;         //вспомогательная строка
Status:DWord;       //статус устройства (модема)
Begin
//получим статус COM-порта устройства (модема)
If Not GetCommModemStatus(hPort,Status) Then
Begin {ошибка при получении статуса модема}
SysErrorMessage(GetLastError);
Exit;
End;

//читаем буфер из Com-порта

FillChar(MyBuff,SizeOf(MyBuff),#0);
If Not ReadFile(hPort,MyBuff,SizeOf(MyBuff),ByteReaded,Nil) Then
Begin
SysErrorMessage(GetLastError);
Exit;
End;

If ByteReaded>0 Then
Begin

ReciveBytes:=ReciveBytes+ByteReaded;
Str:=String(MyBuff);
fmMain.Memo1.Text:=fmMain.Memo1.Text+ Str;
fmMain.lbRecv.Caption:='Принято: '+IntToStr(ReciveBytes)+' байт...';
End;
End;
В работе с байтами не очень силен, да и с портами в целом тоже. Так что очень нуждаюсь в помощи.
Возможно данная информация поможет:
Цитата:
Ответ устройства имеет переменную длину и содержит контрольную сумму. Контрольная сумма считается как сумма всех последующих за ней байт по модулю 32768, включая символ EOF, и передается полубайтами (с прибавлением к каждому полубайту 0x30, чтобы получился ASCII-символ), начиная с младшего полубайта.
Ответить с цитированием
Ответ


Delphi Sources

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

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

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

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


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


 

Сайт

Форум

FAQ

RSS лента

Прочее

 

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

ВКонтакте   Facebook   Twitter