Forum: Mikrocontroller und Digitale Elektronik Problem mit INT0 auf Attiny24A


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Tim T. (tim_taylor) Benutzerseite


Bewertung
0 lesenswert
nicht lesenswert
Nabend,

ich habe ein Problem mit meinem Programm, ein absolutes Luxusproblem, es 
sollte eigentlich nicht funktionieren aber es funktioniert wie 
gewünscht.
Also ums etwas einzugrenzen, ich setze in meinem kleinen Würfelprogramm 
den Timer1 (Abschalttimer) zurück wenn ein Externer Interrupt auf PB2 
kommt, dieser sollte durch entsprechendes setzen des MCUCR nur dann 
ausgelöst werden wenn es eine fallende Flanke ist, demnach hatte ich 
erwartet das bei dauerhaftem low-Pegel auf PB2 dieser NICHT ausgelöst 
wird und somit Timer1 nicht zurück gesetzt wird und der Tiny nach ein 
paar Sekunden in den Powerdown geht, die Realität sieht aber anders 
aus...

PS: Wenn PB2 nicht auf low-Pegel ist, geht der Tiny nach der 
entsprechnden Zeit ohne Probleme in den Powerdown und wacht auch beim 
auslösen des INT0 wie gewünscht wieder auf!
1
#include <avr/io.h>
2
#include <avr/sleep.h>
3
#include <avr/interrupt.h>
4
#include <inttypes.h>
5
6
const uint8_t Muster[] = {0x08, 0x44, 0x4C, 0x55, 0x5D, 0x77};
7
volatile uint8_t Zahl = 1;
8
9
int main(void) {
10
11
 // Pin 1-8 von PORTA als Ausgang
12
 DDRA = 0xFF;
13
14
 // PORTB Pullup für PB2 an, alle anderen Bits von PORTB auf 0
15
 PORTB = (1<<PB2);
16
17
 // Prescaler 8 => 128.000/8 = 16.000 Hz
18
 TCCR0B = (1<<CS01);
19
20
 // Prescaler 64 => 128.000/64 = 2.000 Hz
21
 TCCR1B = (1<<CS11) | (1<<CS10);
22
23
 // Overflow Interrupt für Timer0 erlauben
24
 TIMSK0 |= (1<<TOIE0);
25
26
  // Overflow Interrupt für Timer1 erlauben
27
 TIMSK1 |= (1<<TOIE1);
28
29
 // INT0 Interrupt bei fallender Flanke
30
 MCUCR |= (1<<ISC01);
31
32
  // INT0 Interrupt auf PB2 aktivieren
33
 GIMSK |= (1<<INT0);
34
35
 // Powerdown Mode als Sparmodus, alles aus, nur Pin Interrupts funktionieren noch
36
 set_sleep_mode(SLEEP_MODE_PWR_DOWN);
37
38
 // Global Interrupts aktivieren
39
 sei(); 
40
 
41
 while(1) {
42
  if (Zahl < 6) Zahl++;
43
  else Zahl = 1;
44
 }
45
46
 return 0;
47
}
48
49
// 16.000 Hz/256 = 62,5 Hz
50
ISR (TIM0_OVF_vect) { 
51
52
 // Wenn PB2 low dann Zahlenmuster auf PortA ausgeben
53
 if ( !(PINB & (1<<PINB2)) ) PORTA = Muster[Zahl-1];
54
}
55
56
// 2.000 Hz/65.536 = 0,03 Hz -> 32,768s
57
ISR (TIM1_OVF_vect) { 
58
59
 // Augen aus!
60
 PORTA = 0x00;
61
62
 // schlafen
63
 sleep_enable();
64
}
65
66
//PB2 Int auf fallender Flanke
67
ISR (EXT_INT0_vect) {
68
69
 // Timer1 (Schlaftimer) zurücksetzen!
70
 TCNT1 = 0;
71
}

Jemand ne Idee dazu?

von Carl D. (jcw2)


Bewertung
0 lesenswert
nicht lesenswert
sleep() in ISR?
sleep_enable() ohne sleep()?

So "kompliziert" wie dieses Prgramm ist, braucht man keine Interrupts, 
die entsprechenden Flags INTF0, TOV0 und TOV1 kann man auch in der 
Main-Loop abfragen. Um diese zu quittieren (zu löschen), einfach eine 1 
reinschreiben.

Eventuell reicht es auch die Zahl 62,5 mal je Sekunde hochzuzählen.

von Tim T. (tim_taylor) Benutzerseite


Bewertung
-1 lesenswert
nicht lesenswert
Carl D. schrieb:
> sleep() in ISR?
> sleep_enable() ohne sleep()?

Spielt keinerlei Rolle. sleep_enable() funktioniert entsprechend, und 
auch diesmal. Das merkwürdige Verhalten (INT0 ISR wird ausgelöst trotz 
Pin auf LOW) bleibt auch wenn man den µC garnicht in den Schlaf setzt 
oder über einen Pin die Ausführung des Timer1_ovf anzeigen lässt, also 
bitte keine unnötigen/falschen Nebenkriegsschauplätze eröffnen.

> So "kompliziert" wie dieses Prgramm ist, braucht man keine Interrupts,
> die entsprechenden Flags INTF0, TOV0 und TOV1 kann man auch in der
> Main-Loop abfragen. Um diese zu quittieren (zu löschen), einfach eine 1
> reinschreiben.
Ist bekannt, aber warum sollte ich das per Hand machen? Auch das tut 
garnichts zur Sache...

von Tim T. (tim_taylor) Benutzerseite


Bewertung
-1 lesenswert
nicht lesenswert
Ja, hab den Fehler mittlerweile gefunden, es ist ein Pending Interrupt 
(vom Timer) der dafür sorgt das der µC garnicht in den Powerdown kommt. 
Abgesehen davon würde ein Edge INT0 im Powerdown auch garnicht 
funktionieren laut Datenblatt...

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.