Листинг 13. Обработчики сброса и исключений на С


#include "nios2_ctrl_reg_macros.h"

void main(void);

void interrupt_handler(void);

void interval_timer_isr(void);

void pushbutton_ISR(void);

/* глобальные переменные */

extern int key_pressed;

/* Код на языке ассемблер, выполняющийся при сбросе процессора */

void the_reset (void) __attribute__ ((section (".reset")));

void the_reset (void)

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

* Обработчик сброса

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

{

asm (".set noat");

asm (".set nobreak");

asm ("movia r2, main"); //вызывается основная программа на С

asm ("jmp r2");

}

/* Код на языке ассемблер, выполняющийся при возникновении прерывания или исключения*/

void the_exception (void) __attribute__ ((section (".exceptions")));

void the_exception (void)

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

* Обработчик исключений

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

{

asm (".set noat");

asm (".set nobreak");

asm ("subi sp, sp, 128");

asm ("stw et, 96(sp)");

asm ("rdctl et, ctl4");

asm ("beq et, r0, SKIP_EA_DEC"); //прерывания не внешние

asm ("subi ea, ea, 4"); //декрементируем регистр ea на 1 команду

asm ("SKIP_EA_DEC:");

asm ("stw r1, 4(sp)"); //сохраняем содержимое всех регистров в стеке

asm ("stw r2, 8(sp)");

asm ("stw r3, 12(sp)");

asm ("stw r4, 16(sp)");

asm ("stw r5, 20(sp)");

asm ("stw r6, 24(sp)");

asm ("stw r7, 28(sp)");

asm ("stw r8, 32(sp)");

asm ("stw r9, 36(sp)");

asm ("stw r10, 40(sp)");

asm ("stw r11, 44(sp)");

asm ("stw r12, 48(sp)");

asm ("stw r13, 52(sp)");

asm ("stw r14, 56(sp)");

asm ("stw r15, 60(sp)");

asm ("stw r16, 64(sp)");

asm ("stw r17, 68(sp)");

asm ("stw r18, 72(sp)");

asm ("stw r19, 76(sp)");

asm ("stw r20, 80(sp)");

asm ("stw r21, 84(sp)");

asm ("stw r22, 88(sp)");

asm ("stw r23, 92(sp)");

asm ("stw r25, 100(sp)"); // r25 = bt

asm ("stw r26, 104(sp)"); // r26 = gp

asm ("stw r28, 112(sp)"); // r28 = fp

asm ("stw r29, 116(sp)"); // r29 = ea

asm ("stw r30, 120(sp)"); // r30 = ba

asm ("stw r31, 124(sp)"); // r31 = ra

asm ("addi fp, sp, 128");

asm ("call interrupt_handler"); //вызываем процедуру обработки прерывания

asm ("ldw r1, 4(sp)"); //восстанавливаем содержимое всех регистров

asm ("ldw r2, 8(sp)");

asm ("ldw r3, 12(sp)");

asm ("ldw r4, 16(sp)");

asm ("ldw r5, 20(sp)");

asm ("ldw r6, 24(sp)");

asm ("ldw r7, 28(sp)");

asm ("ldw r8, 32(sp)");

asm ("ldw r9, 36(sp)");

asm ("ldw r10, 40(sp)");

asm ("ldw r11, 44(sp)");

asm ("ldw r12, 48(sp)");

asm ("ldw r13, 52(sp)");

asm ("ldw r14, 56(sp)");

asm ("ldw r15, 60(sp)");

asm ("ldw r16, 64(sp)");

asm ("ldw r17, 68(sp)");

asm ("ldw r18, 72(sp)");

asm ("ldw r19, 76(sp)");

asm ("ldw r20, 80(sp)");

asm ("ldw r21, 84(sp)");

asm ("ldw r22, 88(sp)");

asm ("ldw r23, 92(sp)");

asm ("ldw r24, 96(sp)");

asm ("ldw r25, 100(sp)"); // r25 = bt

asm ("ldw r26, 104(sp)"); // r26 = gp

asm ("ldw r28, 112(sp)"); // r28 = fp

asm ("ldw r29, 116(sp)"); // r29 = ea

asm ("ldw r30, 120(sp)"); // r30 = ba

asm ("ldw r31, 124(sp)"); // r31 = ra

asm ("addi sp, sp, 128"); //увеличиваем адрес указателя стека

asm ("eret"); //выходим из обработчика прерывания

}

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

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

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

void interrupt_handler(void)

{

int ipending;

NIOS2_READ_IPENDING(ipending); //читаем содержимое бита ipending

if (ipending & 0x1) //если было обнаружено прерывание от таймера

{

interval_timer_isr(); //вызываем процедуру обработки прерываний от таймера

}

if (ipending & 0x2) // если было обнаружено прерывание от кнопок

{

pushbutton_ISR(); //вызываем процедуру обработки прерываний от кнопок

}

return;

}


Листинг 14. Программа обслуживания прерываний от интервального таймера

#include "key_codes.h"

extern volatile int key_pressed;

extern volatile int pattern;

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

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

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

void interval_timer_isr()

{

volatile int * interval_timer_ptr = (int *) 0x10002000; //базовый адрес таймера

volatile int * HEX3_HEX0_ptr = (int *) 0x10000020; //адрес HEX3_HEX0

volatile int * HEX7_HEX4_ptr = (int *) 0x10000030; //адрес HEX7_HEX4

*(interval_timer_ptr) = 0; //Сбрасываем прерывания

*(HEX3_HEX0_ptr) = pattern; // вывод заготовки на HEX3_HEX0

*(HEX7_HEX4_ptr) = pattern; // вывод заготовки на HEX7_HEX4

/* сдвигаем текст на 7-сегментных индикаторах */

if (key_pressed == KEY2) //если была нажата кнопка KEY2, то сдвигаем текст влево

if (pattern & 0x80000000)

pattern = (pattern << 1) | 1;

else

pattern = pattern << 1;

else if (key_pressed == KEY1) //если была нажата кнопка KEY1, то сдвигаем текст вправо

if (pattern & 0x00000001)

pattern = (pattern >> 1) | 0x80000000;

else

pattern = (pattern >> 1) & 0x7FFFFFFF;

return;

}



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



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