Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: LPC2214 не генериться прерывание SPI
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
Slider_spb
Идея в следующем:
Используються прерывания Timer0 Uart0 EINT0 I2C SPI0

Все прерывания проходят кроме SPI0
Причём первый байт принимаеться правильно флаг прерывания разрешён и выставляеться
но по вектору прерывания не обращается....

значение регистров после принятия данных...

S0SPCR = 0x90;
S0SPSR =0xA0;
S0SPDR =0x35; // превильно принятый байт

S0SPINT=0x01;

ниже выборка кода

/ VIC Channel Assignments
#define VIC_WDT 0
#define VIC_TIMER0 4
#define VIC_TIMER1 5
#define VIC_UART0 6
#define VIC_UART1 7
#define VIC_PWM 8
#define VIC_PWM0 8
#define VIC_I2C 9
#define VIC_SPI 10
#define VIC_SPI0 10
#define VIC_SPI1 11
#define VIC_PLL 12
#define VIC_RTC 13
#define VIC_EINT0 14
#define VIC_EINT1 15
#define VIC_EINT2 16
#define VIC_EINT3 17
#define VIC_ADC 18


#define VIC_TIMER0_bit (1 << VIC_TIMER0)
#define VIC_TIMER1_bit (1 << VIC_TIMER1)
#define VIC_UART0_bit (1 << VIC_UART0)
#define VIC_UART1_bit (1 << VIC_UART1)
#define VIC_I2C_bit (1 << VIC_I2C)
#define VIC_EINT0_bit (1 << VIC_EINT0)
#define VIC_EINT1_bit (1 << VIC_EINT1)
#define VIC_EINT2_bit (1 << VIC_EINT2)
#define VIC_SPI_bit (1 << VIC_SPI0)


void VIC_EnableInt(unsigned int IntType);
void VIC_DisableInt(unsigned int IntType);
void Vic_Init(void);

/**** INIT INTERRUPTS ****/
void InitTIMER0Interrupt(void);
void InitTIMER1Interrupt(void);
void InitUART0Interrupt(void);
void InitUART1Interrupt(void);
void InitI2CInterrupt(void);
void InitEINT0Interrupt(void);
void InitEINT1Interrupt(void);
void InitEINT2Interrupt(void);
void InitSPIInterrupt(void);

static void TIMER0Interrupt(void) __attribute__ ((interrupt ("IRQ")));
static void TIMER1Interrupt(void) __attribute__ ((interrupt ("IRQ")));
static void UART0Interrupt(void) __attribute__ ((interrupt ("IRQ")));
static void UART1Interrupt(void) __attribute__ ((interrupt ("IRQ")));
static void I2CInterrupt(void) __attribute__ ((interrupt ("IRQ")));
static void EINT0Interrupt(void) __attribute__ ((interrupt ("IRQ")));
static void EINT1Interrupt(void) __attribute__ ((interrupt ("IRQ")));
static void EINT2Interrupt(void) __attribute__ ((interrupt ("IRQ")));
static void SPIInterrupt(void) __attribute__ ((interrupt ("IRQ")));


static void InterruptDef(void) __attribute__ ((interrupt ("IRQ")));

//******************************************************************************
void InterruptDef(void)
{
void (*interrupt_function)();
unsigned int vector;

vector = VICVectAddr; // Get interrupt vector.
interrupt_function = (void(*)())vector;
(*interrupt_function)(); // Call vectored interrupt function.

VICVectAddr = 0; // Clear interrupt in VIC.
}

//******************************************************************************
void VIC_EnableInt(unsigned int IntType)
{
VICIntEnable |= IntType; //Enable inerrupt
}
//******************************************************************************
void VIC_DisableInt(unsigned int IntType)
{
VICIntEnClr |= IntType; //Disable interrupt
}
//******************************************************************************
void Vic_Init(void)
{
VICProtection = 0; // Setup interrupt controller.
VICIntEnClr = 0xffffffff; // Disable all interrupts
VICDefVectAddr=(unsigned int)InterruptDef;
}


//******************************************************************************
void InitSPIInterrupt(void)
{

VICIntSelect &= ~VIC_SPI_bit; // IRQ on RTC line.
VICVectAddr8 = (unsigned int)SPIInterrupt;
VICVectCntl8 = 0x20 | VIC_SPI; // Enable vector interrupt for RTC.
VICIntEnable |= VIC_SPI_bit; // Enable RTC interrupt.

}


void InitSPI0 (void)
{
unsigned char temp;
S0SPCCR = 0x0a; //

PINSEL0 |= 0x00005500; // configure SPI0 pins
S0SPCR = 0x90;

}

//******************************************************************************
unsigned char SlaveRcv = 0xAA;
unsigned char SlaveSnd;
//******************************************************************************
static void SPIInterrupt(void)
{
if (S0SPSR) ; // (dummy) read status register

SlaveRcv = S0SPDR; // read data received
S0SPDR = SlaveSnd; // next data to transmit
S0SPINT = 0x01; // reset interrupt flag

VICVectAddr = 0; // reset VIC
}
Сергей Борщ
Цитата(Slider_spb @ Apr 3 2008, 10:27) *
Используйте теги [ code ] и [ /code ] (без пробелов) для вставки исходников. В форме ввода есть для них специальная кнопочка с символом #.

У вас случайно не открыто в отладчике окно с регистрами SPI0 или VIC? Чтение регистров отладчиком может сбрасывать флаги.

Вы два раза пишете в VICVectAddr - в InterruptDef() и SPIInterrupt().
Какой компилятор вы используете? Многие версии GCC неправильно генерят эпилог прерывания IRQ.
Alex03
Цитата(Slider_spb @ Apr 3 2008, 13:27) *
VICIntEnable |= IntType; //Enable inerrupt
...
VICIntEnClr |= IntType; //Disable interrupt
...
VICIntEnable |= VIC_SPI_bit; // Enable RTC interrupt.

Зачем "ИЛИ"?
VICIntEnClr на чтение вообще недоступен.
Может выключая другое прерывание Вы выключаете этим прерывание от SPI?
Slider_spb
Цитата(Alex03 @ Apr 3 2008, 13:52) *
Зачем "ИЛИ"?
VICIntEnClr на чтение вообще недоступен.
Может выключая другое прерывание Вы выключаете этим прерывание от SPI?


Остальные то прерывания работают нормально.

Прерывания не запрещаю.

Регистры были открыты в отладчике, закрыл но результат тот же.

Несколько раз прерывание вызывалось.
Но это первый раз: включаем питание, программируем в режиме отладчика, запускаем, однократно прерывание генериться, затем тишина..
Alex03
Цитата(Slider_spb @ Apr 3 2008, 18:49) *
Но это первый раз: включаем питание, программируем в режиме отладчика, запускаем, однократно прерывание генериться, затем тишина..

А чтение SPSR в обработчике прерывания?
Цитата
SPIF
SPI transfer complete flag. When 1, this bit indicates when a SPI data transfer is
complete. When a master, this bit is set at the end of the last cycle of the transfer.
When a slave, this bit is set on the last data sampling edge of the SCK. This bit is
cleared by first reading this register, then accessing the SPI data register.


Цитата
SPI Interrupt
SPI interrupt flag. Set by the SPI interface to generate an interrupt. Cleared by writing
a 1 to this bit.
Note: this bit will be set once when SPIE=1 and at least one of SPIF and WCOL bits
is 1. However, only when SPI Interrupt bit is set and SPI Interrupt is enabled in the
VIC, SPI based interrupt can be processed by interrupt handling software.


Также Errata почитайте по поводу очистки флага прерывания и работы SPI в slave режиме.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.