Листинг 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;

}

 









Дата добавления: 2015-05-30; просмотров: 779;


Поиск по сайту:

При помощи поиска вы сможете найти нужную вам информацию.

Поделитесь с друзьями:

Если вам перенёс пользу информационный материал, или помог в учебе – поделитесь этим сайтом с друзьями и знакомыми.
helpiks.org - Хелпикс.Орг - 2014-2024 год. Материал сайта представляется для ознакомительного и учебного использования. | Поддержка
Генерация страницы за: 0.018 сек.