• Email
  • Forum

Przerwania wywołane zmianą stanu na pinie

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ć.

[Rozmiar: 28350 bajtów]

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.

[Rozmiar: 26438 bajtów]

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.

Email

Jeśli mogę w czymś pomóc, napisz.