Переполнение Таймера 1 и установка флага прерывания TMR1IF происходит после 216 = 65 536 событий, считая от нуля. Этот флаг, в свою очередь, может использоваться для прерывания работы процессора, если парный ему бит маски TMR1IE в регистре PIE1 (см. Рис. 7.5 на стр. 223) установлен в 1. Разумеется, никто не запрещает отслеживать это событие путем обычного опроса данного флага. В любом случае флаг TMR1IF должен быть сброшен вручную после обнаружения переполнения.
К примеру, при использовании резонатора с частотой 32.768 кГц переполнение Таймера 1 будет происходить каждые 2 с при T1CKPS[1:0] = 00 и каждые 16 с при T1CKPS[1:0] = 11.
∙
По умолчанию сигнал с выхода программируемого предделителя синхронизируется с системным тактовым сигналом, что приводит к появлению задержки, равной двум машинным циклам. Однако в отличие от Таймера 0 в этом таймере сигнал может передаваться в обход сдвигового регистра синхронизатора при установке бита
За исключением указанных случаев, бит
movlw h’80’; Новое значение старшего байта
bcf T1CON,TMR1ON; Останавливаем таймер
movwf TMR1H; Загружаем в Таймер 1 число 8000h
clrf TMR1L
bsf T1CON,TMR1ON; Перезапускаем таймер
Изменение состояния Таймера 1 всегда вызывает сброс счетчика предделителя.
Если Таймер 1 работает в синхронном режиме, его значение можно изменять «на лету». Необходимо только быть аккуратным при изменении обоих байтов счетчика, поскольку может случиться так, что после изменения старшего байта переполнение младшего произойдет до записи в него нового значения, в результате чего старший байт изменится нежелательным образом. Чтобы избежать этого, перед записью нового значения следует обнулить младший байт. Вот как, например, можно записать в Таймер 1 «налету» число h’9FFF’:
movlw h’9F’; Новое значение старшего байта
clrf TMR1L; Предохраняемся от переполнения младшего байта
movwf TMR1H; Обновляем старший байт счетного регистра
movlw h’FF’; Новое значение младшего байта
movwf TMR1L; Обновляем младший байт счетного регистра
Содержимое Таймера 1 можно прочитать в любой момент времени даже при работе в асинхронном режиме. Однако, поскольку одновременно можно считать только один байт[175], возможна ситуация, при которой между двумя последовательными операциями чтения произойдет переполнение таймера, например:
; Предположим, что текущее состояние Таймера 1 — h’80FF’
movf TMR1L,w; Читаем младший байт = h’FF’
movwf TEMPL; Запоминаем
; ««в этот момент состояние Таймера 1 изменилось на h’8100’»»
movf TMR1H,w; Читаем старший байт = h’81’
movwf TEMPH; Запоминаем. Считанное значение равно h’81FF’!!!
В результате выполнения предыдущего кода мы получим значение h’81FF’ вместо h’80FF’. Возникновение такой ситуации наиболее вероятно при генерации прерывания от другого периферийного устройства между последовательными операциями чтения.
Чтобы результат считывания был предсказуемым, можно использовать два способа. Первый способ заключается в остановке таймера перед считыванием его состояния. Второй же способ заключается в том, что сначала считывается старший байт, а после считывания младшего байта проводится проверка, не изменилось ли состояние старшего байта, как показано в следующем примере: