Не могу, кажется, получить ответ вир ком-порт

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

НАПРИМЕР

(я) установить attrib= да

(Dev. Board) ОК

или же

(Dev. Board) ERR

Но ничего не приходит в норму... ни ОК, ни ERR

в то время как плата загружается, эхо включено... поэтому, если я отправлю команды, пока плата загружается, она отскочит "set attrib=yes" и однажды загрузит "ERR", потому что вы не можете отправлять команды во время загрузки.

я думаю, что он не читает ответ вовремя или не пытается прочитать его слишком рано.

procedure TReaderProgrammer.Button2Click(Sender: TObject);
Var 
  Buffer: AnsiString; 
  RxData: string; 
  Count : integer;
begin
  if ComPort1.Connected then
  begin
    ComPort1.WriteStr(edtSendText.Text+#13);
    comport1.ReadStr(RxData,Count);
    Buffer := Buffer + Rxdata;
    memoRxData.Text := memoRxData.Text+Buffer+#13+#10;
  end;
end;

1 ответ

Решение

Вот несколько открытых вопросов в воздухе, поэтому я должен сделать некоторые предположения, которые могут быть неправильными, но давайте посмотрим.

Я не знаю, какую библиотеку COM-портов вы используете, поэтому я предполагаю, что это библиотека CPort из SourceForge. Я никогда не использовал его сам, но я читал, что он осведомлен о Юникоде, так что вы можете вызывать методы записи с уникальным параметром, который будет преобразован библиотекой в ​​ansistring перед отправкой. Точно так же при получении отклика из внешнего мира библиотека преобразуется в уникальную для методов Read.

Из-за асинхронного характера последовательной связи важно понимать, что когда вы отправляете что-либо с использованием метода записи, метод возвращается немедленно, в то время как библиотека и ОС выплевывают символы по одному за раз со скоростью, определяемой скоростью передачи данных. В результате ваш первый код никогда не получал ничего, потому что вы уже пытались читать с порта связи, прежде чем внешнее устройство даже не получило первый символ. Приятно видеть, что вы сделали первый шаг к успеху, реализовав обработчик событий для (предположительно, библиотечного события) OnRxChar.

OnRxChar, вероятно, срабатывает для каждого символа (или пары символов). У вас должен быть постоянный буфер между этими событиями. Локальная переменная (как она есть сейчас и которая размещена в стеке) в обработчике событий не является постоянной, она теряется при каждом выходе из обработчика событий. Вы должны объявить переменную Buffer как поле TReaderProgrammer. Я не знаю, почему вы определили буфер как AnsiString, но я предлагаю вам попробовать со строкой (см. Обсуждение выше относительно понимания Unicode).

type
  TReaderProgrammer = class
    ..
    RxBuffer: string;
    ..
  end;

Буфер должен быть очищен при отправке новой команды на внешнее устройство, чтобы оно было готово для получения новых данных в ответ на вашу команду.

РЕДАКТИРОВАТЬ: В качестве альтернативы вы можете очистить RxBuffer немедленно, когда вы получили и обработали полный ответ.

TReaderProgrammer.ComPort1RxChar должен выглядеть следующим образом:

procedure TReaderProgrammer.ComPort1RxChar(Sender: TObject; Count: Integer);
var
  RxData : string;
begin
  (Sender as TComPort).ReadStr(RxData,Count);
  RxBuffer := RxBuffer + Rxdata;
  ...
end;

Остальная часть обработчика событий, я думаю, вероятно, просто чтобы увидеть прогресс приема, так что ничего более об этом.

Другие вопросы по тегам