Отчетные материалы. Отчетные материалы должны содержать

Отчетные материалы должны содержать:

1. Цель лабораторной работы.

2. Материалы, связанные с подготовкой к работе, включая теоретическую часть и заготовку программы. Обязательно включите в отчет описание регистров, влияющих на прерывания процессора.

3. Информацию по выполнению каждого пункта задания. Причем в отчете должны содержаться выполняемые Вами действия, наблюдаемые результаты и Ваши объяснения.

4. Написанные Вами фрагменты программ.

5. Краткое заключение.

Приложение

В приложении содержится исходный файл тестовой программы interrupt_example.s. В программе используются прерывания от таймера и кнопок. Обработчик прерываний от таймера содержится в файле interval_timer.s. Обработчик прерываний от кнопок содержится в файле pushbutton_ISR.s. Обработчик исключений, задачей которого является определение причины прерывания и вызов соответствующей процедуры, содержится в файле exception_handler.s.

Листинг 4 Текст программы interrupt_example.s

.equ KEY1, 0

.equ KEY2, 1

/******************************************************************************** Эта программа демонстрирует использование прерываний на стенде

* DE2-70 Media Computer. Вначале запускается таймер, который генерирует

* прерывания каждые 33 мс. Затем разрешаются прерывания от таймера и кнопок.

* Процедура обработки прерывания таймера отображает текст на 7-сегментных

* индикаторах и сдвигает его влево или вправо. Направление сдвига определяется

* кнопками. При нажатии кнопки key1 текст сдвигается вправо, при нажатии

* key2 – влево, при нажатии key3 изменяется текст, используя данные с переключателей.****************************************************************************************************************************************/

text

.global _start

_start:

movia sp, 0x03FFFFFC /* Определяем адрес вершины стека */

movia r16, 0x10002000

/* Определяем период срабатывания интервального таймера */

movia r12, 0x190000 /* 1/(50 MHz) x (0x190000) = 33 msec */

sthio r12, 8(r16) /*определяем младшее полуслово как стартовое значение*/

srli r12, r12, 16

sthio r12, 0xC(r16) /* старшее полуслово как стартовое значение */

/* Запускаем таймер и разрешаем прерывания от него */

movi r15, 0b0111 /* START = 1, CONT = 1, ITO = 1 */

sthio r15, 4(r16)

/* Разрешаем прерывания PIO, к которому подсоединены кнопки */

movia r15, 0x10000050 /* Адрес регистра кнопок */

movi r7, 0b01110

stwio r7, 8(r15) /* Устанавливаем 3 бита регистра маски прерывания*/

/* Разрешаем прерывания NIOS 2 процессора */

movi r7, 0b011

wrctl ienable, r7 /*Разрешаем прерывания от кнопок*/

movi r7, 1

wrctl status, r7 /*Разрешаем процессору обрабатывать прерывания */

IDLE:

br IDLE /* Бесконечный цикл */

data

.global PATTERN

PATTERN:

.word 0x0000000F

.global KEY_PRESSED

KEY_PRESSED:

.word KEY2

.end

Листинг 5 Текст программы exception_handler.s

/* СЕКЦИЯ СБРОСА "ax" требуется для того, чтобы определить секцию как исполняемую.AMP автоматически размещает секцию сброса по адресу, определяемому в настройках процессора в SOPC Builder.*/

.section.reset, "ax"

movia r2, _start

jmp r2 /* Переходим в основную программу */

/***************************************************************************

СЕКЦИЯ ИСКЛЮЧЕНИЙ "ax" требуется для того, чтобы определить секцию как исполняемую.AMP автоматически размещает секцию сброса по адресу, определяемому в настройках процессора в SOPC Builder.***************************************/

section.exceptions, "ax"

.global EXCEPTION_HANDLER /*Определяем процедуру как глобальную*/

EXCEPTION_HANDLER: /*Процедура обработки прерываний*/

subi sp, sp, 16 /* Изменяем адрес указателя стека */

stw et, 0(sp) /*Сохраняем содержимое регистра et в стеке*/

rdctl et, ctl4

beq et, r0, SKIP_EA_DEC /* Если прерывание не внешнее, то переходим на SKIP_EA_DEC */

subi ea, ea, 4 /* декрементируем регистр ea на 1 команду */

SKIP_EA_DEC:

stw ea, 4(sp) /* Сохраняем регистры в стеке */

stw ra, 8(sp)

stw r22, 12(sp)

rdctl et, ctl4

bne et, r0, CHECK_LEVEL_0 /* Если прерывание внешнее, то переходим на CHECK_LEVEL_0*/

NOT_EI: /* Прерывание произошло в случае встречи невыполнимой команды или команды TRAP */

br END_ISR /* Выходим из обработчика прерываний */

CHECK_LEVEL_0: /* Проверка, является ли прерывание прерыванием от таймера IRQ0 */

andi r22, et, 0b1

