Временные задержки необходимы для обеспечения требуемого времени индикации, для ожидания окончания временных процессов в дискретных элементах системы, для генерации временных интервалов заданной длительности и пр. Выполнение этих функций реализуется специальными модулями микроконтроллеров – таймерами-счетчиками или процессорами событий. Временные задержки в пределах нескольких тактов можно обеспечить за счет использования команд процессора, не приводящих к изменению данных системы. Задержки большой длительности реализуются за счет вложенных циклов. Длительность задержки можно определить, если учесть количество тактов, необходимое для выполнения каждой команды. Такой способ организации временной задержки называется программным.
Рассмотрим пример реализации режима сравнения таймерного модуля TIM08, т.е. пример организации временной задержки длительностью 20 мкс. В данном примере задержки осуществляются благодаря таймеру-счетчику, который устанавливается таким образом, чтобы через каждые 20 мкс он переполнялся. Блок-схема данной программы представлена на рис. 3.8.
Начало |
Загрузка старшего байта константы пересчета в регистр T1MODH, (T1MODH)←$00 |
Загрузка младшего байта константы пересчета в регистр T1MODL, (T1MODL)←$A0 |
Очистка седьмого бита T1SC |
Запуск таймера-счетчика (T1SC)←$40 |
Очистка флага I регистра CCR |
Подпрограмма обработки прерывания |
ДА |
НЕТ |
Прерывания от TIM08 – 1? |
Рис. 3.8. Блок-схема программы формирования временной
задержки 20 мкс в режиме таймера
Текст программы реализации временной задержки длительностью 20 мкс представлен ниже.
romstart | equ | $9000 | ;назначается начальный адрес прикладной;программы |
ramstart | equ | $0040 | ;назначается адрес первой ячейки памяти ОЗУ МК |
vectorstart | equ | $FFFE | ;назначается адрес вектора начального запуска |
vectorTIM1 | equ | $FFF6 | ;назначается адрес вектора по прерыванию |
T1SC | equ | $0020 | |
T1MODH | equ | $0023 | |
T1MODL | equ | $0024 | |
mov | $00,T1MODH | ;записать старший разряд регистра данных | |
mov | $A0,T1MODL | ;записать младший разряд регистра данных | |
bclr | 7,T1SC | ;сбросить бит переполнения | |
mov | #$40,T1SC | ;запустить таймер с разрешением прерываний | |
сli | ;команда разрешения прерываний | ||
prer: | … | ;программа обработки прерываний ;на данном участке располагается подпрограмма;управления;прерыванием | |
org | vectorTIM1 | ||
dw | prer | ||
end |
Начало данной программы аналогично началам рассмотренных ранее программ. Так же происходит присвоение переменным символьных имен.
После этих команд происходит запись констант пересчета в регистр данных. Старший байт константы пересчета записывается в регистр T1MODH, младший байт константы пересчета записывается в регистр T1MODL. Таким образом 16-разрядный таймер-счетчик будет перебирать числа не от $0000-$FFFF, а в диапазоне $0000-$00A0. Затем очищается седьмой бит регистра управления-состояния T1SC, т.е. происходит сброс бита переполнения TOF регистра T1SC.
Происходит запуск таймера с разрешением прерываний. В регистр T1SC записывается код $40 (%1000000):
TOF | TOIE | TSTOP | TRST | - | PS2 | PS1 | PS0 | |
Состояние до записи | ||||||||
после записи |
TOF – признак переполнения таймера, доступный только для чтения; принимает значение TOF = 1, если содержимое T1CNT достигает максимального значения, заданного содержимым регистра T1MOD.
Бит TOIE устанавливается в 1, что разрешает формирование запроса прерывания при переполнении счетчика (признак TOF = 1).
Бит TSTOP вызывает остановку работы таймера, если TSTOP = 1. В нашем случае TSTOP = 0, остановки не произойдет.
PS2–PS0 – определяют коэффициент деления частоты переключения счетчика T1CNT. В нашем случае PS2–PS0 = 000, то коэффициент деления частоты Kd = 1.
В данный момент запускается таймер-счетчик, который проходит полный цикл от начального состояния кода $0000 до конечного $00A0 за время, определяемое по формуле:
t вых = N× t вх
где N – количество перебираемых чисел, в нашем случае $00A0 = 160, tвх – длительность входных импульсов, определяются частотой внутренней шины f = 8 МГц.
Получаем:
.
После переполнения таймера-счетчика, которое происходит каждые 20 мкс, управление переходит на подпрограмму обработки прерывания. Таким образом, реализуется организация временной задержки 20 мкс.
Теперь рассмотрим формирование временной задержки 0,5 с в режиме таймера. В данном примере временные задержки осуществляются благодаря таймеру-счетчику, который устанавливается таким образом, чтобы через каждые 0,5 с он переполнялся. Блок-схема программы формирования временной задержки представлена на рис. 3.9.
Начало |
Запись старшего байта константы пересчета в регистр T1MODH, (T1MODH)←$00 |
ДА |
НЕТ |
ДА |
Запись младшего байта константы пересчета в регистр T1MODL, (T1MODL)←$A0 |
Запуск таймера-счетчика (T1SC)←$46 |
Очистка флага I регистра CCR |
Прерывания от TIM08 – 1? |
Подпрограмма обработки прерывания |
Рис. 3.9. Блок-схема программы формирования временной задержки 0,5 с
Ниже представлен текст программы реализации временной задержки длительностью 0,5 с.
romstart | equ | $9000 | ;назначается начальный адрес прикладной;программы |
ramstart | equ | $0040 | ;назначается адрес первой ячейки памяти ОЗУ МК |
vectorstart | equ | $FFFE | ;назначается адрес вектора начального запуска |
vectorTIM1 | equ | $FFF6 | ;назначается адрес вектора по прерыванию |
T1SC | equ | $0020 | |
T1MODH | equ | $0023 | |
T1MODL | equ | $0024 | |
mov | $Е4,T1MODH | ;записать старший разряд регистра данных | |
mov | $24,T1MODL | ;записать младший разряд регистра данных | |
mov | #$46,T1SC | ;записать в регистр управления код, по;необходимым параметрам | |
сli | ;команда разрешения прерываний | ||
prer: | … | ;программа обработки прерываний в данном;участке располагается подпрограмма управления;прерыванием | |
org | vectorTIM1 | ||
dw | prer | ||
end |
Данная программа практически аналогична предыдущей программе. Рассмотрим отличия этой программы.
Старший байт константы пересчета $E4 записывается в регистр T1MODH, младший байт константы пересчета $24 записывается в регистр T1MODL. Таким образом, 16-разрядный таймер-счетчик будет перебирать числа не от $0000 – $FFFF, а в диапазоне $0000 – $E424.
В регистр T1SC записывается код $46 (%1000110).
TOF | TOIE | TSTOP | TRST | - | PS2 | PS1 | PS0 | |
Состояние до записи | ||||||||
после записи |
Бит TOIE устанавливается в 1, что разрешает формирование запроса прерывания при переполнении счетчика (признак TOF = 1).
Бит TSTOP вызывает остановку работы таймера, если TSTOP = 1. В нашем случае TSTOP = 0, остановки не произойдет.
PS2–PS0 – определяют коэффициент деления частоты переключения счетчика T1CNT. В нашем случае PS2 – PS0 = 110, коэффициент деления частоты Kd = 64. Таким образом, частота входного сигнала будет определяться по формуле:
где f = 8 МГц – частота внутренней шины микроконтроллера.
Таймер-счетчик проходит полный цикл от начального состояния кода $0000 до конечного $Е424 за время, определяемое по формуле:
где N – количество перебираемых чисел, в нашем случае $Е424 = 58404, tвх – длительность входных импульсов, определяются частотой fвх = 125 КГц.
Получаем:
После переполнения таймера-счетчика, которое происходит каждые 0,5 с, управление переходит на подпрограмму обработки прерывания. Таким образом, реализуется организация временной задержки 0,5 с.
Теперь рассмотрим программный способ организации временной задержки 20 мкс. Данный способ организации задержки основывается на реализации циклов. Каждую команду процессор выполняет за определенное время. В результате для получения заданной задержки можно подсчитать, какое количество команд необходимо для ее реализации. Блок-схема программы организации временной задержки длительностью 20 мкс программным способом представлена на рис. 3.10.
НЕТ |
ДА |
Очередная команда основной управляющей программы |
($40)←($40)-1 |
Начало |
($40) = 0 -? |
Загрузка в ячейку $40 |
Рис. 3.10. Блок-схема программы организации временной задержки длительностью 20 мкс программным способом
Ниже представлен текст программы организации временной задержки длительностью 20 мкс программным способом.
org | $8000 | ;задание начального адреса программы | |
mov | #31,$40 | ;записать константу пересчета в ячейку $40 | |
m1: | dbnz | $40,m1 | ;вычесть 1 из содержимого ячейки $40 и перейти по метке;m1, если результат не равен 0 |
end |
Представлен программный способ организации временной задержки. В произвольную, пустую ячейку $40 для организации временной задержки 20 мкс записывается константа-пересчета число 31. После этого выполняется команда условного перехода dbnz, которая вычитает еденицу из содержимого ячейки $40 и проверяет на равенство 0. Если результат не равен 0, то процессор переходит по метке m1, т.е. опять возвращается на эту команду, так продолжается до тех пор, пока содержимое ячейки $40 не станет равным 0. После этого процессор идет на выполнение команды, следующей за командой dbnz. Таким образом, в приведенной программе команда dbnz будет выполняться 31 раз.
Рассмотрим, каким образом определяется константа пересчета. Общее время выполнения команд (временная задержка) определяется по формуле:
где N – константа пересчета, tmov, tdbnz – число циклов команд mov, dbnz соответственно, эти значения указаны в мнемокоде для микроконтроллера, Т – период системной шины.
f – частота системной шины.
Отсюда можно вычислить константу пересчета N:
Таким образом реализуется программный способ организации задержки.
Рассмотрим пример реализации режима захвата таймерного модуля TIM08 при положительном переходе сигнала.
Блок-схема программы представлена на рис. 3.11.
Ниже представлена программа реализации режима захвата таймерного модуля TIM08 при положительном переходе сигнала.
romstart | equ | $9000 | ;назначается начальный адрес прикладной программы |
ramstart | equ | $0040 | ;назначается адрес первой ячейки памяти ОЗУ МК |
vectorstart | equ | $FFFE | ;назначается адрес вектора начального запуска |
vectorTIM1 | equ | $FFF6 | ;назначается адрес вектора по прерыванию |
T1SC0 | equ | $0025 | |
T1SC | equ | $0020 | |
T1CH0h | equ | $0026 | |
mov | #$45,T1SC0 | ;задание регистра управления каналом | |
mov | #$40,T1SC | ;запустить таймер с разрешением прерываний | |
prer: | … | ;программа обработки прерываний в данном участке;располагается подпрограмма обработки прерывания | |
org | vectorTIM1 | ||
dw | prer | ||
end |
Начало |
Присваивание переменным и абсолютным величинам символьных имен |
Задание регистра управления каналом (T1SC0)←$45 |
Запуск таймера-счетчика (T1SC)←$40 |
Подпрограмма обработки прерывания |
ДА |
НЕТ |
Прерывания от TIM08 – 1? |
Рис. 3.11. Блок-схема программы реализации режима захвата
таймерного модуля TIM08 при положительном переходе сигнала
Для того чтобы программа могла начать работу, должны быть определены через команды присвоения EQU все спецификации аппаратных средств, такие как имена регистров и области памяти. С помощью объявлений определяются все переменные. Назначается начальный адрес прикладной программы, назначается адрес первой ячейки памяти ОЗУ МК, назначается адрес вектора начального запуска, назначается адрес вектора по прерыванию.
Далее при помощи команды mov задается регистр управления каналом:
mov #$45, T1SCO
Таким образом, в регистр управления каналом T1SC0 записывается следующий код $45 (%1000101). Рассмотрим подробнее биты регистра T1SC0:
СH0F | CH0IE | MS0B | MS0A | ELS0B | ELS0A | TOV0 | CH0MAX | |
Состояние до записи | ||||||||
после записи |
После записи в регистр управления кода на нулевом бите T1SC0 CH0MAX установится высокий уровень. Этот бит определяет выбор коэффициента заполнения Кm в режиме формирования ШИМ-сигналов. Так как CH0MAX = 1, то коэффициент Km = 1.
Бит TOV0 задает вариант изменения сигнала на выходе T1CH0 канала, работающего в режиме совпадения или в режиме форматирования ШИМ-сигналов. Поскольку TOV0 = 0, то при переполнении таймера/счетчика произойдет сохранение текущего состояния.
Биты ELS0B, ELS0A определяют тип события в режиме захвата или уровень выходного сигнала в режиме совпадения. В нашем случае в эти биты записывается комбинация 0 1, в результате будет происходить захват при положительном перепаде сигнала на выходе T1CH0.
Биты MS0B, MS0A определяют режим работы канала. В эти биты записываются низкие уровни, что соответствует захвату при положительном перепаде сигнала на входе T1CH0.
Бит CH0IE = 1, что разрешает формирование запроса прерывания при срабатывании 0-го канала (признак CH0F = 1).
Бит CH0F доступен только для чтения, поэтому в этот бит ни чего не записывается. Это признак срабатывания 0-го канала принимает значение CH0F = 1, если канал формирует выходной сигнал в режиме совпадения.
После задания регистра управления каналом происходит запуск таймера с разрешением прерываний при помощи команды:
mov #$40, T1SC
В 8-разрядный регистр управления-состояния T1SC записывается код: $40 (%1000000)
TOF | TOIE | TSTOP | TRST | - | PS2 | PS1 | PS0 | |
Состояние до записи | ||||||||
после записи |
TOF – признак переполнения таймера, доступный только для чтения; принимает значение TOF = 1, если содержимое T1CNT достигает максимального значения, заданного содержимым регистра T1MOD.
Бит TOIE устанавливается в 1, что разрешает формирование запроса прерывания при переполнении счетчика (признак TOF = 1).
Бит TSTOP вызывает остановку работы таймера, если TSTOP = 1. В нашем случае TSTOP = 0, остановки не произойдет.
PS2–PS0 – определяют коэффициент деления частоты переключения счетчика T1CNT. В нашем случае PS2–PS0 = 000, коэффициент деления частоты Kd = 1.
При переполнении счетчика происходит формирование запроса на прерывание, управление передается на программу обработки прерывания.
Команда ORG VectorTIM1 сообщает ассемблеру адрес начала вектора по прерыванию. В последних двух командах программы нет абсолютной необходимости, но при таком подходе вероятность неадекватной работы при возникновении ложных запросов на прерывания снижается. Эти две команды реализуют таблицу векторов прерывания.
Рассмотрим пример реализации режима захвата таймерного модуля TIM08 при отрицательном переходе сигнала.
Блок-схема программы представлена на рис. 3.12.
Данная программа практически аналогична программе реализации режима захвата таймерного модуля TIM08 при положительном переходе сигнала. Отличие лишь в задании регистра управления каналом. В данном случае в регистр T1SC0 записывается код $48 (%1001000). Рассмотрим подробнее каждый бит этого регистра:
СH0F | CH0IE | MS0B | MS0A | ELS0B | ELS0A | TOV0 | CH0MAX | |
Состояние до записи | ||||||||
после записи |
В данном случае СН0MAX = 0, отсюда следует, что коэффициент заполнения Km определяется содержимым регистра данных 0-го канала T1CH0.
В битах ELS0B, ELS0A устанавливается комбинация 1 0, что определяет захват при отрицательном перепаде сигнала на входе T1CH0. В этом и заключается отличие от предыдущий программы.
Начало |
Присваивание переменным и абсолютным величинам символьных имен |
Задание регистра управления каналом (T1SC0)←$48 |
Запуск таймера-счетчика (T1SC)←$40 |
Подпрограмма обработки прерывания |
ДА |
НЕТ |
Прерывания от TIM08 – 1? |
Рис. 3.12. Блок-схема программы реализации режима захвата
таймерного модуля TIM08 при положительном переходе сигнала
Ниже представлена программа реализации режима захвата таймерного модуля TIM08 при отрицательном переходе сигнала.
romstart | equ | $9000 | ;назначается начальный адрес прикладной;программы |
ramstart | equ | $0040 | ;назначается адрес первой ячейки памяти ОЗУ МК |
vectorstart | equ | $FFFE | ;назначается адрес вектора начального запуска |
vectorTIM1 | equ | $FFF6 | ;назначается адрес вектора по прерыванию |
T1SC0 | equ | $0025 | |
T1SC | equ | $0020 | |
T1CH0h | equ | $0026 | |
mov | #$48,T1SC0 | ;задание регистра управления каналом | |
mov | #$40,T1SC | ;запустить таймер с разрешением прерываний | |
prer: | … | ;программа обработки прерываний в данном участке;располагается подпрограмма обработки прерывания | |
org | vectorTIM1 | ||
dw | prer | ||
end |
В данном случае СН0MAX = 0, отсюда следует, что коэффициент заполнения Km определяется содержимым регистра данных 0-го канала T1CH0.
В битах ELS0B, ELS0A устанавливается комбинация 1 0, что определяет захват при отрицательном перепаде сигнала на входе T1CH0. В этом и заключаются отличии от предыдущий программы.