Файл: Лабораторная работа 2. Система прерываний. Таймерсчётчик.doc
ВУЗ: Не указан
Категория: Не указан
Дисциплина: Не указана
Добавлен: 08.11.2023
Просмотров: 23
Скачиваний: 2
ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.
Лабораторная работа №2.
Система прерываний. Таймер/счётчик.
Прерывания в микроконтроллерах AVR служат для обработки внешних и внутренних событий. Самое первое, что происходит в случае сброса или включения микроконтроллера – обработка прерывания RESET. Это прерывание нельзя запретить, в отличие от остальных, командой CLI (очистки флага I в регистре SREG). При сбросе, все I/O регистры устанавливаются в их начальные значения, и программа начинает выполнение с адреса $000. По этому адресу должна быть расположена инструкция RJMP (Относительный переход) на процедуру обработки сброса. Эта процедура фактически может являться главным блоком программы. Если программа не использует прерывания, и вектора прерываний не задействованы, то по адресу $000 может располагаться любая команда основной программы. Приведём эти варианты:
Если прерывания не задействованы | Если прерывания задействованы |
.CSEG .ORG 0 LDI r16,0xAA ;код программы | .CSEG ;начало сегмента программы .ORG 0 ;адрес $000 кода RJMP reset;обработка reset .ORG 2 ;адрес $002(вектор EXT0INT) RJMP ext0irq; Обработка ;внешнего прерывания 0 ext0irq: … ;команды обработки прерывания reti reset: LDI r16, 0xAA ; код программы |
Микроконтроллер может обрабатывать следующие прерывания:
Адрес вектора | Метка, определённая в M16def.inc (через .EQU) | Описание прерывания |
$000 | | Reset |
$002 | INT0addr | Внешнее прерывание 0 (вывод 16 = PortD 2) |
$004 | INT1addr | Внешнее прерывание 1 (вывод 17 = PortD 3) |
$006 | OC2addr | Совпадение с константой таймера/счётчика 2 |
$008 | OVF2addr | Переполнение таймера/счётчика 2 |
$00A | ICP1addr | Захват таймера/счётчика 1 |
$00C | OC1Aaddr | Совпадение с константой A таймера/счётчика 1 |
$00E | OC1Baddr | Совпадение с константой B таймера/счётчика 1 |
$010 | OVF1addr | Переполнение таймера/счётчика 1 |
$012 | OVF0addr | Переполнение таймера/счётчика 0 |
$014 | SPIaddr | Прерывание от SPI |
$016 | URXCaddr | Прерывание от UART: приём данных окончен |
$018 | UDREaddr | Прерывание от UART: регистр данных пуст |
$01A | UTXCaddr | Прерывание от UART: передача данных завершена |
$01C | ADCCaddr | Прерывание от ADC: преобразование закончено |
$01E | ERDYaddr | Прерывание от EEPROM: готовность |
$020 | ACIaddr | Прерывание от аналогового компаратора |
$022 | TWIaddr | Прерывание от двухпроводного посл.интерфейса |
$024 | INT2addr | Внешнее прерывание 2 (вывод 3 = PortB 2) |
$026 | OC0addr | Совпадение с константой таймера/счётчика 0 |
$028 | SPMRaddr | Прерывание от программной памяти: загрузка окончена |
Помимо общего запрета (командой CLI) и разрешения (командой SEI) прерываний, необходимо разрешать каждое прерывание по отдельности.
ВАЖНО: Во время вызова обработчиков прерываний и процедур, адрес возврата программного счётчика (откуда дальше продолжать программу) сохраняется в стеке. Стэк в микроконтроллерах организован программно, поэтому все программы, использующие прерывания и процедуры, должны инициализировать стек при начале работы! Делается это следующим образом:
ldi temp,low(RAMEND) ; Берём младший байт адреса RAMEND
out SPL,temp ;Записываем в младший байт указателя стека
ldi temp,high(RAMEND) ; Старший байт адреса
out SPH,temp ;в старший байт указателя стека
Для настройки микроконтроллера на использование прерываний необходимо произвести инициализацию регистров соответствующими значениями (описания регистров – в методичке):
Вид прерывания | Регистры |
External Interrupt | MCUCR, MCUCSR, GICR |
Timer/Counter Interrupts | TIMSK |
Также не забывайте: чтобы прерывание от к.л. модуля работало, должен работать сам модуль.
Индивидуальные задания:
Вариант | Текст задания |
1 | Разработать программу, которая, используя прерывание от счётчика 0, увеличивает значение к.л. регистра на 1 каждую секунду и выводит значение на панель светодиодов. Вектор прерывания: OC0addr |
2 | Разработать программу, которая увеличивает значение к.л. регистра по переполнению счётчика 1 и выводит результат на панель светодиодов.. Вектор прерывания: OVF1addr |
3 | Разработать программу, которая, используя прерывание от счётчика 1, увеличивает значение к.л. регистра на 1 каждую секунду и выводит значение на панель светодиодов. Вектор прерывания: OC1Aaddr/ OC1Baddr |
4 | Разработать программу, которая увеличивает значение к.л. регистра по переполнению счётчика 0 и выводит результат на панель светодиодов. Вектор прерывания: OVF0addr |
5 | Разработать программу, которая увеличивает значение к.л. регистра по прерыванию INT0, которое инициируется спадающим фронтом сигнала, и выводит результат на панель светодиодов. Вектор прерывания: INT0addr |
6 | Разработать программу, которая увеличивает значение к.л. регистра по прерыванию INT1, которое инициируется спадающим фронтом сигнала, и выводит результат на панель светодиодов. Вектор прерывания: INT1addr |
7 | Разработать программу, которая увеличивает значение к.л. регистра по прерыванию INT0, которое инициируется нарастающим фронтом сигнала, и выводит результат на панель светодиодов. Вектор прерывания: INT0addr |
8 | Разработать программу, которая увеличивает значение к.л. регистра по прерыванию INT1, которое инициируется нарастающим фронтом сигнала, и выводит результат на панель светодиодов. Вектор прерывания: INT1addr |
9 | Разработать программу, которая увеличивает значение к.л. регистра по переполнению счётчика 2 и выводит результат на панель светодиодов. Вектор прерывания: OVF2addr |
10 | Разработать программу, которая, используя прерывание от счётчика 2, увеличивает значение к.л. регистра на 1 каждую секунду и выводит значение на панель светодиодов. Вектор прерывания: OC2addr |
11 | Разработать программу, которая увеличивает значение к.л. регистра по прерыванию INT2, которое инициируется спадающим фронтом сигнала, и выводит результат на панель светодиодов. Вектор прерывания: INT2addr |
12 | Разработать программу, которая увеличивает значение к.л. регистра по прерыванию INT2, которое инициируется нарастающим фронтом сигнала, и выводит результат на панель светодиодов. Вектор прерывания: INT2addr |
* Микроконтроллер в стенде STK 500 работает на частоте 3.68 MHz.