Добавил:
I want to die Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

лр2 / FAQ

.docx
Скачиваний:
0
Добавлен:
07.06.2023
Размер:
21.78 Кб
Скачать

Задачи:

  • Познакомиться с понятием прерывание, таблица и вектора прерываний, обработчик прерывания.

  • Научиться использовать таймер и его прерывания для выполнения действий через фиксированные промежутки времени.

Работа:

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 Гц.