Листинг 18.6

procedure TForm2.Button2Click(Sender:TObject);

begin {запрос}

    if FlagCOM=False then exit;

      {если порт еще не инициализирован — выход}

    AfComPortl.PurgeRX; {очищаем буфер порта на всякий случай}

    xb:=$А2;

    AfComPort1.WriteData(xb,1); {посылаем команду}

    FlagSend:=$А2; {обозначаем посылку запроса времени}

    tall:=0; {обнуляем время}

    хn:=0; {счетчик принятых байтов}

    Timer1.Enabled:=True; {запускаем таймер}

end;

procedure TForm1.FormCreate(Sender:TObject);

begin

{инициализация COM1 при запуске}

    stcom:='COM1';

    IniCOM;

    end;

procedure TForm1.ComboBox1Select(Sender: TObject);

begin

     stcom:=ComboBox1.Text; {устанавливаем порт COM1,2,3,4}

     IniCOM;

end;

procedure TForm1.FormDestroy(Sender: TObject);

begin

     AfComPort1.Close; {закрытие порта}

end;

Теперь нам осталось разобраться с тем, что мы там напринимали. Это позволит сделать установленное нами значение FiagSend и таймер. В таймере переменную tall мы будем увеличивать на единицу, а в процедуре приема мы все время ее обнуляем, так что пока она равна нулю, можно полагать, что прием еще не закончился. Как только она станет больше единицы (прошло более секунды с момента последнего принятого байта или прием вообще не происходил), мы начинаем что-то делать, но только в том случае, если флаг FlagCOM установлен (True), иначе это вообще был не прием, а опрос модема. Сказанное иллюстрирует листинг 18.7.

Листинг 18.7

procedure TForm1.Timer1Timer(Sender:TObject);

var i: integer;

begin {таймер}

     inc tall

     if FlagCOM=False then exit;

     if tall>1 then

     begin

         Timer1.Enabled:=False; {выключаем таймер}

         if xn=0 then {если счетчик = 0, то ничего не принято}

         begin

             Application.MessageBox('Устройство не обнаружено 1,'Error',МВ_ОК);

             exit {выход из процедуры — неудача}

           end else

           begin {иначе обрабатываем данные}

               if FlagSend=$A2 then {если был запрос времени}

               begin

                   if xn<>6 then

                   begin

                       Application.MessageBox('Неправильный формат данных','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;

           end;

       end;

end; {конец таймера)

По аналогии вы легко добавите процедуры, соответствующие всем остальным командам, предусмотренным в программе нашего измерителя. Пользуясь функцией DateTime, легко создать процедуру, которая будет загружать из компьютера точное время (только С форматом TDateTime придется немного попотеть, см. по этому поводу [15] и [16]). Не забывайте принимать и анализировать возвращаемые байты для процедур записи. При длинной процедуре приема данных из flash, когда число байтов заранее неизвестно, суммарное значение счетчика хn покажет, сколько именно байтов принято. Причем если это число не кратно четырем, то можно смело утверждать, что целостность данных была нарушена. И не забудьте увеличить размер массива ab, если у вас энергонезависимая память большей емкости!

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

<p>Глава 19</p><p>Практические схемы на AVR</p>
Перейти на страницу:

Поиск

Похожие книги