tn
Guest
Fri Mar 14, 2008 11:42 am
Witam
Problem polega na tym, że w czasie trwania symulacji przerwania są
wywoływane tylko raz . Później mimo tego, że w oknie AIC jest przy nich
pending nic się nie dzieje. Zaznaczony jest też bit NIRQ. Gdy program
wchodzi do funkcji obsługi przerwania ustawiana jest flaga I w Current:CPSR
i nie jest czyszczona przy wyjściu z niego. Co zrobić, żeby kolejne
przerwania nie były blokowane? Może trzeba samemu wyczyścić flagę I, ale w
przykładach nic takiego nie widziałem.
kod:
void Przerwanie2(void)
{
unsigned int dummy;
....
dummy = AT91C_BASE_PIOA->PIO_ISR;
dummy = dummy;
AT91F_AIC_AcknowledgeIt(AT91C_BASE_AIC);//nie zauważyłem różnicy w
działaniu programu gdy to polecenie jest lub go nie ma.
}
int main(void)
{
....
AT91F_PMC_EnablePeriphClock ( AT91C_BASE_PMC, 1 << AT91C_ID_PIOA ) ;
AT91F_PIO_CfgInput(AT91C_BASE_PIOA, 0x100);
AT91F_AIC_ConfigureIt ( AT91C_BASE_AIC, AT91C_ID_PIOA,
2,AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL, Przerwanie2);
AT91F_PIO_InterruptEnable(AT91C_BASE_PIOA,0x100);
AT91F_AIC_EnableIt (AT91C_BASE_AIC, AT91C_ID_PIOA);
....
i = 0; for(;

{ i++;}
}
pozdrawiam
tn
tn
Guest
Fri Mar 14, 2008 2:21 pm
Quote:
Problem polega na tym, że w czasie trwania symulacji przerwania są
wywoływane tylko raz . Później mimo tego, że w oknie AIC jest przy nich
pending nic się nie dzieje. Zaznaczony jest też bit NIRQ. Gdy program
wchodzi do funkcji obsługi przerwania ustawiana jest flaga I w
Current:CPSR i nie jest czyszczona przy wyjściu z niego. Co zrobić, żeby
kolejne przerwania nie były blokowane? Może trzeba samemu wyczyścić flagę
I, ale w przykładach nic takiego nie widziałem.
dodatkowa informacja:
W oknie Regs jest pogrubioną czcionką pisana grupa rejestrów "aktualnego"
trybu. Przed wejściem do funkcji obsługi przerwania jest to grupa
User/System, po wejściu do przerwania i po jego obsłudze program pozostaje w
grupie Interrupt.
tn
Guest
Sat Mar 15, 2008 6:41 pm
Quote:
Problem polega na tym, że w czasie trwania symulacji przerwania są
wywoływane tylko raz . Później mimo tego, że w oknie AIC jest przy nich
pending nic się nie dzieje. Zaznaczony jest też bit NIRQ. Gdy program
wchodzi do funkcji obsługi przerwania ustawiana jest flaga I w
Current:CPSR i nie jest czyszczona przy wyjściu z niego. Co zrobić, żeby
kolejne przerwania nie były blokowane? Może trzeba samemu wyczyścić flagę
I, ale w przykładach nic takiego nie widziałem.
dodatkowa informacja:
W oknie Regs jest pogrubioną czcionką pisana grupa rejestrów "aktualnego"
trybu. Przed wejściem do funkcji obsługi przerwania jest to grupa
User/System, po wejściu do przerwania i po jego obsłudze program pozostaje
w grupie Interrupt.
Udało mi się rozwiazać problem po intensywnym googlaniu.
Funkcja przerwania powinna wyglądać następująco:
__irq void Przerwanie (void)
{
volatile unsigned int dummy;
....{kod właściwy}...
dummy = AT91C_BASE_TC0->TC_SR;
dummy = dummy;
AT91F_AIC_AcknowledgeIt(AT91C_BASE_AIC);
}
A przerwanie powinno być włączone następująco:
AT91F_AIC_ConfigureIt(AT91C_BASE_AIC, AT91C_ID_TC0,
AT91C_AIC_SRCTYPE_HIGH_LEVEL, AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL, (void (*)())
Przerwanie);
AT91F_AIC_EnableIt (AT91C_BASE_AIC, AT91C_ID_TC0);
kluczem do sukcesu okazały się __irq i (void (*)()).
Nie wiem tylko dlaczego w przykładach jakie napotkałem w sieci przerwania
działały bez tego, a u mnie trzeba jakieś dodatkowe zabiegi robić... life.
pozdrawiam
tn