ТОП 10:

Прерывания по переполнению таймера-счётчика



Прерывания в контроллерах могут быть внешние и внутренние. Если запрос на прерывание пришёл по внешним входам контроллера, то такое прерывание называют внешним. Внешние прерывания мы рассмотрели лабораторной работе 2.2. Источником внешних прерываний являются как правило датчики, переключатели и пр.

Если запрос на прерывание вырабатывается внутри контроллера – его функциональными блоками или процессором, то такое прерывание называют внутренним. Одним из источников внутренних прерываний являются таймеры-счётчики.

Контроллер ATmega8 имеет следующие таймеры:

v T/C0 (Timer/Counter0) – 8-разрядный таймер-счётчик, имеющий предделитель частоты и режим сравнения;

v T/C1 (Timer/Counter0) – 16-разрядный таймер-счётчик, имеющий все основные режимы работы таймеров-счётчиков, в том числе режим захвата событий;

v T/C2 (Timer/Counter0) – 8-разрядный таймер-счётчик, имеющий предделитель частоты, режим сравнения и режим широтно-импульсной модуляции (ШИМ).

v WDT (Watch Dog Timer) – сторожевой таймер, имеющий предделитель частоты и собственный генератор с частотой 1 МГц.

На этом практическом занятии рассмотрим задание прерывания по переполнению T/C0 и его обработку. Счётный 8-битный регистр TCNT0 (Timer/Counter0) этого таймера хранит текущую сумму импульсов от предделителя частоты. При переходе содержимого этого регистра с 255 к 0 наступает переполнение T/C0, что и вызывает так называемое прерывание по переполнению T/C0. Этот регистр доступен по чтению и по записи в любой момент времени.

Для инициализации прерывания по переполнению необходимо установить бит разрешения прерывания TOIE0 (Timer/Counter0 Overflow Interrupt Enable) в регистре масок прерываний TIMSK (Timer/Counter Interrupt Mask Register) и задать коэффициент предварительного деления частоты PRESCALER в регистре управления таймером-счётчиком TCCR0 (Timer/Counter Control Register0). На рисунках 2.3.1 и 2.3.2 описаны биты регистров TIMSK и TCCR0 соответственно. Биты выбора CS (Clock Select) источника тактирования описаны в Таблице 2.3.1.

Таблица 2.3.1. Описание битов выбора источника тактирования

CS02 CS01 CS00 Описание
Нет источника (T/C0 – остановлен)
Источник – тактовый генератор с fтакт
Источник – тактовый генератор с fтакт/8
Источник – тактовый генератор с fтакт/64
Источник – тактовый генератор с fтакт/256
Источник – тактовый генератор с fтакт/1024
Источник – спадающий фронт импульсов на линии T0
Источник – возрастающий фронт импульсов на линии T0

Как видно из таблицы мы можем выбирать всего пять коэффициентов предварительного делителя частоты. Время до срабатывания прерывания можно оценить по суммарной длительности импульсов тактового генератора, которые заполнят регистр TCNT0 от 0 до 255, т.е. всего 256 (таймер у нас 8-битный). Для этого надо выбранный из Таблицы 1 коэффициент предделителя частоты умножить на число 256 и разделить на тактовую частоту генератора fтакт.

Например, пусть fтакт = 8МГц, коэффициент предделителя PRESCALER = 010, т.е. тактовая частота делится на восемь (к регистру TCNT0 будет проходить только каждый восьмой импульс от генератора). Значит время до срабатывания прерывания T

T = 8*256 / 8*106 = 0,000256 сек.

Таким образом, время срабатывания прерывания равно 256 микросекундам. Для увеличения этого времени надо увеличить коэффициент предделителя. К примеру, при PRESCALER = 101, T = 0,032768 сек.

Пример 2.3.1. Рассмотрим задачу управления группой реле с помощью прерывания по переполнению T/C0. На рис. 2.3.3 изображена схема подключения шести реле Р1-Р6 к линиям порта B через схему ULN2003A, содержащую семь транзисторных ключей на составных транзисторах (схема Дарлингтона), шесть из которых нами используются, а один – нет. Они позволяют управлять нагрузкой до 500 mA при напряжении Uпит до 50 В. Внутри этой микросхемы уже имеется встроенный защитный диод, который можно подключать или отключать, осуществляя внешние соединения. На листинге 2.3.1 представлена программа подачи напряжения на управляющие обмотки реле Р1-Р6 на строго заданное время T = 0,016 сек., по истечению которого напряжение снимается. Включение реле производится подачей на соответствующую линию порта B логической единицы. Отключается реле логическим нулём.

В начале программы расписана таблица векторов прерываний, в которой инициализируются только два прерывания: INIT – для инициализации контроллера при подаче питания и TIM0_OVF – для обработки прерывания по переполнению разрядной сетки таймера-счётчика T/C0. Процедура ERROR обслуживает остальные прерывания, если они случайно возникнут.

Далее в программе задаётся коэффициент предделителя частоты в шестнадцатеричном представлении PRESCALER = 0x04, то есть fтакт/256. На тактовой частоте 4 Мгц такой предделитель обеспечит время срабатывания T = 0,016384 сек.

Листинг 2.3.1.

.INCLUDE "m8def.inc" ; AtMega8 definitions

 

.ORG 0x00 rjmp INIT ; начальные установки

.ORG INT0addr rjmp ERROR ; ловушка для всех

.ORG INT1addr rjmp ERROR ; неинициализированных прерываний

.ORG OC2addr rjmp ERROR

.ORG OVF2addr rjmp ERROR

