Для коррекции задействуем Timer 2 с коэффициентом 1:256, получаем на выходе 15 625 Гц (при тактовой частоте 4 МГц). Если использовать прерывание по сравнению с величиной 156, получаем примерно 100 Гц (или 10 мс). К ккормы будем хранить в EEPROM (по адресу KоrrEE), и переписывать его в RAM (по адресу KorrRAM) — эти адреса выбираются из любых свободных. Процедура для инициализации регистра сравнения таймера и коэффициента коррекции приведена в листинге 19.2 (в секторе начальной загрузки, о самой программе см. главу 16 ).
Листинг 19.2
;команду ldi temp,(1<
ldi temp, (1«TOIE0)|(1<<���ОСIЕ2)
;добавляем:
ldi temp,156
out OCR2,temp ;получаем 100 Гц Timer2
…
;коэффициент коррекции ============
clr ZH;addr eepr
ldi ZL,KorrEE
rcall ReadEEP
cpi temp,$FF
brne corr_K
ldi temp,100 ;если = FF, то по умолчанию 100
corr_K:
ldi ZH,1
ldi ZL,KorrRAM
st Z,temp
Величина задержки по умолчанию определяется на основе предварительных изысканий по уходу конкретного кварца (здесь часы спешили примерно на 1 с в сутки). Не забудем заменить в четвертой сверху строке таблицы прерываний retiна rjmp TIM2_comp. Отведем для счета прерываний регистр count_msek(пусть будет r12). Бит 4 регистра Flagбудет сигнализировать о том, отстают часы или спешат (если отстают, то бит установлен). Значение этого бита и регистра count_msekбудем устанавливать в момент, когда будет вызываться процедура коррекции (см. далее), там же часы останавливаются. Сам обработчик приведен в листинге 19.3.
Листинг 19.3
ТIМ2_СОМР:
dec count_msek
brne end_t ;если еще не 0, то на выход
sbrs Flag,4
rjmp k_minus ;если спешат, то пропустить если отстают
cbr Flag,8 ;очищаем бит к следующему разу; устанавливаем часы на 01 сек. и заводим их
ldi temp,1
rcall IniSek
ldi count_sek,1 ;меняем значение в регистре секунд
ldi ZH,1
ldi ZL,Sek
st Z,count_sek
rjmp end_korr
k_minus:
;если спешат, просто заводим часы обратно
clr temp
rcall IniSek
end_t:
reti ;конец прерывания коррекции
Теперь собственно процедура вызова коррекции: будем выполнять ее в полночь. Она довольно громоздкая, потому что приходится определять момент, когда полночь настала. Мы можем вклинить ее туда, где часы проверяются на кратность трем (0 минут и 0 секунд нам обеспечены). Однако сразу после этого производится запись во flash (а иногда и не производится), и она нам будет непредсказуемо тормозить коррекцию. Потому будем ее проводить в одну минуту первого (00:01:00). Сразу после метки sek_0вписываем фрагмент кода, содержащийся в листинге 19.4.
Листинг 19.4
sek_0:
ldi ZL,1 ;загружаем минуты
ld temp,Z+;
cpi temp,1 ;сравниваем минуты, если 1 — коррекция
breq min_1
cpi temp,0 ;сравниваем минуты, если 0 — запись
breq mm0 ;на проверку трехчасового цикла
reti ;иначе выходим
min_1:
ld temp,Z ;загружаем часы
cpi temp,0 ;сравниваем часы = 0
breq hour_0 ;если равны 0, то на коррекцию
reti ;иначе выходим
hour_0:
ldi ZL,KorrRAM ;коэффициент коррекции Id
count_msek,Z ;в счетчик
ldi temp,128
ср count_msek,temp ;определяем его величину
brlo k_plus
com count_msek ;если больше 127, то вычитаем из 255
sbr Flag,8 ;значит отстают
k_plus: ;если меньше — часы отстают
ldi temp,$80
rcall IniSek ;останавливаем часы
ldi temp,0Ь00000110 ;заводим таймер
out TCCR2,temp ;Timer2 1:256
reti
mm: ;далее по тексту программы
Разумеется, если вы используете сторожевой таймер, то его следует останавливать на время проведения этой операции (и запускать в прерывании Timer 2 по окончании коррекции.) В правильно организованной программе, кроме того, необходимо также запрещать за некоторое время до наступления момента коррекции длинные процедуры с запрещением прерываний (вроде чтения данных из Flash), иначе коррекцию можно пропустить.
Измерение частоты
Частоту можно измерять, как известно, двумя способами: либо подсчетом числа импульсов измеряемой частоты за определенный промежуток времени, либо, наоборот, подсчетом числа импульсов известной частоты за период (или несколько периодов) измеряемого сигнала. В первом случае мы получаем именно значение частоты (если промежуток времени равен 1 с, то сразу в герцах), а во втором — обратную величину, значение периода. Первый способ удобнее для измерения высоких частот, второй — низких.
Читать дальше
Конец ознакомительного отрывка
Купить книгу