Pokażę fragmenty dotyczące autofire, bo cały projekt (S)NESctrl nie jest opensource.
Fragmenty kodu w języku C.
W (S)NESctrl używam Attiny2313 i taktuję go wewnętrznym oscylatorem 8MHz z dzielnikiem przez 8, czyli mam częstotliwość 1MHz
Timer1 dla autofire ustawiam tak:
TCCR1B |= (1 << WGM12); //ustaw timer w tryb CTC
OCR1A = 1040; //ustaw do ilu liczy timer: 1MHz/64=15625(to by dało 1Hz, więc 1040 daje około 15Hz)
TCCR1B |= ((1 << CS10) | (1 << CS11)); //CS10 włącza timer, CS11 ustawia preskaler na Fcpu/64
TIMSK |= (1 << OCIE1A); //zezwolenie na przerwania dla CTC timer1
sei(); //zezwolenie globalne na przerwania
Następnie robię sobie zmienną, w której mam zapisany jeden bit i zmieniam go na przeciwny w procedurze obsługi przerwania pochodzącego od timera1.
Czyli na początku programu deklaracja zmiennej:
unsigned char Autofire = 0;
I procedura obsługi przerwania:
ISR(TIMER1_COMPA_vect) //przerwanie compare timera1
{
Autofire ^= 1;
}
Po takich zabiegach masz w głównym programie zmienną Autofire, która przyjmuje przemiennie wartość 0 i 1 z odpowiednią częstotliwością.
Dalej tą zmienną już sobie wykorzystujesz jak chcesz, możesz ją przypisywać do jakiegoś portu, albo co tam chcesz. Ja u siebie w zależności od wybranych trybów pracy wykorzystuję tą zmienną do przeliczania różnych funkcji, składam całe bajty z kerunkami joyów, autofire itd i wynik wystawiam później na cały port od razu, ale (S)NESctrl, to trochę bardziej skomplikowane urządzenie, a autofire, to tylko jedna z małych dodatkowych opcji.
Powodzenia w eksperymentach