Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Лабник по СПО

.pdf
Скачиваний:
9
Добавлен:
05.06.2015
Размер:
1.59 Mб
Скачать

Лабораторная работа № 7. Измерение времени

Задание

Цель работы:

1.Изучение методов создания непрерывного управляемого потока с помощью таймера.

2.Исследование погрешности задания временного интервала таймера.

3.Освоение приёмов определения системного времени и интервалов времени.

Содержание работы:

Разработка секундомера с часами.

Технические требования к программе:

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

Выполняемые действия: задание интервала таймера; пуск, останов секундомера, переключение режимов секундомера, задание положения окна относительно других окон. Режимы секундомера: измерение одиночных интервалов времени, суммирование времени нескольких интервалов.

Положение часов: поверх всех окон или позади активного окна. Число форм в проекте: 1.

Форма отчёта:

Текст проекта в папке с именем Work7 на диске Н:.

Содержание отчёта:

Файлы проекта и исполняемый файл.

Средства для измерения времени

Компонент Timer (таймер) находится на вкладке System и служит для отсчёта интервалов реального времени.

171

PDF created with pdfFactory Pro trial version www.pdffactory.com

Объект Timer имеет четыре свойства и одно событие OnTimer. Свойство Enabled управляет запуском и остановкой таймера. Свойство Interval задаёт интервал времени в миллисекундах, через который возникает событие OnTimer. Свойство Name хранит имя объекта. Свойство Tag является переменной целого типа, которая может использоваться в программе по усмотрению разработчика. Изменение значения переменной Tag не оказывает прямого влияния на работу объекта.

Интервалы задаются с некоторой дискретностью, зависящей от версии операционной системы и способа их реализации. Дискретность задания длительности интервалов означает, что получаемые фактические значения интервалов не всегда совпадают с заданными значениями. Если дискретность равна 15 мс, то при установке длительности интервала в 1 или 15 мс интервал на самом деле будет составлять 15 мс. При установке длительности интервала в диапазоне от 16 до 31 мс фактически получится 31 мс, при 16 мс - 46 мс и т.д. Следовательно, использовать эти интервалы для точного отсчета времени нельзя.

Для получения точных временных интервалов можно использовать системную функцию GetTickCount типа DWord, возвращающую значение, которое увеличивается на единицу через 1 мс. Чтобы отсчитать интервал времени, необходимо в начальный момент переменной типа DWord присвоить значение функции GetTickCount. В конечный момент вычислить разницу между старым и новым значениями функции, преобразовать эту разницу в часы, минуты, секунды и миллисекунды, и вывести эти значения на метку. Используя переменную TickCount, следует учитывать, что каждые 49,7 суток счётчик переполняется и обнуляется, и в этот момент может появиться ошибка в измерении интервала времени.

Для получения системного машинного времени предназначена системная функция Time типа TDateTime. Значения, возвращаемые функцией Time, можно вычитать и складывать, что позволяет измерять временные интервалы. Для преобразования времени в строку предусмотрена функция TimeToStr(Time), возвращающая стандартную строку с часами, минутами и секундами, разделёнными двумя точками. Для получения значений часов, минут, секунд и миллисекунд предназначена процедура DecodeTime(Time,h,m,s,ms), которая присваивает переменным h, m, s и ms значения в часах, минутах, секундах и миллисекундах.

Используя эти функции, можно проверить дискретность изменения временного интервала таймером. Для этого нужно измерить фактическое значение интервала, возвращаемое таймером с помощью импульсов TickCount. Для повышения точности

172

PDF created with pdfFactory Pro trial version www.pdffactory.com

можно замерить время 10 или 20 интервалов, разделить полученное время на число тактов, результат вывести на экран и сравнить с заданным значением.

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

Схема приложения

Работа приложения всегда обязана начинаться с проверки введённых команд. В данной программе это команды: на закрытие программы (блок 2 на рис.7.1), команда на задание положения окна программы относительно других окон (блок 3 на рис.7.1), команда на пуск измерителя интервала (блок 7 на рис.7.1) и команда на включение секундомера (блок 10 на рис.7.1).

