Mikrocontroller und Digitale Elektronik
›
Thread
Interrupt am attiny85
GH
Gerd H.
(gerd_h28)
OP
11.03.2015 00:23
#4047938
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
MV
Marc V.
(logarithmus)
(Firma: Vescomp)
11.03.2015 00:50
#4047958
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.
W
Walter
Gast
11.03.2015 05:22
#4047997
Gerd Heber schrieb:
> uint8_t schalter=2;
volatile uint8_t schalter=2;
GH
Gerd H.
(gerd_h28)
OP
11.03.2015 22:25
#4049195
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
M
MWS
Gast
11.03.2015 22:45
#4049214
Wie wär's damit den PCInt in GIMSK zu erlauben?
MV
Marc V.
(logarithmus)
(Firma: Vescomp)
11.03.2015 22:46
#4049215
Gerd Heber schrieb:
> Leider passiert immer noch nichts. Bitte nochmal um Hilfe.
PCINT feuert bei Wechsel , also sowohl bei der aufsteigender als
auch bei der abfallenden Flanke.
Abfrage entsprechend ändern, prellen berücksichtigen.
GH
Gerd H.
(gerd_h28)
OP
11.03.2015 23:07
#4049239
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?
MS
Matthias S.
(mschoeldgen)
(Firma: matzetronics)
12.03.2015 08:01
#4049390
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.
↑ Nach oben
← Zurück zu Mikrocontroller und Digitale Elektronik
Antwort schreiben