Forum: Mikrocontroller und Digitale Elektronik ATtiny2313 & Pin Change Interrupt


von Mathias (Gast)


Lesenswert?

Ich will einen einfachen Versuch mit "Pin Change Interrupt" machen.

Als Beispiel sollte der PCINT0 bis PCINT5 dienen.

Nur scheitert es schon an folgenden Zeilen:
1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3
#include <util/delay.h>
4
5
...
6
7
  PCICR |= (1 << PCIE0);
8
9
  PCMSK0 |= (1 << PCINT0) | (1 << PCINT1) | (1 << PCINT2) | (1 << PCINT3)  | (1 << PCINT4);
1
../Stepper.ino:37:2: error: 'PCICR' was not declared in this scope
2
  PCICR |= (1 << PCIE0);
3
  ^
4
../Stepper.ino:37:17: error: 'PCIE0' was not declared in this scope
5
  PCICR |= (1 << PCIE0);

Ich verwende die Arduino-Software mit Sloeber.
Hat jemand eine Idee ?
Oder gar ein einfaches Beispiel ?

von HildeK (Gast)


Lesenswert?

Ich kenne zwar deine Softwareumgebung nicht, aber z.B. steht laut 
Datenblatt PCIE0 im Register GIMSK.
Ersetze mal PCICR durch GIMSK.

von Thomas E. (thomase)


Lesenswert?

...und erzähl uns, ob du den alten 2313 oder den aktuellen 2313a hast. 
Das macht in diesem Fall nämlich ausnahmsweise einen Unterschied.

von Mathias (Gast)


Lesenswert?

Thomas E. schrieb:
> ...und erzähl uns, ob du den alten 2313 oder den aktuellen 2313a
> hast.
> Das macht in diesem Fall nämlich ausnahmsweise einen Unterschied.

Auf dem Gehäuse steht: ATtiny2313A-PU

von Thomas E. (thomase)


Lesenswert?

Mathias schrieb:
> Auf dem Gehäuse steht: ATtiny2313A-PU

Und 2313a hast du auch eingestellt?

Der 2313 hat den Pinchange nur auf Port B. Der 2313a auf allen Pins. 
Entsprechend hat der 2313a auch mehr Interrupt-Vektoren und andere 
Bezeichnungen für diese sowie auch für die Bezeichner der 
Freigabe-Flags. Klär das mal ab, damit du weißt, ob der gemeinsame 
Nenner vorhanden ist. Denn du schriebst 2313, hast aber den 2313a. 
Manchmal ist diese Pedanterie vonnöten. In diesem Fall sogar besonders.

Und du guckst natürlich auch ins Datenblatt vom 2313a/4313?

Schreibt man 2313-Code für den 2313a ab, ich meine natürlich, daß man 
bewährten Code verwendet, schiesst man sich an dieser Stelle ins Knie.

: Bearbeitet durch User
Beitrag #5125606 wurde vom Autor gelöscht.
von Mathias (Gast)


Angehängte Dateien:

Lesenswert?

Eine A-Version kann ich leider nicht anwählen, oder kann man die mit 
einer anderen Option einstellen ?
Siehe Anhang.

von Thomas E. (thomase)


Lesenswert?

Dann probier mal den 2313a als 2313 zu programmieren. Das könnte 
klappen. Den Knieschuss holt man sich eher andersrum.

Also die relevanten Bezeichner, PCINT0 nach PCINT, PCIE0 nach PCIE usw. 
ändern. Dann schluckt das wenigstens der Compiler.

Aber mit was für einem Sch...-Programm werkelst du da? Allein die 
Auswahl 2313/4313 ist so was von für'n A....

2313A und 4313 sind Brüder, der 2313 ist der greise Onkel der beiden.
Was für ein Hirni hat das verzapft?

von Mathias (Gast)


Lesenswert?

>Aber mit was für einem Sch...-Programm werkelst du da? Allein die
>Auswahl 2313/4313 ist so was von für'n A....

Es ist das beste, was ich für den Arduino kenne, die Orignal-IDE des 
Arduinos bietet Null Komfort.
Die Board-Auswahl ist nur die Familie. Weiter unten bei Chip kann man 
ATtiny2313 oder 4313 wählen. Aber leider kein A-Typ.
Das fehlen des A ist der json-Datei zurück zu führen.
https://github.com/arduino/Arduino/wiki/Unofficial-list-of-3rd-party-boards-support-urls


>Also die relevanten Bezeichner, PCINT0 nach PCINT, PCIE0 nach PCIE usw.
>ändern. Dann schluckt das wenigstens der Compiler.
Dies werde ich bei Gelegenheit probieren.