1

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Начало

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Да

 

 

2

 

?

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

10

 

 

 

 

 

 

 

 

 

Выход

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Конец

 

 

 

 

 

 

Нет

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

6

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Время

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

7

 

 

 

Нет

8

 

 

?

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Старт

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Интервал

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

?

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Да

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

3

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

9

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Поверх

 

 

 

Да

 

 

 

 

 

 

 

 

 

 

 

 

Секундомер

 

 

 

 

Нет

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

4

 

 

 

 

 

 

 

 

 

 

5

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Style=OnTop

 

 

 

 

 

 

 

 

 

 

 

 

Style=Normal

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Рис.7.1. Схема программы, демонстрирующей измерение времени

Поток для измерения системного времени, поток для измерения длительности

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

173

PDF created with pdfFactory Pro trial version www.pdffactory.com

Поток, измеряющий системное время, работает непрерывно, начиная работу в момент запуска программы и прекращая работу после закрытия программы. Поток считывает и выводит системное время с периодом, равным длительности интервала таймера, управляющего этим потоком. Схема потока, измеряющего системное время, показана на рис.7.2.

1 Начало

 

 

 

 

 

 

 

 

 

 

 

2

 

 

 

 

 

 

 

 

 

Расчёт

 

 

 

 

 

 

 

 

 

 

 

времени

 

4

 

 

 

 

 

 

 

 

tзадержки = tинт1

 

 

 

3

 

 

 

 

 

 

 

 

 

 

 

 

Вывод

 

 

 

 

 

 

 

 

 

 

времени

Рис.7.2. Схема потока измерения системного времени

Поток измерения длительности интервала таймера запускается при задании интервала. При изменении значения задаваемого интервала таймер должен включиться, измеритель времени должен зарегистрировать время начала отсчёта, счётчик тиков должен отсчитать заданное число тиков, измеритель времени - зарегистрировать время конца отсчёта и вывести разницу двух отсчётов времени в пересчёте на один тик. Схема потока измерения фактической длительности интервала таймера показана на рис.7.3.

1

Начало

 

 

2

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Tag = 0

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

11

 

Конец

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

3

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Ввод t1

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

10

 

 

 

 

4

 

 

 

 

 

 

tфак

 

 

 

 

 

 

 

 

Вывод

 

 

 

 

 

 

 

 

tзадержки = tинт2

 

 

 

5

 

 

 

 

 

 

 

 

 

9

 

 

 

 

 

 

 

 

Tag = Tag+1

 

tфак =

(t2 t1)/10

 

 

 

 

 

 

 

?

Да

 

 

 

 

 

 

 

 

 

6

 

8

 

 

 

 

 

Ввод t2

 

 

 

 

 

 

 

Выход

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Нет

 

Да

 

 

 

 

 

 

 

 

 

Нет

 

7

?

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Tag = 10

 

 

 

 

 

 

 

 

 

 

 

Рис.7.3. Схема алгоритма потока, измеряющего фактический интервал таймера

174

PDF created with pdfFactory Pro trial version www.pdffactory.com

Блок 9 на рис.7.1 проверяет наличие команды на запуск секундомера. Схема подпрограммы секундомера показана на рис.7.4.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

1

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Начало

 

 

10

 

 

Конец

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Да

 

 

 

 

 

 

2

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Нет

 

 

9

 

?

 

 

 

 

Ввод t1 и N1

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Стоп

 

 

Да

 

3

 

 

 

?

 

 

 

 

 

 

 

 

 

 

 

 

 

8

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Накопление

 

 

Вывод времени

 

4

 

 

 

 

 

Добавка tн

 

 

Нет

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

7

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

5

 

 

 

 

 

 

 

Расчёт времени

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

tзадержки = tинт3

 

 

 

6

 

 

 

 

 

 

 

 

 

