Синхронизация работы программ внутренним сигналом
Рассмотрим синхронизацию с помощью таймера с номером 0. В этом случае в блоке инициализации и при подготовке к следующему прерыванию необходимо записывать в таймер определённые коды.
Пусть fТ = 12 МГц, а fД = 1/h = 100 Гц. Коды для записи в таймер выберем так, чтобы первое прерывание после инициализации произошло через 256 мкс, а интервал дискретизации h = 1/fД = 10 мс.
Необходимые ресурсы:
1 – регистр масок прерывания IE
(IE)=82h
2 – регистр режима таймера TMOD
|
(TMOD)=01h
3 – регистр управления таймером TCON
4 – собственно таймер
Логика работы таймера 1 в режиме 0
Какой код мы должны записать в счетчики TL0 и TH0, чтобы первое прерывание (переполнение таймера 0) произошло через 256 мкс.?
Очевидно, xx=(TL0)=00h, yy=(TH0)=0FFh.
Какой код мы должны записать в счетчики TL0 и TH0, чтобы последующие прерывания (переполнения таймера 0) происходили через h=10мс=10 000 мкс?
Очевидно, 10 00010 = 271016.
10000h – 2710h = 0D8F0h = 55 53610. xx =(TL0)=0F0h, yy=(TH0)=0D8h.
Однако, это только приблизительная оценка. Для ее уточнения необходимо подсчитать, сколько импульсов поступит на вход счетчика к моменту записи в него младшего байта (пусть 12 мкс – зависит от программы) и учесть время, потраченное на переход от запроса прерывания к обработке прерывания (пусть 9 мкс). 0D8F0h + 2110 = 0D8F0h + 15h = 0D905h.
Таким образом, xx =(TL0)=05h, yy=(TH0)=0D9h.
CSEG | AT | ;Абсолютный сегмент кода ;по адресу 0 | ||
ljmp | Start_Up | ;Первая команда по адресу 0. ;Переход на блок ;инициализации | ||
org | 000Bh | ;Переместить локальный ;счетчик на адрес 000Bh. Это ;вектор прерывания от таймера 0. | ||
clr | EA | ;запрет всех прерываний | ||
ljmp | Main | ;Переход на подпрограмму ;обслуживания этого ;прерывания | ||
ISEG | AT | 60h | ;Абсолютный сегмент с ;косвенной адресацией по ;адресу 0060h | |
Stack: | DS | 10h | ;Резервируем 16 байтов под ;стек | |
My_Prog | Segment | Code | ;Объявляем перемещаемый ;сегмент с именем My_Prog ;для кода нашей программы | |
Rseg | My_Prog | ;Активизируем этот сегмент | ||
org | 30h | ;Переместить локальный ;счетчик на адрес 0030h. | ||
Start_Up: | ||||
;Начало блока инициализации | ||||
mov | SP, | #Stack-1 | ;Инициализировать указатель ;стека | |
;запись кода в порты микроконтроллера | ||||
;установка режимов работы периферийных устройств | ||||
;запись кодов в регистры спецфункций | ||||
;чтение исходных данных из ПЗУ | ||||
;запись начальных значений в рабочие ячейки | ||||
;т.е. конфигурирование микроконтроллера для решения поставленной задачи | ||||
mov | TMOD, | #01h | ;Включить счетчик 0 в ;режиме 16-ти разрядного ;таймера. Уверены в том, что ;счетчик 1 не используется | |
mov | TH0, | #0FFh | ;Запись кодов начальной | |
mov | TL0, | #00h | ;задержки в таймер 0 | |
mov | IE | #82h | ;Разрешить прерывания ;от таймера 0 | |
setb | TR0 | ;Запуск таймера 0 | ||
Back_Gr: | ||||
;конец блока инициализации, начало фоновой задачи | ||||
;выполнение фоновой задачи | ||||
jmp | Back_Gr | ;Бесконечный цикл | ||
; - - -Срочная задача (Подпрограмма обслуживания прерывания) - - - - - - - - - - | ||||
Main: | clr | EA | ;запретить прерывания | |
mov | TH0, | #0D9h | ;ст. байт доп. кода периода ;цикла | |
mov | TL0, | #05h | ;мл. байт доп. кода периода ;цикла | |
push | PSW | ;Сохранение регистров | ||
push | Acc | ;(только используемых п/п) | ||
; Команды, необходимые для обслуживания прерывания | ||||
pop | Acc | ;Восстановление | ||
pop | PSW | ;регистров | ||
setb | EA | ;разрешить прерывания | ||
reti | ;Возврат из прерывания | |||
; - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | ||||
END | ;Директива завершения ;трансляции |