Синхронизация работы программ внутренним сигналом
Рассмотрим синхронизацию с помощью таймера с номером 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 | ;Директива завершения ;трансляции |