Ввод t2 и N2

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Рис.7.4. Схема секундомера

При запуске секундомера вводится время и номер тика на момент запуска,

вычисляется разница между текущим временем и текущим номером тика и временем и номером в момент запуска, и разница выводится на экран. При подаче команды Стоп останавливается работа таймера, управляющего секундомером, и на экране остаются результаты последнего расчёта разницы двух отсчётов времени и числа тиков. При

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

Создание проекта

Создаём проект типа VCL Forms Application. Сохраняем проект в подготовленной заранее папке с именем Work7, присваиваем главному модулю имя UnTimer, а проекту - имя WatchTimer. Присваиваем главной форме имя fmTimer.

Размещаем на форме визуальные объекты в соответствии с рис.7.5.

175

PDF created with pdfFactory Pro trial version www.pdffactory.com

Рис.7.5. Окно программы, демонстрирующей измерение времени

Размещаем на форме шесть меток для обозначения параметров и пять меток для вывода рассчитанных параметров. Меткам для вывода параметров присваиваем имена: WatchLb, LabTickCount, TickLab, DataLab и TimeLab. Помещаем на форму один редактор с именем ValSet для задания интервала и один редактор с именем ValGet для вывода фактического значения интервала таймера. Свойству ReadOnly редактора ValGet присваиваем значение False.

Помещаем на форму четыре кнопки. Кнопкам присваиваем имена: ButWatch, RegButt, StartBut, BtClse. Вводим начальные значения заголовков кнопок таким образом, чтобы было понятно, какую команду формирует нажатие кнопки.

Установим на форму три объекта Timer. Зададим свойствам Interval таймеров, предназначенных для управления часами и секундомером, значение 1 мс, таймеру для отсчёта фактического интервала - значение 15 мс. Свойству Enabled таймера секундомера зададим значение False.

Текст программы на языке Delphi

Объявляем глобальные переменные:

Var

fmTimer: TfmTimer; TT2,TTS, msTick :LongWord; BegTime :TDateTime; Reg,StSt: Byte;

Days: Array[1..7] Of String;

Переменная TT2 предназначена для хранения числа тиков при измерении фактического значения интервала таймера, переменная TTS - для хранения числа тиков в

176

PDF created with pdfFactory Pro trial version www.pdffactory.com

секундомере. В переменной msTick предполагается хранить предыдущее значение секундомера, в переменной BegTime - начальное время отсчёта, в переменных Reg и StSt - состояния кнопок RegButt и StartBut.

Массив Days предназначен для определения имён дней недели.

Вобработчик события OnClick кнопки ButWatch вводим операторы для задания положения формы относительно других форм и изменения надписи на кнопке. Проверяем правильность действия кнопки.

Procedure TfmTimer.ButWatchClick(Sender: TObject);

Begin

If fmTimer.FormStyle=fsNormal

Then Begin fmTimer.FormStyle:=fsStayOnTop; ButWatch.Caption:='Поверх всех'

End Else Begin

fmTimer.FormStyle:=fsNormal; ButWatch.Caption:='Назад'

End End;

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

возвращаемых функцией TimeToStr(Time) и процедурой DecodeTime(Time,h,m,s,ms),

выводим системное время, возвращаемое функцией TimeToStr(Time), на заголовок формы, а время, возвращаемое процедурой DecodeTime(Time,h,m,s,ms), - на метку

WatchLb.

Procedure TfmTimer.Timer1Timer(Sender: TObject); Var h,m,s,ms :Word;

Begin

DecodeTime(Time,h,m,s,ms); WatchLb.Caption:=IntToStr(h)+' час '+ IntToStr(m)+' мин ' +IntToStr(s)+' с ' +IntToStr(ms)+ ' мс';

Caption := ' Системное время-> '+TimeToStr(Time)

End;

177

PDF created with pdfFactory Pro trial version www.pdffactory.com

В обработчик события OnTimer второго таймера вводим операторы для вычисления фактического значения интервала таймера. Для измерения фактического времени используем значение системной переменной TickCount.