von M. K. (sylaina)


Lesenswert?

Mathias schrieb:
> Oder gar ein einfaches Beispiel ?

Öhm, du willst doch den Versuch selbst machen, oder?

von Peter D. (peda)


Lesenswert?

Thomas E. schrieb:
> Schreibt man 2313-Code für den 2313a ab, ich meine natürlich, daß man
> bewährten Code verwendet, schiesst man sich an dieser Stelle ins Knie.

Nö.
Der 2313A ist abwärtskompatibel. Schreibt man nichts in die zusätzlichen 
Register, passiert auch nichts.

Was natürlich bescheuert ist, daß beide die gleiche Signatur haben. Wenn 
also die 2313A Erweiterungen benötigt werden, kann man eine 
Fehlbestückung beim Programmieren nicht erkennen.

von Mathias (Gast)


Lesenswert?

Ich habe es nun hingekriegt:
1
ISR(PCINT_vect) {
2
  if (!(PINB & (1 << PB0))) { // Pin auswerten
3
    PORTD = 0b00000000;
4
  }
5
6
  if (!(PINB & (1 << PB1))) {
7
    PORTD = 0b00000100;
8
  }
9
10
  if (!(PINB & (1 << PB2))) {
11
    PORTD = 0b00001000;
12
  }
13
14
  if (!(PINB & (1 << PB3))) {
15
    PORTD = 0b00010000;
16
  }
17
18
  if (!(PINB & (1 << PB4))) {
19
    PORTD = 0b00100000;
20
  }
21
}
22
23
void setup() {
24
25
  PCMSK |= (1 << PCINT0) | (1 << PCINT1) | (1 << PCINT2) | (1 << PCINT3)| (1 << PCINT4);
26
  GIMSK |= (1 << PCIE);
27
28
  DDRD = 0b00111100;
29
  DDRB = 0b00000000;
30
  PORTB = 0b00011111; // PullUp
31
//  Step(1);
32
}

von M. K. (sylaina)


Lesenswert?

Mathias schrieb:
> Ich habe es nun hingekriegt:

War nicht schwer, oder? ;)

Tipp noch von mir:

Schreibe statt
1
...
2
PORTB = 0b00011111;
3
...

doch besser
1
...
2
PORTB = (1 << PB4)|(1 << PB3)|(1 << PB2)|(1 << PB1)|(1 << PB0);
3
...

Das ist zwar mehr Schreibarbeit als den Binärcode direkt hinzuschreiben, 
kann aber später von Vorteil sein. Schaut man nämlich in 1-2 Jahren 
wieder ins Projekt rein muss man bei PORTC |= 0b00001000 erstmal die 
Nullen abzählen und fragt sich vielleicht auch, was man damit bezwecken 
wollte wobei aus einem PORTC |= (1 << PC3) sofort ersichtlich ist, dass 
man hier den Pin PC3 setzen wollte.
Auch bei der Fehlersuche kann das Hilfreich sein, während man sich beim 
Binärcode durchaus dumm und dusselig suchen kann, warum denn nun die LED 
nicht an geht, die an PA5 angeschlossen ist, sieht man bei der 
Shift-Schreibweise sofort, dass man aus versehen PA4 geschrieben hat.

von Mathias (Gast)


Lesenswert?

Danke für den Tip, ich habe aus dem = noch ein |= gemacht.

Da habe ich doch noch eine Frage, ist dies richtig, das man mit PCIE die 
Interrupt aktiviert und mit PCMSK sagt man welche Ports(Pin) auf den 
Interrupt reagieren sollen ?

von M. K. (sylaina)


Lesenswert?

Ein |= macht man, wenn man die anderen Bits des Registers nicht löschen 
will.

Und ja, das ist richtig, mit PCIE aktiviert man den Pin Change Interrupt 
und mit PCMSK wird angegeben, auf welche Pins der PCIE sensitiv ist.

von Ransepans (Gast)


Lesenswert?

Hallo Zusammen,

ich versuche gerade auf nem Tiny4313 eine Pinchange Funktion zu 
implementieren. Aber die Registernamen aus dem Datenblatt und die von 
Winavr (aus iotn4313.h) passen nicht zusammen. Es gibt kein PCMSK0..2 
sondern nur PCMSK. Es gibt kein GIFR sondern nur EIFR. Soll ich die 
defines händisch in den Header eintragen, oder was stimmt hier nicht?
Ich kann in der AVR libc Hilfe auch die entsprechenden 
Interrupt-Vektoren finden.

Was ist hier los?

Vielen Dank und viele Grüße

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.