beq r22, r0, CHECK_LEVEL_1 /*Если бит 0b1 регистра et не равен 1, то переходим к проверке, является ли прерывание прерыванием от кнопок*/

call INTERVAL_TIMER_ISR /*Вызываем процедуру обработки прерывания от таймера*/

br END_ISR /*Выходим из обработчика прерываний*/

CHECK_LEVEL_1: /*Проверка, является ли прерывание прерыванием от кнопок IRQ1*/

andi r22, et, 0b10

beq r22, r0, END_ISR /* Если бит 0b10 регистра et не равен 10, то выходим из обработчика прерываний*/

call PUSHBUTTON_ISR /*Вызываем процедуру обработки прерываний от кнопок*/

END_ISR:

/*Восстанавливаем из стека все используемые регистры*/

ldw et, 0(sp)

ldw ea, 4(sp)

ldw ra, 8(sp)

ldw r22, 12(sp)

addi sp, sp, 16

eret /*Выходим из процедуры обработки прерывания*/

.end

Листинг 6 Текст программы interval_timer.s

.include "key_codes.s"

.extern PATTERN

.extern KEY_PRESSED

/****************** Процедура обработки прерываний от таймера****************/

.global INTERVAL_TIMER_ISR

INTERVAL_TIMER_ISR:

subi sp, sp, 40 /* Сохраняем регистры в стеке */

stw ra, 0(sp)

stw r4, 4(sp)

stw r5, 8(sp)

stw r6, 12(sp)

stw r8, 16(sp)

stw r10, 20(sp)

stw r20, 24(sp)

stw r21, 28(sp)

stw r22, 32(sp)

stw r23, 36(sp)

movia r10, 0x10002000

sthio r0, 0(r10)

movia r20, 0x10000020 /*адрес регистра HEX3_HEX0 */

movia r21, 0x10000030 /*адрес регистра HEX7_HEX4*/

addi r5, r0, 1

movia r22, PATTERN

movia r23, KEY_PRESSED

ldw r6, 0(r22) /* загружаем текст для вывода на 7-сегментные индикаторы */

stwio r6, 0(r20) /* выводим на HEX3... HEX0 */

stwio r6, 0(r21) /* выводим на HEX7... HEX4 */

ldw r4, 0(r23) /* Проверяем, какая кнопка была нажата */

movi r8, KEY1

beq r4, r8, LEFT /* Если была нажата key1, то сдвигаем текст вправо */

rol r6, r6, r5 /* иначе, сдвигаем влево */

br END_INTERVAL_TIMER_ISR

LEFT:

ror r6, r6, r5 /* сдвигаем текст вправо*/

END_INTERVAL_TIMER_ISR:

stw r6, 0(r22) /* выводим текст на 7-сегментные индикаторы */

ldw ra, 0(sp) /* Восстанавливаем регистры из стека */

ldw r4, 4(sp)

ldw r5, 8(sp)

ldw r6, 12(sp)

ldw r8, 16(sp)

ldw r10, 20(sp)

ldw r20, 24(sp)

ldw r21, 28(sp)

ldw r22, 32(sp)

ldw r23, 36(sp)

addi sp, sp, 40

ret

.end

Листинг 7 Текст программы pushbutton_ISR.s

.include "key_codes.s"

.extern KEY_PRESSED

.extern PATTERN

/******************* Обработчик прерываний от кнопок************************/

.global PUSHBUTTON_ISR

PUSHBUTTON_ISR:

subi sp, sp, 20 /* Сохраняем регистры в стеке*/

stw ra, 0(sp)

stw r10, 4(sp)

stw r11, 8(sp)

stw r12, 12(sp)

stw r13, 16(sp)

movia r10, 0x10000050

ldwio r11, 0xC(r10) /* Считываем значение из edge-capture регистра*/

stwio r0, 0xC(r10) /* Сбрасываем прерывание */

movia r10, KEY_PRESSED

CHECK_KEY1:

andi r13, r11, 0b0010 /* Если была нажата кнопка key1 */

beq r13, zero, CHECK_KEY2

movi r12, KEY1

stw r12, 0(r10)

br END_PUSHBUTTON_ISR

CHECK_KEY2:

andi r13, r11, 0b0100 /* Если была нажата кнопка key2*/

beq r13, zero, DO_KEY3

movi r12, KEY2

stw r12, 0(r10)

br END_PUSHBUTTON_ISR

DO_KEY3:

movia r13, 0x10000040

ldwio r11, 0(r13) /* Считываем значение с переключателей */

movia r13, PATTERN

stw r11, 0(r13) /* Сохраняем измененный текст */

END_PUSHBUTTON_ISR:

ldw ra, 0(sp) /* Восстанавливаем регистры из стека */

ldw r10, 4(sp)

ldw r11, 8(sp)

ldw r12, 12(sp)

ldw r13, 16(sp)

addi sp, sp, 20

ret

.end


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: