
Синхронизация работы программ внутренним сигналом
Рассмотрим синхронизацию с помощью таймера с номером 0. В этом случае в блоке инициализации и при подготовке к следующему прерыванию необходимо записывать в таймер определённые коды.
Пусть fТ = 12 МГц, а fД = 1/h = 100 Гц. Коды для записи в таймер выберем так, чтобы первое прерывание после инициализации произошло через 256 мкс, а интервал дискретизации h = 1/fД = 10 мс.
Необходимые ресурсы:
1
– регистр масок прерывания IE
(IE)=82h
2 – регистр режима таймера TMOD
16-ти разрядный таймер
(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 |
|
;Абсолютный сегмент кода ;по адресу 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 |
|
|
;Директива завершения ;трансляции |