Forum: Mikrocontroller und Digitale Elektronik Interrupt am attiny85


von Gerd H. (gerd_h28)


Lesenswert?

Hallo,

ich habe vor dem Post wirklich erst gesucht... sorry, bin noch 
C-Anfänger.
Also - der attiny85 hat an PIN0,1,2,3 je eine LED, an PIN4 einen Taster 
auf Masse.

Hier mein Code:
1
#define F_CPU 1000000L
2
#include <stdint.h>
3
#include <stdio.h>
4
#include <bitio.h>
5
6
#include <avr/io.h>
7
#include <avr/interrupt.h>
8
9
#include <util/delay.h>
10
11
12
void lauf_links ( uint8_t , uint8_t ) ;          // Deklaration
13
void lauf_rechts ( uint8_t , uint8_t ) ;         // Deklaration
14
void blink_alle ( uint8_t , uint8_t , uint8_t ) ;    // Deklaration
15
uint8_t schalter=2;
16
17
ISR (PCINT0_vect) {                            // Interrupt on PCINT vector
18
      if ( PINB & (1<<PINB4) )           // Eingang PIN4 abfragen - nicht gedrückt
19
        schalter = 0;
20
      else                               // gedrückt
21
        schalter = 1;
22
}
23
24
int main(void) {
25
  DDRB |= (1 << DDB0) | (1 << DDB1) | (1 << DDB2) | (1 << DDB3)| (1 << DDB4) | (1 << DDB5 );   // PORTB is output, all pins
26
  PORTB &= ((0 << PINB0) | (0 << PINB1) | (0 << PINB2) | (0 << PINB3));             // Make pins low to start
27
28
    BIT_CLEAR ( &DDRB , PINB4 );        // PIN PB4 auf Eingang Taster)  
29
    BIT_SET ( &PORTB , PINB4 );         // Pullup-Widerstand aktivieren 
30
  sei();                              // Interrupts zulassen
31
  uint8_t i;
32
33
//                                                      INIT fertig
34
35
  for (;;) {                                       // Endlosschleife
36
    for ( i = 0 ; i <= 1; i++ ) {
37
      lauf_links (0,0);            // LED an PB0 blinken lassen
38
    }
39
40
41
    for ( i = 0 ; i<=3 ; i++ ) 
42
//      if ( PINB & (1<<PINB4) )     // Eingang PIN4 abfragen - nicht gedrückt
43
      if ( schalter==2 )  {;}
44
      else if (schalter)   
45
        blink_alle (1,1,2) ;     // LED an PB1 blinken lassen
46
      else                         // gedrückt
47
        blink_alle( 2,3,2);      // LED an PB2 und PB3 blinken lassen
48
    
49
  }
50
  return 0;
51
}  // main Ende
52
53
// 
54
55
void lauf_links ( uint8_t von , uint8_t bis ) {
56
  uint8_t i;
57
  for ( i = von ; i <= bis ; ++i ){
58
    BIT_TOGGLE ( &PORTB , i); 
59
    _delay_ms (100);
60
    BIT_TOGGLE ( &PORTB , i ) ;
61
    _delay_ms (100);      
62
  }
63
}
64
65
void lauf_rechts ( uint8_t von , uint8_t bis ) {
66
  uint8_t i;
67
  for ( i = bis ; i <= von ; --i ){
68
    BIT_TOGGLE ( &PORTB , i); 
69
    _delay_ms (100);
70
    BIT_TOGGLE ( &PORTB , i ) ;
71
    _delay_ms (100);      
72
  }
73
}
74
void blink_alle ( uint8_t von , uint8_t bis , uint8_t anzahl) {
75
  uint8_t i,j;
76
  for (j=0 ; j<anzahl ; j++) {
77
    for ( i = von ; i <= bis ; ++i ){
78
      BIT_TOGGLE ( &PORTB , i); 
79
    }
80
    _delay_ms (100);
81
  }
82
}
Ergebnis: LED an PIN0 blinkt, egal ob ich den Taster drücke oder nicht.
aber: verwende ich innerhalb der Endlosschleife
1
if ( PINB & (1<<PINB4) )
 dann reagiert er auf meinen Taster.
