
- •Встраиваемые микроконтроллеры avr-8
- •Санкт-Петербург 2013 Содержание
- •Часть 1. Архитектура мк (л2, л3)
- •Понятия мк для встраиваемых приложений и семейства мк. Семейство avr-8
- •Структура и архитектура мк
- •Тактирование, процессор и арифметико-логическая группа команд
- •Структура и адресация памяти программ. Ветвления, циклы, подпрограммы, и группа команд передачи управления
- •Структура и адресация памяти данных. Группа команд передачи данных
- •Порты ввода/вывода. Типовая схема включения мк. Структура управляющей программы, поллинг.
- •Часть 2. Процесс проектирования устройств на мк (л4, л5)
- •2.1. Этапы процесса проектирования устройств на мк
- •2.2.Техническое задание и разработка алгоритма (блок-схемы)
- •2.3. Языки программирования и синтаксическая проверка проекта
- •2.4. Средства загрузки кодов программ и данных (программаторы)
- •2.5. Средства отладки для выявления логических и схемотехнических ошибок
- •2.6. Подключение индикаторов и клавиатуры
- •Часть 3. Ввод/вывод в мпу
- •3.1. Понятие и характеристики интерфейса
- •3.2. Внутрисистемные интерфейсы в мпу
- •3.3 Параллельный порт avr
- •3.4. Внешняя магистраль памяти данных avr мк
- •3.5. Принцип и средства ввода/вывода по прерываниям.
- •3.6. Принцип прямого доступа к памяти
- •Часть 4. Прерывания (л8)
- •4.1. Механизм прерываний в avr и его программирование
- •4.2. Входы прерываний inTx и pcinTx.
- •Часть 5. Таймеры/счетчики
- •5.1. Задачи формирования и измерения временных интервалов
- •5.2. Принципы программного формирования/измерения временного интервала
- •5.3. Таймер/счетчик с прерыванием по переполнению
- •5.4. Таймер/счетчик с дополнительными узлами захвата и сравнения
- •Часть 6. Задачи и устройства аналогового ввода/вывода (л12, л13)
- •6.1. Задачи аналогового ввода и вывода
- •6.2. Встроенный аналоговый компаратор
- •6.3. Встроенный многоканальный ацп
- •6.4. Встроенный цап
- •Часть 7. Задачи и устройства последовательного интерфейса (л14, л15)
- •7.1. Принципы и преимущества последовательного интерфейса
- •7.2. Функции встроенного контроллера последовательного интерфейса
- •7.3. Протокол и контроллер трехпроводного синхронного пи (spi)
- •7.4. Устройство контроллера i2c и его применение
- •7.5 Цап с последовательным интерфейсом
- •7.6. Устройство контроллера u(s)art и его применение
- •7.7. Сетевые протоколы и их стандартизация
- •7.8. Открытый протокол Modbus
- •История
- •Введение
- •Категории кодов функций
- •Модель данных
- •Стандартные функции протокола Modbus
- •Запись одного значения
- •Запись нескольких значений
- •Контроль ошибок в протоколе Modbus rtu
- •Rtu фрейм
- •Логические ошибки
- •Стандартные коды ошибок
4.2. Входы прерываний inTx и pcinTx.
Внешние прерывания
Внешние прерывания в МК серии AVR ранних моделей состоят только из альтернативных функций INTx. Они поддерживают аппаратное выявление фронта, среза, пр. и формирование индивидуального запроса прерывания, такими функциями оснащались от 2-х до 8-ми отдельных выводов портов. В более поздних моделях к этим функциям добавились функции аппаратного выявления изменения состояния вывода PCINTn [Pin Change INTerrupt], которыми оснащаются все выводы портов.
Оба механизма ориентированы на автоматизацию обслуживания входов, то есть контроля состояния внешних сигналов. Но это не мешает использовать их для контроля изменения состояния выводов в режиме выхода, то есть формировать программно управляемые прерывания.
В МК AT90S8515 имеется два входа прерывания INT0/PD2, INT1/PD3. Событием может быть (табл. 4.1): низкий уровень, фронт, срез, либо любое изменение (фронт/срез). Тип события задается программно битами ISCX1, ISCX0 в регистре MCUCR (табл. 4.2).
Таблица 4.1. Внешние прерывания МК at90s8515
Источник |
Вектор |
Флаг |
Маска |
Выбор формы сигнала |
INT0 / PD2 |
INT0_vect = 0x02 |
GIFR:INTF0 |
GIMSK:INT0 |
MCUCR:ISC01, ISC00 |
INT1 / PD3 |
INT1_vect = 0x04 |
GIFR:INTF1 |
GIMSK:INT1 |
MCUCR:ISC11, ISC10 |
Таблица 4.2. Настройка регистра MCUCR на событие на входах INT0, INT1
ISCх1 |
ISCх0 |
Форма прерывающего сигнала |
0 |
0 |
Низкий уровень |
0 |
1 |
Резерв |
1 |
0 |
Срез (переход от 1 к 0) |
1 |
1 |
Фронт (переход от 0 к 1) |
Прерывание по фронту или срезу устанавливает флаг в регистре GIFR, его сброс выполняется автоматически при вызове подпрограммы прерывания (ISR), если данное прерывание запрещено флаг следует сбросить программно записью единицы в бит флага.
Прерывание по низкому уровню отличается от других отсутствием триггера запоминания, поэтому это прерывание активно все время, пока на входе присутствует низкий уровень, и «забывается», если к моменту предоставления прерывания уровень стал высоким.
Программное обеспечение прерываний состоит из подготовки (инициализации) и собственно ISR. На этапе инициализации программируются регистры маски [GIMSK], настройки на событие [MCUCR], настройки соответствующего вывода на вход [DDRD]. Последним действием этапа инициализации обычно выполняется команда общего разрешения прерывания [sei].
Обязательными элементами ISR являются целевые действия и команда выхода из прерывания [reti].
Ниже приведен пример использования входов прерывания INT0 и INT1 с реализацией на ассемблере и на GNU-C, схема примера и результаты измерений в симуляторе AVR-Studio.
//INT0/PD2 – счет импульсов, если частота выше порога 200Гц, то включить красный светодиод на выходе PD4, иначе переключать светодиод с частотой 10 Гц
//INT1/PD3 – по срезу кнопки на этом входе переключать зеленый светодиод на выходе PD0
Пример на Ассемблере |
Пример на GNU-С |
.include <8515def.inc> .macro LOAD ;@0, @1 ldi r16,@1 out @0,r16 .endm .def cnt = r17 .def tmp_int0 = r0 .equ N = 10 rjmp START .org INT0addr rjmp ISR_INT0 rjmp ISR_INT1 .org INT_VECTORS_SIZE START: LOAD SPL,LOW(RAMEND) LOAD SPH,HIGH(RAMEND) LOAD DDRD,(1<<PD0)|(1<<PD4) LOAD PORTD, (1<<PD3)|(1<<PD0) LOAD GIMSK, (1<<INT0)|(1<<INT1) LOAD MCUCR, (1<<ISC11)|(1<<ISC01)|(1<<ISC00) clr cnt sei LOOP: ldi r18, 100 rcall WAIT_ms cpi cnt, N brlo LL sbi PORTD,PD0 rjmp MM LL: sbic PORTD,PD0 rjmp BB sbi PORTD,PD0 rjmp MM BB: cbi PORTD,PD0 MM: clr cnt rjmp LOOP ; *********************************** ISR_INT0: in tmp_int0,SREG inc cnt out SREG,tmp_int0 reti ; =================================== ISR_INT1: sbic PORTD,PD4 rjmp AA sbi PORTD,PD4 reti AA: cbi PORTD,PD4 reti ; =================================== |
#include <avr/io.h> #include <avr/interrupt.h> #include <avr/delay.h> #define N 10 char cnt; ISR(INT0_vect) { cnt++; }
ISR(INT1_vect) { if(PORTD & (1<<PD4)) PORTD &= ~(1<<PD4); else PORTD |= (1<<PD4); }
int main() { DDRD = (1<<PD0)|(1<<PD4); PORTD = (1<<PD3)|(1<<PD0); GIMSK = (1<<INT0)|(1<<INT1); MCUCR = (1<<ISC11)|(1<<ISC01)|(1<<ISC00); GIFR = (1<<INTF1)|(1<<INTF0); sei(); while(1) { _delay_ms(100); if(cnt > N) { PORTD |= (1<<PD0); } else { if(PORTD & (1<<PD0)) PORTD &= ~(1<<PD0); else PORTD |= (1<<PD0); } cnt=0; } } //***********************************
Fclk = 1 МГц |
Задержка выполнения действия в ISR_INT0: 10 мкс, 10 м.ц. в ISR_INT1: 7 мкс, 7 м.ц. Время выполнения в ISR_INT0: 16 мкс, 16 м.ц. в ISR_INT1: 15 мкс, 15 м.ц. Период основного цикла 100318 мкс |
Задержка выполнения действия в ISR_INT0: 23 мкс, 23 м.ц. в ISR_INT1: 33 мкс, 33 м.ц. Время выполнения в ISR_INT0: 48 мкс, 48 м.ц. в ISR_INT1: 85 мкс, 85 м.ц. Период основного цикла 103540 мкс |
Задержка выполнения измерялась от изменения состояния PIND.2 / PIND.3 до первой команды / оператора, выполняющей заданное действие (или выбор действия), то есть время реакции на событие. Время выполнения показывает задержку основного цикла на обслуживание данного прерывания.
Преимущество варианта на ассемблере перед свободно распространяемым транслятором GNU-C (avr-gcc) объясняется оптимальным расходом на сохранение/восстановление контекста.
Любопытные могут увидеть машинный код в файле листинга <*.lss>.и сравнить его с ассемблерным вариантом. Подпрограмма ISR_INT0 использует в качестве ячейки «глобальной» памяти РОН, для сохранения регистра состояния используется еще один РОН. Любой транслятор поместит «глобальную» ячейку в SRAM, для сохранения контекста использует стек в SRAM. Подпрограмма ISR_INT1 использует команды, которые не используют РОН и не меняют содержимое регистра состояния.
В МК ATmega48/88/168/328 имеются два входа прерывания INTх, все выводы оснащены функцией выявления изменения состояния [PCINT0…23].
Механизм входов прерывания INTх, действует подобно описанному для МК AT90S8515. Отличия сводятся к использованию ранее зарезервированной комбинации битов выбора события (ISCx1 = 0, ISCx0 = 1) для выявления любого изменения вывода, а также к смене символьных имен регистров [MCUCR, GIFR, GIMSK] на соответствующие им [EICRA, EIFR, EIMSK].
Механизм аппаратного выявления изменения состояния вывода PCINTn различает только любое изменение сигнала. Он имеет по одному вектору [PCINT0,1,2] и флагу прерывания на группу из 8 выводов, маскирование прерываний выполняется как общее на группу (например, PCICR.PCIE0 – для PCINT0…7), так и индивидуальное (PCMSK0.PCINT0). Для уточнения причины прерывания: фронт или срез и на каком из 8 выводов группы произошло изменение состояния, необходимо иметь память предыдущего состояния текущего порта и затратить время на анализ. Эти действия не нужны, если разрешен только один из 8 выводов данной группы и не имеет значение тип события (фронт или срез), тогда временные затраты не отличаются от механизма INTx.
Регистр PCICR [Pin Change Interrupt Control Register] содержит биты: PCIE0 – разрешение прерывания при изменении состояния на 8 выводах PCINT0…7, PCIE1 – на выводах PCINT8…15, и т.д.
Pin Change Interrupt Flag Register – PCIFR: Bit 0 - PCIF0: Pin Change Interrupt Flag 0, 1, 2
Pin Change Mask Register 0 – PCMSK0(1, 2): Bit 7..0 – PCINT7..0: Pin Change Enable Mask 7..0
Ориентирован для сравнительно медленных сигналов,
Сгруппированы по 8 входов - флаги (по фронту/срезу, вектора), индивидуальны - маска прерывания PCMSKx. Следовательно, для сравнительно медленных нет проблем, если используется один из входов в данном порту, иначе - требуется анализ предыдущего состояния, хотя для разбора фронт или срез...