Forum: Mikrocontroller und Digitale Elektronik PCINT benutzen Atmega


von André R. (andr_r23)


Lesenswert?

Ich habe ein kleines Problem ... Meine fertig geroutete Platine weißt 
einen Fehler auf. Ich brauche einen Interrupt für mein Ethernet. Habe 
das Webserver Projekt vom Radig der den INT2 benutzt. Nun habe ich die 
Interruptleitung vom ENC28J60 auf PB1 gelegt. PB1(T1/CLKO/PCINT9) ist 
aber nicht INT2...

Kann ich PCINT9 auch als Interrupt benutzen? Ich weiß noch nichteinmal 
was PCINT überhaupt ist... Da ich vermeiden möchte mit Drähten 
rumzuspielen wollte ich vorher nochmal hier nachfragen!

Danke

von André R. (andr_r23)


Lesenswert?

Gut ich weiß nun das es damit wohl geht. Pin-Change Interrupt. Aber wie 
genau kann ich den den benutzen das er genauso funktioniert wie der 
INT2??

von spess53 (Gast)


Lesenswert?

Hi

PC erzeugt bei jeder Änderung einen Interrupt. In der ISR musst du halt 
feststellen welche Flanke und bei mehreren Pins einer Gruppe, welcher es 
war.

MfG Spess

von André R. (andr_r23)


Lesenswert?

Hmm und wie mache ich das ?

ETH_INT_ACTIVE soll auf 1 gesetzt werden wenn der Interrupt kommt.

So steht es vom Radig im Code:

 #define ETH_INTERRUPT           INT2_vect
 #define ETH_INT_ACTIVE          (!(ENC_PIN & (1<<ENC_INT)))
 #define ETH_INT_ENABLE  EIMSK |= (1<<INT2)
 #define ETH_INT_DISABLE EIMSK &= ~(1<<INT2)

Wie kann ich da nun den PCINT9 integrieren. BIn da gerade echt ratlos ^^

von spess53 (Gast)


Lesenswert?

Hi

>Wie kann ich da nun den PCINT9 integrieren. BIn da gerade echt ratlos ^^

Und ich kein C-Programmierer.

PCINT9 gehört zum Interrupt PCINT1. Um den freizugeben muss PCIE1 in 
PCICR gesetzt werden. Damit PCINT9 den Interrupt auslöst muss außerdem 
PCINT9 in  PCMSK1 gesetzt werden.

Ohne Gewähr:

 #define ETH_INTERRUPT           PCINT1_vect
 #define ETH_INT_ACTIVE          (!(ENC_PIN & (1<<ENC_INT)))  ??????
 #define ETH_INT_ENABLE  PCMSK1 |= (1<<PCINT9)
 #define ETH_INT_DISABLE EIMSK &= ~(1<<PCINT9)

Beim zweiten define weiß ich nicht in welchem Zusammehang das verwendet 
wird.
Das PCIE1 in PCICR musst du noch irgendwo in der Initialisierung setzen.

MfG Spess

von spess53 (Gast)


Lesenswert?

Hi

Habs gefunden

 #define ENC_PIN                 PINB

 #define ENC_INT                 2

Setze dort deinen Port und dein Pin ein.

MfG Spess

von André R. (andr_r23)


Lesenswert?

Hab ich gemacht wie du es beschrieben hast aber irgendwie funktioniert 
das nicht. Mein uC startet auch irgendwie alle 10 sekunden neu ... 
zumindest im UART zeigt er mir das er sich dauern wieder selbst 
initialisiert.

Scheinbar nen Timeout oder sowas.... hmmmm

in der main() habe ich direkt am Anfang:

PCICR |= (1<<PCIE1);
PCMSK1 |= (1<<PCINT9);

Komisch...

Danke aufjedenfall schonmal bis hierhin!

von Peter D. (peda)


Lesenswert?

André R. schrieb:
> Mein uC startet auch irgendwie alle 10 sekunden neu ...

Ja, wenn Du einen Interrupt freigibst, mußt Du für diesen auch einen 
Handler schreiben.
Ansonsten springt der AVR-GCC einfach zum Resethandler.


Peter

von spess53 (Gast)


Lesenswert?

Hi

>Mein uC startet auch irgendwie alle 10 sekunden neu ...
>zumindest im UART zeigt er mir das er sich dauern wieder selbst
>initialisiert.

Hast du auch eine Interruptroutine für PCINT1 ?

MfG Spess

von André R. (andr_r23)


Lesenswert?

ne habe ich nicht. Habe nur den Code vom Radig halt. Muss ich noch ne 
ISR einbinden? Was mache ich den in der ISR ???!?

von André R. (andr_r23)


Lesenswert?

Alles funktioniert!

Der Fehler war das ich das PCMSK Register direkt am anfang beschrieben 
habe. Habe das ganze nach ETH_INT_ENABLE gemacht und nun funktioniert 
alles.

Ich danke dir für deine tolle Hilfe!!!

von holger (Gast)


Lesenswert?

Hallo Andre,
das mit dem PCINT habe ich auch vor einigen Tagen gemacht.
Funktioniert eine ganze Zeit lang recht gut. Irgendwann
hängt sich der Webserver aber auf bzw. reagiert nicht
mehr auf den PCINT. Ansonsten lief der AVR noch. Falls das
bei dir auch so ist kannst du den PCINT auch komplett
weglassen und den ENC28J60 einfach pollen. Das frisst ein
wenig Rechenzeit, ist aber nicht so viel.

Du musst dann nur in stack.c zwei Zeilen wegkommentieren:
1
//----------------------------------------------------------------------------
2
//ETH get data
3
void eth_get_data (void)
4
{
5
  if(eth.timer)
6
  {
7
    tcp_timer_call();
8
    arp_timer_call();
9
    eth.timer = 0;
10
  }
11
12
// Polling geht irgendwie besser als mit PCINT zu arbeiten;)
13
// Aus irgendeinem Grund bleibt der Webserver irgendwann hängen.
14
// Der AVR selbst läuft noch, der Webserver reagiert nicht mehr.
15
16
17
//  if(eth.data_present)
18
  {
19
  #if USE_ENC28J60
20
//    while(ETH_INT_ACTIVE)
21
    {
22
  #endif

von Peter D. (peda)


Lesenswert?

holger schrieb:
> Irgendwann
> hängt sich der Webserver aber auf bzw. reagiert nicht
> mehr auf den PCINT.

Das liegt einfach daran, daß es mehrere Interruptquellen gibt.
Dann bleibt der Pin auf aktiv und es gibt keine Flanke. Daher ist ein 
Pegelinterrupt besser.

Aber es geht auch mit Flankeninterrupt. Man schreibt den Handler als 
Schleife und testet zum Schluß den Pin, Ist er immer noch aktiv, wird 
die Schleife nochmal durchlaufen.


Peter

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.