attiny2313 und "pin change interrupt"

OP #4362731
Hi,

Ich versuch schon seit Stunden einen Interrupt auf eine steigende Flanke 
(PWM von RC) an PB0 bei einem attiny2313 zu bekommen. Der code hat bei 
einem attiny45 funktioniert und ich hab keine Ahnung weshalb er jetzt 
nicht mehr tut. Bin schon alle register im DB durchgegangen ... 
vielleicht kann hier mal jemand drüber schauen:
1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3
#include <util/delay.h>
4

5
#define    SERVO_DDR    DDRB
6
#define    SERVO_PORT    PORTB
7
#define    SERVO_PIN    PINB
8
#define    SERVO      PB0
9

10
#define    LED_DDR      DDRB
11
#define    LED_PORT    PORTB
12
#define    LED            PB1
13

14
ISR(INT0_vect)
15
{
16
  LED_PORT ^= (1<<LED);
17
}
18

19
int main(void)
20
{
21
  LED_DDR |= (1<<LED);   // Set as output
22
  LED_PORT |= (1<<LED);  // Set high
23

24
  SERVO_PORT |= (1<<SERVO);        // Servo Signal Input Pull-Up
25

26
  PCMSK |= (1<<PCINT0);         // PB0 pin will serve as an external interrupt source.
27
  MCUCR |= (1<<ISC01) | (1<<ISC00);      // The rising edge of INT0 generates an interrupt request.
28
  GIMSK |= (1<<INT0) | (1<<PCIE);      // (INT0) External Interrupt Request 0 Enable
29
                                            // (PCIE) Pin Change Interrupt Enable
30
  sei();
31

32
  while(1) {}
33
}

So einfach aber doch sooo schwierig grrrr
Gast #4362770
Ja,  der Kollege hatte keine Ahnung ;). Du verwendest keinen PCI sondern 
einen normalen Interrupt. Einen PCI kann man auch nicht auf eine 
gewünschte Flanke triggern und man bekommt nur einen Gruppen Interrupt.

Gruß Matthias
OP #4362774
Ja danke, schon gefunden ... da hab ich leider die falsche ISR erwischt. 
Tut leider immer noch nicht.
1
 PCMSK |= (1<<PCINT0);
2
  MCUCR |= (1<<ISC01) | (1<<ISC00);
3
  GIMSK |= (1<<PCIE);

sollte genügen zum initialisieren, oder?
#4362775
INT0 und INT1 sind was anderes als PinChangeInterrupt. Während man bei 
INT0 und INT1 einstellen kann, dass z. B. nur bei einer steigenden 
Flanke der Interrupt ausgelöst werden soll, geht das beim 
PinChangeInterrupt (wie der Name ja schon sagt) nicht.

Wenn die Flankenerkennung nötig ist, musst du das Signal an PD2 (INT0) 
oder PD3 (INT1) anlegen und INT0_vect oder INT1_vect als Interruptvektor 
benutzen.

Beim PinChangeInterrupt musst du im Interrupt den Pegel des Pins 
einlesen und selber ermitteln, was für ein Ereignis das jetzt war.

Für bspw. INT0:
1) im MCUCR die Bits ISC00/ISC01 entsprechend setzen
2) im GIMSK INT0 setzen
3) INT0_vect als Interruptvektor nutzen

Für PinChangeInterrupt:
1) im PCMSK das Bit auf 1 setzen, was dem Portpin (Port B) entspricht
2) im GIMSK PCIE setzen
3) PCINT_vect als Interruptvektor nutzen

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 10 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.