.ORG ICP1addr rjmp ERROR

.ORG OC1Aaddr rjmp ERROR

.ORG OC1Baddr rjmp ERROR

.ORG OVF1addr rjmp ERROR

.ORG OVF0addr rjmp TIM0_OVF ; прерывание Timer/Counter0

.ORG SPIaddr rjmp ERROR

.ORG URXCaddr rjmp ERROR

.ORG UDREaddr rjmp ERROR

.ORG UTXCaddr rjmp ERROR

.ORG ADCCaddr rjmp ERROR

.ORG ERDYaddr rjmp ERROR

.ORG ACIaddr rjmp ERROR

.ORG TWIaddr rjmp ERROR

.ORG SPMRaddr rjmp ERROR

 

ERROR: rjmp ERROR ; бесконечный цикл ловушки

 

.EQU PRESCALER = 0x04 ; настройка делителя таймера

 

INIT:

Cli ; запрет прерываний

ldi r16,high(RAMEND) ; указ-ль стека на последний байт ОЗУ

out SPH,r16

ldi r16,low(RAMEND)

out SPL,r16

 

ser r16

out DDRB,r16 ; инициализируем порт B на вывод

out PORTB,r16 ; снимаем напряжение с реле

 

ldi r16,0x01 ; TOIE0=1

out TIMSK,r16 ; прерывание по переполнению регистра TCNT0

 

ldi r16,PRESCALER

out TCCR0,r16 ; включаем прерывание от Timer/Counter0

 

ser r16

out PORTB,r16 ; подаём напряжение на реле

 

sei ; разрешаем прерывания

 

LOOP:

rjmp LOOP

 

TIM0_OVF:

clr r16

out PORTB,r16 ; снимаем напряжение с реле

out TCCR0,r16 ; отключаем прерывание от Timer/Counter0

reti

Скопируйте указанную программу в окно редактора исходного текста, ассемблируйте и запустите отладчик (рис. 2.3.4). Так как в нашей программе используется порт B для взаимодействия с группой реле Р1-Р6 и таймер-счётчик T/C0, то для удобства просмотра регистров порта B и регистров таймера T/C0 отобразим их на панели регистров. Для этого щёлкнем по порту B на панели модулей и, удерживая клавишу CTRL, щёлкнем по таймеру-счётчику T/C0, добавив тем самым регистры таймера к регистрам порта на панели регистров (рис. 2.3.4).

Делать пошаговое выполнение мы не будем, так как для этого потребуется нащёлкать мышкой несколько тысяч тактов генератора. Поэтому вначале поставим курсор перед основным циклом программы – командой sei и выполним нашу программу до указанного положения курсора с помощью пункта меню Debug ® Run to Cursor или кнопкой на панели инструментов, указанной на рис. 2.3.4. На рисунке 2.3.5 представлен внешний вид программы и содержимое регистров контроллера по достижении курсора.

Для того чтобы убедиться, что контроллер накапливает сумму тактов в регистре TCNT0, выполним несколько тактов вручную с помощью клавиши F11 или соответствующей кнопки на панели инструментов. Удерживайте клавишу F11 и наблюдайте за увеличением счётчика тактов. На 257 такте в счётчик TCNT0 запишется первая единица.

 

На рисунке 2.3.6 показано содержимое регистров после выполнения 259 тактов. Команда sei устанавливает флаг разрешения прерываний и далее программа входит в основной цикл, где и будет выполняться до тех пор, пока счётчик таймера T/C0 досчитав от 0 до 255 и вернувшись на 0, вызовет прерывание TIM0_OVF. Однако на данный момент времени счётчик таймера равен единице. Этот счётчик будет инкрементироваться каждые 256 тактов тактовой частоты, так как константой PRESCALER мы задали деление тактовой частоты на 256.

Дальше выполнять вручную не имеет смысла, поэтому поставим курсор на начало процедуры обслуживания прерывания, т.е. на метку TIM0_OVF и выполним программу до указанного положения курсора.

Как можно увидеть (рис. 2.3.7) счётчик тактов стал равен 65544. Таким образом, программа ожидала прерывания, включив реле, 65544‑16=65528 тактов. Тактовая частота процессора равна 4 МГц. Следовательно, прошло ровно 65528/4000000 = 0,016382 сек. или »16 мс.

Выполнив вручную по шагам процедуру TIM0_OVF вплоть до возвращения в основной цикл программы (рис. 2.3.8) можно увидеть, как сначала отключаются все реле, потом запрещается прерывания таймера T/C0, потом по команде возврата из прерывания устанавливается флаг разрешения прерываний.

После этого программа будет находиться в вечном цикле и реле больше не включатся, так как мы в процедуре TIM0_OVF запретили прерывания таймера T/C0.

Задание 2.3.1. Разработать электрическую схему и программу подачи питания на управляющие обмотки 12 маломощных реле на 0,065536 сек. (65мс.) по включении контроллера.

Задание 2.3.2. Разработать электрическую схему и программу для управления реле, которое должно попеременно включаться и отключаться с периодом 130 мс. (65 мс. + 65мс.) и скважностью 1/2.

Задание 2.3.3. Разработать электрическую схему и программу для управления тремя светодиодами, которые должны включаться и отключаться с периодом 4 сек. и скважностью 1/2. Подсказка: организуйте дополнительный цикл, который будет считать нужное количество срабатываний прерываний по переполнению таймера.







Последнее изменение этой страницы: 2016-06-29; Нарушение авторского права страницы

infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 54.236.35.159 (0.013 с.)