ISR auf PCINT4_vect läuft im compiler auf Warning: ‘PCINT4_vect’ appears 
to be a misspelled signal handler [enabled by default]
Ich vermute irgendeinen dummen groben Denkfehler, finde ihn jedoch 
nicht.

mfg
Gerd

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

Gerd Heber schrieb:
> ISR auf PCINT4_vect läuft im compiler auf Warning: ‘PCINT4_vect’ appears

 Weil es nur einen PCINT ISR gibt. Mit PCMSK setzt man fest welche
 Pins einen Interrupt auslösen.
 Wenn der PCINT feuert, muss man sehen welcher Pin rückgesetzt ist.

von Walter (Gast)


Lesenswert?

Gerd Heber schrieb:
> uint8_t schalter=2;

volatile uint8_t schalter=2;

von Gerd H. (gerd_h28)


Lesenswert?

Hallo,

habe meinen Code nach beiden Antworten verändert:
1
volatile uint8_t schalter=2;
2
3
ISR (PCINT0_vect) {                            // Interrupt on PCINT vector
4
      if ( PINB & (1<<PINB4) )           // Eingang PIN4 abfragen - nicht gedrückt
5
        schalter = 0;
6
      else                               // gedrückt
7
        schalter = 1;
8
}
9
10
int main(void) {
11
  cli();
12
  DDRB |= (1 << DDB0) | (1 << DDB1) | (1 << DDB2) | (1 << DDB3)| (1 << DDB4) | (1 << DDB5 );   // PORTB is output, all pins
13
  PORTB &= ((0 << PINB0) | (0 << PINB1) | (0 << PINB2) | (0 << PINB3));             // Make pins low to start
14
15
    BIT_CLEAR ( &DDRB , PINB4 );        // PIN PB4 auf Eingang Taster)  
16
    BIT_SET   ( &PORTB , PINB4 );         // Pullup-Widerstand aktivieren 
17
    BIT_SET   ( &PCMSK , PINB4 );      // Interrupt-Maske setzen
18
  sei();                              // Interrupts zulassen
Leider passiert immer noch nichts. Bitte nochmal um Hilfe.

mfg
Gerd

von MWS (Gast)


Lesenswert?

Wie wär's damit den PCInt in GIMSK zu erlauben?

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

Gerd Heber schrieb:
> Leider passiert immer noch nichts. Bitte nochmal um Hilfe.

1
 GIMSK |= (1<<PCIE);

 PCINT feuert bei Wechsel, also sowohl bei der aufsteigender als
 auch bei der abfallenden Flanke.

 Abfrage entsprechend ändern, prellen berücksichtigen.

von Gerd H. (gerd_h28)


Lesenswert?

Hallo,

jetzt läuft es:
1
BIT_SET   ( &GIMSK , 5 ) ;             // GIMSK Bit 5 ( PCIE) freigeben

Danke.
mfg

Gerd

P.S.: wo hätte ich ein Tutorial oder ähnliches gefunden, dass mich auf 
alle diese Punkte hingewiesen hätte?

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Gerd Heber schrieb:
> P.S.: wo hätte ich ein Tutorial oder ähnliches gefunden, dass mich auf
> alle diese Punkte hingewiesen hätte?

Im Datenblatt des MC, Kapitel 9 Interrupts. Dadrin gibts es die Register 
Description 9.3.

Ich empfehle dir, das Datenblatt immer im Hintergrund zum Nachschlagen 
bereit zu haben. Es ist die grundlegende Quelle für Information. 
Tutorials o.ä. basieren darauf. Ausserdem kann kein Tutorial alle AVR 
abbilden. Der alte ATMega8 z.B. kannte noch gar keine Pinchange 
Interrupts.

: Bearbeitet durch User
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.