end;
Кроме этого, конечно, следует создать меню для выбора порта по ходу работы с программой (аналогичное меню СОМв моей программе СОМ2000, но мы не будем здесь на этом останавливаться, т. к. на основе приведенной процедуры его создать несложно.
Итак, порт открыт, инициализирован с нужными параметрами — что дальше? Далее все очень непросто, потому что мы здесь не можем, как в DOS, зациклить программу в ожидании поступившего байта или нажатия клавиши. Windows и сама представляет собой бесконечный цикл в ожидании сообщений (событий) — в точности такой же, как мы организовывали у себя в контроллере в ожидании прерываний. И вот этими сообщениями мы и должны ее снабдить.
Сначала разберем простейший способ обмена данными: когда мы точно знаем, что нам придет в ответ и в каком количестве. Например, посмотрим, как можно организовать процедуру приема значения часов в ответ на команду $А2(описание того, как это работает в контроллере, см. главу 16 ). Расставим на форме следующие компоненты: кнопку Button1, а также Labelи напротив него StaticText, и то и другое в количестве 6 штук. В компоненты Label запишем, соответственно, по порядку: «Часы», «Минуты», «Секунды», «Дата», «Месяц», «Год» (в таком же порядке их выдает наш контроллер). Листинг 18.3 иллюстрирует, как будет выглядеть сама процедура, когда по нажатию кнопки Button1в МК выдается команда $А2, а потом принятые значения выводятся в Static Text(т. к. они в BCD-формате, то приходится переводить в НЕХ-представление).
Листинг 18.3
procedure TForm1.ButtonlClick(Sender: TObject);
begin{запрос}
if (hCQM=0) or (hCOM=INVALID_HANDLE_VALUE) then exit;
{если порт еще не инициализирован — выход}
PurgeComm(hCOM,PURGE_RXCLEAR);{очищаем буфер}
xb:=$А2;
WriteFile(hCOM,xb,1,xn,nil);
told:=Time;
if ReadFile(hCOM,ab,6,xn,nil) then{читаем 6 байтов в массив ab}
begin
ttime:=Time;
if SecondsBetween(told,ttime)>0 then
begin
Application.MessageBox('Устройство не обнаружено','Error',MB_OK);
exit;
end;
if xn<>6 then
begin
Application.MessageBox('Неправильный формат данных', 1 Error',MB_OK);
exit;
end;
StaticText1.Caption:=IntToHex(ab[1],2)
StaticText2.Caption:=IntToHex(ab[2],2)
StaticText3.Caption:=IntToHex(ab[3],2)
StaticText4.Caption:=IntToHex(ab[4],2)
StaticText5.Caption:=IntToHex(ab[5],2)
StaticText6.Caption:=IntToHex(ab[6],2)
end else {если не сработало}
begin
Application.MessageBox('COM сломался','Error',MB_0K);
exit;
end;
end;
Результат будет выглядеть примерно так, как показано на рис. 18.7.
Рис. 18.7. Результат приема значений времени из часов-измерителя
Здесь процедура PurgeCommнужна для очистки приемного буфера, на случай, если там случайно задержались какие-то байты (те, кто работал с СОМ-портом в DOS, часто об этом забывают, т. к. там никаких буферов не было). Второй момент, который нужно прокомментировать, связан с возможным отсутствием нужного устройства на втором конце линии (или его неработоспособностью — включить забыли). Мы здесь, как видите, все делаем очень просто: читаем системное время до и после вызова функции ReadFile, и выясняем — если прошло более 1 с (a timeout у нас задан в 2 с), то «устройство не обнаружено». Опыт показывает, что это самый надежный метод. Если же связь каким-то образом прервется посередине посылки, то мы получим меньше байтов, чем заказывали, и программа выдаст сообщение «Неправильный формат данных». Не забудьте, что при работе с функциями времени в Delphi надо добавить ссылку на модуль DateUtils.
По той же схеме можно организовать взаимодействие с измерителем для всех наших команд, кроме команды чтения данных из flash-памяти. С ней сложности возникнут оттого, что мы точно не знаем, сколько данных нам придет, и когда пора заканчивать. В принципе можно обойтись тем же приемом с проверкой времени, т. к. данные поступают сплошным потоком, и когда поток этот прервется, то можно заканчивать. Организация процедуры тогда в некотором роде напоминает использование сторожевого таймера в МК: мы задаем в процедуре чтения максимальное количество принимаемых байтов за один прием (например, 1024 — столько придет примерно за секунду), и пока данные идут, в цикле принимаем их, «скидываем» временно в какой-нибудь массив (потом будем обрабатывать) и обнуляем разницу между toldи ttime. Если она не обнулилась вовремя и превысила 1 с — прием окончен.
Читать дальше
Конец ознакомительного отрывка
Купить книгу