Procedure TfmTimer.Timer2Timer(Sender: TObject); Var m,s,ms :LongWord;

Begin

If Tag=0 Then TT2 := GetTickCount; LabTickCount.Caption:=IntToStr(GetTickCount);

If Tag=10 Then

Begin

Timer2.Enabled := False;

ms := (GetTickCount-TT2) Div 10; m := ms Div 60000;

ms := ms-60000*m; s := ms Div 1000; ms := ms-1000*s; ValGet.Text :=

''+IntToStr(s)+' с '+IntToStr(ms)+' мс'

End;

Tag := Tag+1

End;

Операторы, изменяющие значение задаваемого интервала, вводим в обработчик OnChange редактора ValSet.

Procedure TfmTimer.ValSetChange(Sender: TObject);

Begin

Timer2.Interval := StrToInt(ValSet.Text ); Tag := 0;

Timer2.Enabled := True;

End;

Вводом разных значений интервалов второго таймера попытаемся определить дискретность задания интервала.

Для пуска или останова секундомера одной кнопкой используем операторы, изменяющие состояние кнопки Старт/Стоп по значению переменной StSt.

Procedure TfmTimer.StartButClick(Sender: TObject);

Begin

178

PDF created with pdfFactory Pro trial version www.pdffactory.com

If StSt = 0 Then Begin

StartBut.Caption:='Стоп'; StSt := 1; Timer3.Enabled:=True; TTS := GetTickCount;

If Reg=1 Then TTS:=TTS-msTick; BegTime:=Time ;

End

Else Begin

StartBut.Caption:='Старт'; StSt := 0 ; Timer3.Enabled:=False;

End

End;

Операторы для отсчёта времени между подачами команд Старт и Стоп запишем в обработчик события OnTimer третьего таймера. Подсчёт времени выполним двумя способами с выводом результатов на две метки: TickLab и TimeLab.

Procedure TfmTimer.Timer3Timer(Sender: TObject);

Var

h,m,s,ms :Word; mT,sT,msT :LongWord;

Begin msT:=GetTickCount-TTS; msTick:=msT;

mT:=msT Div 60000; msT:=msT-60000*mT; sT:=msT Div 1000; msT:=msT-1000*sT;

TickLab.Caption:=' '+IntToStr(mT)+' мин '+ IntToStr(sT)+' с '+IntToStr(msT)+' мс'; DecodeTime(Time-BegTime,h,m,s,ms); TimeLab.Caption:=' '+IntToStr(m)+' мин ' + IntToStr(s)+' с '+IntToStr(ms)+ ' мс'

End;

179

PDF created with pdfFactory Pro trial version www.pdffactory.com

Изменение режима секундомера производим операторами, записанными в обработчик события OnClick кнопки RegButt.

Procedure TfmTimer.RegButtClick(Sender: TObject);

Begin

If Reg=0

Then Begin

RegButt.Caption:='Накопление'; Reg:=1

End

Else Begin

RegButt.Caption:='Обнуление'; Reg:=0

End End;

Имена дней недели записываем в массив Days при создании формы и в эту же процедуру записываем оператор для определения даты и дня недели.

Procedure TfmTimer.FormCreate(Sender: TObject);

Begin

Days[1] := 'Воскресенье, ';

Days[2] := 'Понедельник, '; Days[3] := 'Вторник, '; Days[4] := 'Среда, '; Days[5] := 'Четверг, '; Days[6] := 'Пятница, '; Days[7] := 'Суббота, ';

DataLab.Caption:='Дата: '+Days[DayOfWeek(Date)]+ DateToStr(Now)

End;

Оператор DayOfWeek(Date) возвращает день недели целым числом от 1 до 7, считая первым днём недели воскресенье.

Если DateToStr(Now) поменять на DateTimeToStr(Now), то кроме даты получим ещё и время.

180

PDF created with pdfFactory Pro trial version www.pdffactory.com

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]