W większości nowych procesorów wprowadzono możliwość generowania przerwania jeśli stan wskazanego pinu się zmieni.
Na wstępie jednak zwracam uwagę, że nie ma ich w "babci" Atmega8. Jeśli jednak mamy "coś nowszego", lub wymienimy Atmega8 na Atmega328 bo mają taki sam rozkład nóżek to możemy z nich skorzystać.
Omówienia wymaga sposób ich użycia. Przerwania PCINTx powiązane są z portem do którego należą. Deklarując ich obsługę i włączenie zezwolenia na przerwanie mamy zakres od PCINT0 do PCINT2. O co tu chodzi? Już piszę.
Przerwanie wybiera się z portu zakładając na niego maskę PCMSK. W At328p mamy trzy porty z PCINT. Resztę objaśnią obrazek z opisem oraz przykład enkodera na takim przerwaniu.
Trzeba jednak zwrócić uwagę na małą różnicę. Te przerwania generowane są przy każdej zmianie na pinie. Czy to z 1 na 0, ale i w drugą stronę. W "normalnych" INT0 i INT1 deklarujemy że "wyzwalaczem" będzie np. opadające zbocze. Tutaj przerwanie generowane jest za każdym razem. Jeśli więc zależy nam na działaniu podobnym do np. INT0 to musimy dołożyć warunek, że IF nasz pin = 0.
$regfile = "m328pdef.dat" 'register file for ATmega328p $crystal = 8000000 '8MHz crystal Config Lcdpin = Pin , Db4 = Portb.2 , Db5 = Portb.3 , Db6 = Portb.4 , Db7 = Portb.5 , E = Portb.0 , Rs = Portc.0 Config Lcd = 20x4 Cursor Off Noblink 'nowy sposób zapisu Cls ' config for encoder Portd.2 = 1 Portd.3 = 1 Encoder_a Alias Pind.2 Encoder_b Alias Pind.3 'pin który generuje przerwanie Pcmsk2 = &B00001000 Enable Pcint2 : On Pcint2 Encoder_isr Dim Encoder_turn_left As Byte , Encoder_turn_right As Byte '------------------------------------------- Dim Zmienna As Word Enable Interrupts Lcd "Licznik:" Do 'encoder turns left If 0 < Encoder_turn_left Then Decr Encoder_turn_left 'tutaj Twój kod - Decr Zmienna Locate 1 , 10 : Lcd Zmienna ; " " End If If 0 < Encoder_turn_right Then Decr Encoder_turn_right 'tutaj Twój kod + Incr Zmienna Locate 1 , 10 : Lcd Zmienna ; " " End If Loop End 'tutaj obsługa przerwania zewnetrznego z enkodera Encoder_isr: If Encoder_b = 0 Then 'dodatkowy warunek If Encoder_a = 0 Then Incr Encoder_turn_right Else Incr Encoder_turn_left End If End If Return
Tym sposobem możemy sobie podłączyć enkoder gdzie nam się żywnie podoba.