; *******************************
; * Сюда попадаем при сбросе по тайм-ауту сторожевого таймера *
; *******************************
READING btfsc GPIO,0
; Новое значение при низкой температуре?goto NEW_LO
; ЕСЛИ да, ТО переходим на эту секцию!btfsc GPIO,1
; Новое значение при низкой температуре?goto NEW_HI
; ЕСЛИ да, ТО переходим на эту секцию!btfsc GPIO,2
; Обновление среднего для низкой температуры?goto UPDATE_LO
; ЕСЛИ да, ТО переходим на эту секцию!btfsc GPIO,3
; Обновление разности для высокой температуры?goto UPDATE_HI
; ЕСЛИ да, ТО переходим на эту секцию!goto READING_EXIT
; ИНАЧЕ ничего не делаемNEW_LO movf ROLL_OVER+1,w
; Берем младший байт текущего числа переполненийaddwf LO_TEMP+1,f
; и прибавляем его к младшему байту накопленного значенияbtfsc STATUS,С
; Проверяем переносincf LO_TEMP,f
; ЕСЛИ был, ТО учитываем егоmovf ROLL_OVER,w
; Берем старший байт текущего числа переполненийaddwf LO_TEMP,f
; и прибавляем его к старшему байту накопленного значенияmovf FIRST_LO,f
; Это был 1-й отсчет?btfsc STATUS,Z
goto FIRST_TIME_LO
; ЕСЛИ да, ТО отметим это!rrf LO_TEMP,f
; ИНАЧЕ делим сумму на дваrrf LO_TEMP+1,f
goto READING_EXIT
; и выходимFIRST_TIME_LO
; При первом отсчете ничего не делаемincf FIRST_LO,f
; Первый отсчет уже былgoto READING_EXIT
NEW_HI movf ROLL_OVER+1,w
; Берем младший байт текущего числа переполненийaddwf HI_TEMP+1,f
; и прибавляем его к младшему байту накопленного значенияbtfsc STATUS,С
; Проверяем переносincf HI_TEMP,f
; ЕСЛИ был, ТО учитываем егоmovf ROLL_OVER,w
; Берем старший байт текущего числа переполненийaddwf HI_TEMP,f
; и прибавляем его к старшему байту накопленного значенияmovf FIRST_HI,f
; Это был 1-й отсчет?btfsc STATUS,Z
goto FIRST_TIME_HI
; ЕСЛИ да, ТО отметим это!rrf HI_TEMP,f
; ИНАЧЕ делим сумму на дваrrf HI_TEMP+1,f
goto READING_EXIT
; и выходимFIRST_TIME_HI
; При первом отсчете ничего не делаемincf FIRST_HI,f
; Первый отсчет уже былREADING_EXIT
; Сбрасываем Таймер 0clrf TMR0
; Перезапускаем сторожевой таймерclrwdt
clrf ROLL_OVER+1
; Обнуляем число переполненийclrf ROLL_OVER
goto $
; Ждем следующего сброса от сторожевого таймераТакже в Программе 15.10 приведены секции кода, соответствующие первым двум задачам. В этих секциях 2-байтное количество переполнений Таймера 0 прибавляется к значению, хранящемуся в регистрах LO_TEMO: LO_TEMP+1 или Н1_ТЕМР:Н1_ТЕМР+1 соответственно, после чего для усреднения результат делится на два сдвигом на один бит вправо. Поскольку суммарное число переполнений достаточно скромное, двух байтов вполне достаточно, чтобы избежать переполнения. Если мы будем в течение нескольких минут многократно выполнять указанные операции, то в результате получим усредненное значение.
Если считывание результата производится в первый раз, то операция деления на два пропускается, а в соответствующую переменную-флаг FIRST_LO
или FIRST_HI заносится ненулевое значение.