Witam!
Mam taki dość nietypowy problem. Kontroler ma reagować na jedno z trzech przerwań: TIMERa 0 i dwóch zewnętrznych (czujki ruchu). Te przerwania zewnętrzne zliczają liczbę reakcji czujek, natomiast TIMER 0 ma odmierzać czas i dzięki niemu co kilka sekund mają być wyświetlane statystyki. Bez TIMERa 0 wszystko działa ok, ale statystyki lecą cały czas, natomiast po dodaniu TIMERa 0 liczby zliczeń z czujek zaczynają szaleć i pojawiają się jakieś abstrakcyjne rzeczy (bez przerwania licznik się zwiększa o kilkadziesiąt, kilkaset itd.). Kod prezentuje się następująco (oczywiście tak wybiórczo):
Jeszcze dodam, że kod obsługi jest skopiowany z urządzenia gdzie chodził na kwarcu 37MHz, a tu mam 25MHz, ale wydaje mi się że jest ok. Choć mogę się mylić.
Może ktoś ma jakiś pomysł jak temu zaradzić?
z góry dzięki
pozdrawiam
herszt
Mam taki dość nietypowy problem. Kontroler ma reagować na jedno z trzech przerwań: TIMERa 0 i dwóch zewnętrznych (czujki ruchu). Te przerwania zewnętrzne zliczają liczbę reakcji czujek, natomiast TIMER 0 ma odmierzać czas i dzięki niemu co kilka sekund mają być wyświetlane statystyki. Bez TIMERa 0 wszystko działa ok, ale statystyki lecą cały czas, natomiast po dodaniu TIMERa 0 liczby zliczeń z czujek zaczynają szaleć i pojawiają się jakieś abstrakcyjne rzeczy (bez przerwania licznik się zwiększa o kilkadziesiąt, kilkaset itd.). Kod prezentuje się następująco (oczywiście tak wybiórczo):
volatile int i;
volatile int j;
volatile int timer_overflow_counter, timer_counter ;
volatile int wyswietl_statystyki ;
static void IrqHandler0(void *arg)
{
++i ;
}
static void IrqHandler1(void *arg)
{
++j ;
}
void T0_init(void) // Inicjalizacja TIMERa
{
timer_overflow_counter = 0 ;
timer_counter = 0 ;
TIMSK &=~((1<<TOIE0)|(1<<OCIE0)); // Disable TC0 interrupt
ASSR |= (1<<AS0); // set Timer/Counter0 to be asynchronous from the CPU clock with a second
// external clock(32,768kHz) driving it.
TCNT0 = 0x00;
TCCR0 = 0x05; // prescale the timer to be clock source 128 to make it exactly 1 second for every overflow to occur
while(ASSR&0x07); // Wait until TC0 is updated
TIMSK |= (1<<TOIE0); // set 8-bit Timer/Counter0 Overflow Interrupt Enable
}
static void IrqTimer0(void *arg) // Przerwanie TIMERa
{
++timer_overflow_counter ;
// !!!!
if (timer_overflow_counter==5) // !!!! ILE SEKUND POMIEDZY WYSWIETLENIEM STATYSTYK
{ // !!!!
timer_counter = 1 ;
wyswietl_statystyki = 1 ;
}
}
[...]
int main()
{
confcom.baud = 115200; // UART speed
DDRD = 0x00 ; // PORTD jako wejscie
PORTD = 0xFF ; // podciagniecie wejsc do 1
EICRA = 0xAA ; // wejscie reaguje na opadajace zbocze
EIMSK = 0x0F ; // odblokowuje przerwania na wejsciach INT0...INT3
NutRegisterIrqHandler(&sig_INTERRUPT0, IrqHandler0, NULL); // obsluga przerwania czujki 1
NutRegisterIrqHandler(&sig_INTERRUPT1, IrqHandler1, NULL); // obsluga przerwania czujki 2
NutRegisterIrqHandler(&sig_OVERFLOW0, IrqTimer0, NULL); // obsluga przerwania TIMERa 0
[...]
T0_init() ; // Inicjalizacja TIMERa 0
int wykonaj = 1;
wyswietl_statystyki = 1 ;
timer_counter = 0 ;
for(;;)
{
if(timer_counter && wyswietl_statystyki) // status licznikow co 5 sekund if(timer_counter && wyswietl_statystyki)
{
timer_counter = 0 ;
timer_overflow_counter = 0 ;
wyswietl_statystyki = 0 ;
//printf_P(PSTR("\r\nWatek glowny\r\n")) ;
printf_P(PSTR("\n\rCzas wyswietlenia danych:\t%s\n\r"), timeToAscii(getTime()));
printf_P(PSTR("Licznik 0: %i\n\r"), i) ;
printf_P(PSTR("Licznik 1: %i"), j) ;
}
//NutDelay(1000) ;
if (wykonaj)
{
wykonaj = 0;
read_f() ;
}
}
Jeszcze dodam, że kod obsługi jest skopiowany z urządzenia gdzie chodził na kwarcu 37MHz, a tu mam 25MHz, ale wydaje mi się że jest ok. Choć mogę się mylić.
Może ktoś ma jakiś pomysł jak temu zaradzić?
z góry dzięki
pozdrawiam
herszt
