Синхронизация работы программ внутренним сигналом

 

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