attiny2313 und "pin change interrupt"

OP #4362731
Lesenswert?
• ▲
▼
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
Lesenswert?
• ▲
▼
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
#4362775
Lesenswert?
• ▲
▼
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

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren