Из Программы 17.1 видно, что время хранится в виде 3-байтного числа в регистрах MINUTES, SECOND и JIFFY. Полагая, что 0-й бит регистра PAUSE сброшен в 0, значение счетчика тиков JIFFY увеличивается на единицу. Обычно после этого выполняется выход из обработчика прерывания, однако если JIFFY становится равным 50, то он обнуляется и декрементируется счетчик секунд SECOND. При этом в регистр NEW_SEC заносится ненулевое значение, извещающее фоновый процесс о том, что прошла секунда. Когда счетчик секунд становится равным нулю, в него снова загружается константа 59, а счетчик минут MINUTES декрементируется. Описанная процедура похожа на операцию инкрементирования счетчика, которую мы реализовали в Примере 7.3.
Задача формирования временных отсчетов также поддерживает функцию приостановки счета. Самым простым решением был бы пропуск декрементирования счетчиков при нажатой кнопке ПАУЗА. Однако если потребуется удерживать кнопку нажатой дольше нескольких минут, то эта операция может оказаться довольно утомительной.
Формирование останова/пуска по последовательным нажатиям кнопки является более эргономичным и может быть достаточно легко реализовано программно. И уж точно, это гораздо лучше, чем использовать кнопку какого-либо другого типа (скажем, кнопку с фиксацией). В Программе 17.1 код обработки нажатия кнопки ПАУЗА вынесен в отдельную подпрограмму FREEZE. Мы вполне можем вызвать подпрограмму из обработчика прерывания точно так же, как и из другой подпрограммы. Аппаратный стек позволяет использовать до 8 уровней вложенности. В нашем случае будет использовано только два уровня стека.
Подпрограмма FREEZE вызывается только в случае замыкания кнопки ПАУЗА. При каждом входе в подпрограмму изменяется состояние 0-го бита регистра PAUSE, что реализуется простым инкрементированием регистра.
После переключения PAUSE[0] проверяется его состояние и, если он равен 1, то вызывается подпрограмма SPI_WRITE для вывода на индикаторы только двух десятичных точек. Разумеется, это только один из множества возможных способов отображения состояния паузы. Можно, например, выводить на индикатор символы
Выход из подпрограммы осуществляется только после отпускания кнопки ПАУЗА. Это очень важно, так как в противном случае при входе в обработчик прерывания по следующему переполнению Таймера 0 могло бы произойти повторное (ложное) переключение флага паузы. Чтобы предотвратить влияние дребезга контактов кнопки, после ее отпускания сначала обнуляется Таймер 0 со своим предделителем и только после этого сбрасывается флаг прерывания T0IF, благодаря чему повторная проверка состояния кнопки будет произведена только через 1/50 секунды.
Вывод на индикаторы содержимого рабочего регистра в виде десятичного числа осуществляется подпрограммой OUTPUT, код которой приведен в Программе 17.2. Эта подпрограмма выполняет следующие операции:
1. Преобразует двоичное число в 2-разрядное BCD-число.
2. Преобразует значения обоих разрядов в коды 7-сегментного индикатора.
3. Пересылает каждый байт в соответствующий индикатор по последовательному каналу.