Задачи:
Познакомиться с понятием прерывание, таблица и вектора прерываний, обработчик прерывания.
Научиться использовать таймер и его прерывания для выполнения действий через фиксированные промежутки времени.
Работа:
1. Создать проект на языке Assembler, скопировать приведённый ниже код примера, проверить его работоспособность.
2. Написать аналогичный код на языке C. Попробовать изменить предделитель ядра на другое значение. Посмотреть, как изменится скорость мигания светодиода. (см. стр. 37 документации на котроллер).
3. Изменить режим работы таймера на CTC, выбрать такое значение сравнения, чтобы светодиод с частотой 1 Гц (стр. 138-139, 147-154 документации). Обработчик прерывания - ISR(TIM0_COMPA_vect)
4.* Задать задержку между переключениями светодиода как #define, вычисляемый на основании используемых предделителей и частоты источника тактовых импульсов.
Код на Assembler:
.def Temp = R17
.ORG 0x000
RJMP RESET
.ORG TIM0_OVFaddr
RJMP Tim_OVF
.ORG INT_VECTORS_SIZE
Tim_OVF:
IN Temp, PINA
NEG Temp
OUT PORTA, Temp
RETI
RESET:
LDI R16, Low(RAMEND)
OUT SPL, R16
LDI R16, High(RAMEND)
OUT SPH, R16
LDI Temp, 0xD8
OUT CCP, Temp
LDI Temp, 0x00
OUT CLKPSR, Temp
SBI DDRA, DDRA5
LDI Temp, (1<<CS00) | (0<<CS01)
OUT TCCR0B, Temp
LDI Temp, (1 << TOIE0)
OUT TIMSK0, Temp
SEI
loop:
RJMP loop
Заготовка кода на C:
#include <avr/io.h>
#include <avr/interrupt.h>
int main(void)
{
// Инициализация
while (1) { }
}
ISR(TIM0_OVF_vect)
{
// Прерывание по переполнению таймера
}
Комментарии и рекомендации:
• Перед тем, как начинать перенос кода между языками разбейте код на логические блоки — инициализация, основной цикл, отдельно каждое используемое прерывание.
• Большая часть работы с микроконтроллером в рамках наших лабораторных работ состоит в настройке регистров ввода/вывода. На Assembler'e это делается комбинацией операций LDI + OUT, или SBI/CBI и похожими. Каждая такая комбинация может быть представлена в виде одной строчки кода в языке C. Например:
LDI Temp, 0xD8
OUT CCP, Temp
транслируется в
CCP = 0xD8;
• В случаях использования в коде прерываний обязательно должна производиться инициализация стека. В коде на Assembler'е за это отвечают строки
LDI R16, Low(RAMEND)
OUT SPL, R16
LDI R16, High(RAMEND)
OUT SPH, R16
А при работе на языке С инициализация стека выполняется компилятором и вручную этого делать не нужно. Эти строки при переносе кода можно проигнорировать
• Чтобы написать обработчик другого прерывания на языке C необходимо изменить значение в скобках после ISR(). Можно использовать заранее определенные константы из заголовочного файла, или номера векторов прерываний напрямую. Например, обработчик прерывания по переполнению таймера мог быть объявлен как:
ISR(_VECTOR(5))
{
}
Во время написания программы базовые математические вычисления могут проводиться прямо в коде. Результат будет вычисляться на компьютере до компиляции программы. Это часто используется для вычисления каких-то констант, имеющих сложную зависимость от нескольких других параметров. Используйте это для выполнения задания 4*. В примере формулы и значения неверные:
#define TARGET_FREQ 100 // Target LED frequency in Hz
#define COMPARE_VAL 4000 / 256 * TARGET_FREQ // Compare value for TCA0
...
OCR0A = COMPARE_VAL; // Use computed compare value for timer setup
Вопросы к защите (теория):
Источники тактовых импульсов, применяемые для тактирования цифровой электроники
Рассказать об одном из режимов работы таймера (счётный, Normal, CTC)
Дать определение прерываниям, привести примеры, рассказать о смысле их использования
Система тактирования микроконтроллера, предделители.
Зачем при установке предделителя ядра требуется последовательная запись в 2 регистра
Рассказать порядок выполнения команд на assembler’e в случае работы с прерываниями
Практическая задача:
Даны частота источника тактовых импульсов, предделитель ядра PS1, предделитель таймера PS2, разрядность таймера, режим его работы, частота возникновения прерываний/частота мигания светодиода при коде, аналогичном тому, что в лабе. Найти один из этих параметров. Пример: Freq = 8 000 000
PS1 = 8
PS2 = 256
10-битный таймер, режим CTC
Найти значение регистра сравнения, если светодиод мигает с частотой 4 Гц.