Цель работы. Целью лабораторной работы является отладка прикладных программ для микроконтроллера AVR семейства Tiny с помощью персонального компьютера и программных средств отладки.
1. Загрузить для отладки в AVR Studio программу преобразования целых 16-битных чисел в двоично-десятичные числа. Алгоритм программы "bin16BCD5" заключается в следующем. Предположим, что имеется целое беззнаковое 16-битное число (диапазон от 0 до 65535). Очевидно, что необходимо найти 5 десятичных цифр. Способ преобразования заключается в том, чтобы, вычитая из исходного числа число 10000, сначала определить десятичную цифру десятков тысяч. Затем находится цифра тысяч последовательным вычитанием числа 1000 и т. д. Вычитание каждый раз производится до получения отрицательной разности с подсчетом числа вычитаний. При переходе к определению каждого следующего десятичного разряда в регистрах исходного числа восстанавливается последняя положительная разность. После того, как будет найдена десятичная цифра десятков, в регистрах исходного числа останется десятичная цифра единиц.
Проследить выполнение программы в пошаговом и автоматическом режиме, записав предварительно в регистры r16 и r17 шестнадцатеричное число $NNNN, где N - номер варианта, задаваемый преподавателем (число от 1 до 9). В окне I/O раскройте содержимое Register 1-31, Processor, I/O ATTINY15 (CPU, WATCHDOG). Какие команды программы влияют на флаги регистра статуса SREG? Зафиксируйте в отчете результат преобразования. В программе часто используются команды вычитания константы из регистра. Есть ли в системе команд AVR аналогичные команды сложения регистра и константы? Как будет работать программа, если в ней удалить последнюю команду?
;***** Программа bin16BCD5 | |||
.DEVICE ATtiny15 | ; Определить устройство | ||
.INCLUDE | |||
"C:\Program Files\Atmel\AVR Tools\AvrAssembler\Appnotes\tn15def.inc" | |||
; Вложить файл определения адресов регистров ввода\вывода | |||
;***** Регистровые переменные | |||
.def | fbinL | =r16 | ; двоичное значение, младший байт |
.def | fbinH | =r17 | ; двоичное значение, старший байт |
.def | tBCD0 | =r17 | ; BCD значение, цифры 1 и 0 |
.def | tBCD1 | =r18 | ; BCD значение, цифры 3 и 2 |
.def | tBCD2 | =r19 | ; BCD значение, цифра 4 |
; Переменные fbinH и tBCD0 должны размещаться в одном регистре | |||
WDR | ; Сброс сторожевого таймера | ||
ldi | r20,0b00001000 | ; Включение сторожевого | |
out | WDTCR,r20 | ; таймера | |
ldi | tBCD2, -1 | ; Начало преобразования | |
m1: | |||
inc | tBCD2 | ||
subi | fbinL, low(10000) | ||
sbci | fbinH, high(10000) | ||
brsh | m1 | ||
subi | fbinL, low(-10000) | ||
sbci | fbinH, high(-10000) | ||
ldi | tBCD1, -0x11 | ||
m2: | |||
subi | tBCD1, -0x10 | ||
subi | fbinL, low(1000) | ||
sbci | fbinH, high(1000) | ||
brsh | m2 | ||
subi | fbinL, low(-1000) | ||
sbci | fbinH, high(-1000) | ||
m3: | |||
inc | tBCD1 | ||
subi | fbinL, low(100) | ||
sbci | fbinH, high(100) | ||
brsh | m3 | ||
subi | fbinL, -100 | ||
ldi | tBCD0, -0x10 | ||
m4: | |||
subi | tBCD0, -0x10 | ||
subi | fbinL, 10 | ||
brsh | m4 | ||
subi | fbinL, -10 | ||
add | tBCD0, fbinL | ; Конец преобразования | |
m5: | rjmp | m5 | ; Зацикливание программы |
Какой период срабатывания сторожевого таймера задан в программе? Что будет, если дождаться его срабатывания?
2. Загрузить для отладки в AVR Studio программу CLOK, реализующую двоично-десятичный счетчик на регистре r19. Счетчик считает с частотой прерываний по переполнению таймера Т0. Тактовый сигнал на вход таймера подается через программируемый делитель частоты. Коэффициент пересчета счетчика равен 100. Для счета используются вспомогательные регистры r16 (счет единиц), r17 (счет десятков) и r18 (объединение десятков и единиц). Основная программа обнуляет регистры счетчика, устанавливает режим работы Т0, разрешает прерывания по переполнению Т0 и зацикливается. Двоично-десятичный счет реализуется в подпрограмме прерывания, расположенной начиная с адреса вектора прерывания по переполнению таймера Т0. Заметим, что в системе команд AVR нет команды сложения регистра с константой и команды десятичной коррекции аккумулятора, как и самого аккумулятора.
Набрать исходный текст программы CLOK.asm без комментария. Проверить работу в пошаговом и автоматическом режимах. В окне I/O AVR Studio раскройте содержимое Register 1-31, I/O ATTINY15 (CPU, TIMER_COUNTER_0).
;****** Программа CLOK | |||
.DEVICE ATtiny15 | |||
.INCLUDE | |||
"C:\Program Files\Atmel\AVR Tools\AvrAssembler\Appnotes\tn15def.inc" | |||
rjmp | RESET | ||
.org | $005 | ; Вектор прерывания по переполнению T0 | |
inc | r16 | ; Инкремент единиц | |
cpi | r16,$0A | ||
breq | m1 | ||
rjmp | m3 | ||
m1: | clr | r16 | |
subi | r17,-$10 | ; Инкремент десятков | |
cpi | r17,$A0 | ||
breq | m2 | ||
rjmp | m3 | ||
m2: | clr | r17 | |
m3: | mov | r18,r17 | |
add | r18,r16 | ||
mov | r19,r18 | ; Инкремент двоично-десятичного счета | |
reti | |||
RESET: | |||
clr | r16 | ; Обнуление регистров | |
clr | r17 | ||
clr | r18 | ||
clr | r19 | ||
ldi | r20,0b00000001 | ; Выбор источника тактового сигнала для Т0 | |
out | TCCR0,r20 | ||
ldi | r20,0b00000010 | ; Разрешение прерываний | |
out | TIMSK,r20 | ; по переполнению таймера T0 | |
sei | ; Глобальное разрешение прерываний | ||
m4: | rjmp | m4 |
С какой частотой переполняется Т0? Каким образом можно уменьшить скорость счета в 1024 раза? Объяснить поведение регистров SREG и TIFR при работе программы. Пояснить назначение директивы .DEVICE. Пояснить содержимое файла clok.map в окне Project.
Изменить программу так, чтобы уменьшить коэффициент пересчета счетчика до 10N, где N - номер варианта, назначаемый преподавателем. В отчете представить измененный вариант программы с комментарием.
3. Сформировать на выводе РВ1 (ОС1А) микроконтроллера ШИМ-сигнал с частотой 50 кГц (программа PWM1). Таймер Т1 используется как генератор импульсов с программируемым периодом (содержимое регистра сравнения OCR1B) и длительностью (содержимое регистра сравнения OCR1А). В окне I/O раскройте содержимое Register 1-31, Processor, I/O ATTINY15 (PORTB, TIMER_COUNTER_1).
;****** Программа PWM1 | |||
.DEVICE ATtiny15 | |||
.INCLUDE | |||
"C:\Program Files\Atmel\AVR Tools\AvrAssembler\Appnotes\tn15def.inc" | |||
sbi | DDRB,1 | ; Настройка первой линии порта В на вывод | |
ldi | r16,0b01100010 | ; Режим работы Т1 (ШИМ с частотой | |
; тактирования 12.8 МГц, 1 при сбросе, | |||
; 0 при сравнении) | |||
out | TCCR1,r16 | ||
ldi | r16,0xFF | ; Частота импульсов 50 кГц | |
out | OCR1B,r16 | ||
ldi | r16,0x80 | ; Скважность импульсов примерно 2 | |
out | OCR1A,r16 | ||
m1: | rjmp | m1 | |
Проследить работу программы в пошаговом режиме. На сколько меняется содержимое Т1 при выполнении команды rjmp m1? Почему? Какие флаги устанавливаются в регистре TIFR?
Модифицировать программу так, чтобы частота ШИМ составила 20 кГц, а скважность 4 (отношение периода к длительности импульса).
4. Проверить программу обращения к энергонезависимой памяти данных EEPROM (проект EEPROM). Открыть окна для просмотра регистров общего назначения 16-31, регистров ввода/вывода (CPU, EEPROM), памяти EEPROM (Memory 3). Проследите выполнение программы в пошаговом режиме. Когда выполняется подпрограмма прерывания и что она делает? Специального флага прерываний от EEPROM нет, поэтому при обращении к подпрограмме прерывания флаг не сбрасывается и прерывания генерируются постоянно.
;****** Программа EEPROM | |||
.DEVICE ATtiny15 | |||
.INCLUDE | |||
"C:\Program Files\Atmel\AVR Tools\AvrAssembler\Appnotes\tn15def.inc" | |||
.cseg | |||
; Рабочие переменные | |||
.def AddrReg=r20 | |||
.def Data1Reg=r21 | |||
.def Data2Reg=r22 | |||
; Векторы прерываний | |||
rjmp | RESET | ||
reti | |||
reti | |||
reti | |||
reti | |||
reti | |||
rjmp | EEPROM_READY | ; Вектор прерывания по записи в EEPROM | |
reti | |||
reti | |||
EEPROM_READY: | ; Подпрограмма прерывания по окончании | ||
inc | r25 | ; цикла записи в EEPROM | |
reti | |||
EEWrite: | ; Подпрограмма записи байта в EEPROM | ||
sbic | EECR,EEWE | ; Ждать, пока флаг EEWE | |
rjmp | EEWRite | ; не будет сброшен | |
cli | ; Запретить прерывания | ||
out | EEAR,AddrReg | ; Загрузить адрес | |
out | EEDR,Data1Reg | ; Загрузить данные | |
sbi | EECR,EEMWE | ||
sbi | EECR,EEWE | ; Выдать строб записи байта в EEPROM | |
sbi | EECR,EERIE | ; Разрешить прерывание по завершении | |
sei | ; цикла записи в EEPROM | ||
cbi | EECR,EERIE | ; Запретить дальнейшие прерывания | |
ret | |||
EERead: | ; Подпрограмма чтения байта EEPROM | ||
sbic | EECR,EEWE | ; Ждать окончания текущей записи пока | |
rjmp | EERead | ; флаг EEWE не равен 0 | |
rjmp | EEWRite | ||
out | EEAR,AddrReg | ; Загрузить адрес | |
sbi | EECR,EERE | ; Выдать строб чтения из EEPROM | |
in | Data2Reg,EEDR | ; Прочитанный байт в регистр | |
ret | |||
RESET: | |||
clr | r25 | ; Начало основной программы | |
clr | r21 | ; Очистка регистров | |
clr | r22 | ||
ldi | AddrReg,$18 | ||
ldi | Data1Reg,$DD | ||
rcall | EEWrite | ; Вызов подпрограммы записи в EEPROM | |
rcall | EERead | ; Вызов подпрограммы чтения из EEPROM | |
m1: | rjmp | m1 |
Изменить программу так, чтобы она записывала в ячейку N EEPROM число 100+N, а читала записанный байт в регистр rN, где N - номер варианта, задаваемый преподавателем (число от 1 до 9).
Отчет в формате WORD должен содержать тексты измененных (в соответствии с вариантом задания) программ с комментариями, ответы на вопросы по пунктам работы, рисунки, отображающие окна регистров и памяти, ответы на контрольные вопросы.