Forum: Mikrocontroller und Digitale Elektronik Tiny85 wacht nicht auf


von Oddel (Gast)


Lesenswert?

Tach,

ich habe ein RFM12 am Tiny85 hängen und möchte nach Senden eines Pakets 
den Tiny schlafen schicken. Mit einem Mega128 getestet und funktioniert 
,
wenn ich die sleeproutine durch einen delay ersetze funktionieren die 
Routinen auch.
Ich finde keinen Fehler, bzw. keinen offensichtlichen ;)
Nach einer eingestellten Zeit wird der INT0 vom RFM12 auf LOW gezogen 
und bleibt dort bis zum Nimmerleinstag.
1
....
2
    MCUCR = (1<<ISC01);                          // fallende Flanke INT0
3
    sei();
4
    PRR |= (1<<PRTIM1) | (1<<PRUSI) | (1<<PRADC); // Timer1 abschalten, USI  und ADC brauchen wir nicht !
5
    set_sleep_mode(SLEEP_MODE_PWR_DOWN);
6
    sleep_enable();
7
8
....
9
        writeCmd(0xEF01); // WakeupTimer ca 30sek.
10
        writeCmd(0x8203); // Alles bis auf den WakeupTimer aus !
11
12
        GIMSK |= (1<<INT0);  // auf alle Fälle noch den INT zum wecken aktivieren !
13
        sleep_cpu();
14
        GIMSK &= ~(1<<INT0);

In Datenblatt zum Tiny85 steht noch zum Wakeup INT0 :

Note: 1. For INT0, only level interrupt.

Das RFM12 zieht nach Ablauf der Zeit den Int0 von High auf Low oder muss 
ich beim level INT noch was beachten ?

Gruß
Oddel

von Thomas E. (thomase)


Lesenswert?

Oddel schrieb:
> Note: 1. For INT0, only level interrupt.

Das hast du doch schon richtig erkannt.

Warum machst du dann das?

MCUCR = (1<<ISC01);                          // fallende Flanke INT0


mfg.

von Michael U. (amiga)


Lesenswert?

Hallo,

benutze ich so mit RFM02 und Tiny45/85.
1
int main()
2
{
3
...
4
  PCMSK = (1<<RFM02_IRQ);                  // Pin Change IRQ
5
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);
6
  sleep_enable();
7
8
  rfm02_init();
9
  sei();
10
11
...
12
13
      rfm02_send_data();
14
15
      GIFR = (1<<PCIF);                    // evtl. noch anstehenden IRQ löschen
16
      GIMSK = (1<<PCIE);                  // Pin-Change-IRQ an
17
18
      sleep_cpu();                        // und schlafen schicken
19
20
}
Aus rfm02_init()
1
  rfm02_send_cmd(0xCC00);   // Status read
2
3
  rfm02_send_cmd(0xC0E0);   // Power Settings: Quarz ein, Synthesizer und PA ein bei Send-Command
4
  rfm02_send_cmd(0xC2A0);    // low bat detector, TX Bit Sync, WakUp-Timer Calibrierung aus
5
  rfm02_send_cmd(0x8883);    // Control: 1MHz Clock Out, 12,5pF Last Quarz, 120kHz Shift
6
  rfm02_send_cmd(0xA620);    // Frequenz: 430MHz + (0,0025 * 0x620) -> 433,92MHz
7
  rfm02_send_cmd(0xB400);   // Power 4 * -3dBm -> .12dBm
8
  rfm02_send_cmd(0xD2C0);   // Set PLL: set 33%
9
  rfm02_send_cmd(0xC810);   // Baudrate: 344827 / 19200 = 17 - 1 -> 0x10                   // Status read
10
  rfm02_send_cmd(0xE500 + 200); // WakeUp-Timer 2^7 *234ms ~ 30s ???!! nicht 1ms sondern 10ms !!???
11
  rfm02_send_cmd(0xC002);   // alles aus, WakeUp-Timer ein
12
13
  rfm02_send_cmd(0xC440);   // sleep, noch 64 Takte

Aus rfm02_send_data():
1
  rfm02_send_cmd(0xC002);                   // alles aus, WakeUp-Timer ein
2
  rfm02_send_cmd(0xC440);                   // sleep, noch 64 Takte

http://www.avr.roehres-home.de/sensoren/index.html

läuft schon knapp 2 Jahre so.
Die C-Versionen der Software liegen wohl nicht auf meiner Homepage, nur 
die alten Assembler-Versionen.
Kann ich aber hier anhängen, wenn gewünscht.

Gruß aus Berlin
Michael

von tom (Gast)


Lesenswert?

mach es mal in der reihenfolge...

1. schlafen legen:
1.1. isr disablen
1.2. nicht benötigte peripherie abschalten
1.3. GIMSK für den pin setzen
1.4. PCMSK für den pin setzen
1.5. MCUCR setzen
1.6. isr enablen
1.7. sleep

2. aufwachen (in pin change isr)
2.1. MCUCR = 0x00; (MUSS die erste anweisung sein in der isr)
2.2. GIMSK = 0x00;


so wird's auch was mit dem aufwachen

von Oddel (Gast)


Lesenswert?

Hallo Thomas,

danke !Habe mir gerade noch einmal die Beschreibung zum MCUCR angeschaut 
und dementsprechend das Register angepasst.
1
       GIMSK |= (1<<INT0);  // auf alle Fälle noch den INT zum wecken aktivieren !
2
        MCUCR &= ~(1<<ISC01);                          // fallende Flanke INT0
3
        sleep_cpu();
4
        GIMSK &= ~(1<<INT0);
5
        MCUCR = (1<<ISC01);                          // fallende Flanke INT0

jetzt funktioniert der Code 1x und danach geht er nicht mehr 
schlafen....
Irgendwie kann ich mit dem Begriff "LEVEL INT" nichts anfangen.
gruß
oddel

von Thomas E. (thomase)


Lesenswert?

Oddel schrieb:
> Irgendwie kann ich mit dem Begriff "LEVEL INT" nichts anfangen.

Level Interrupt bedeutet, daß, je nach Einstellung, bei 0 oder 1 ein 
Interrupt ausglöst wird.

Angenommen es ist Low-Level eingestellt, dann wird ein Interrupt 
ausgelöst, wenn der Pin Low IST. Wenn der Interrupt dann abgearbeitet 
wurde und der Pin immer noch Low ist, dann wird der Interrupt erneut 
ausgelöst.


Level Change Interrupt bedeutet, daß ein Interrupt ausgelöst wird, wenn 
sich der Zustand des Pins ändert. Also von 1 auf 0 geht oder von 0 auf 
1.

Flankengetriggerter Interrupt bedeutet, je nach Einstellung, daß beim 
Übergang von einem Pegel auf den anderen, ein Interrupt ausgelöst wird.

Beispiel: Low-Edge-Triggered: Wenn der Pegel von High auf Low geht, wird 
ein Interrupt ausgelöst. Geht er wieder von Low auf High wird KEIN 
Interrupt ausgelöst.

Flankensteuerung benötigt aber den CPU-Takt. Da dieser im Sleepmode 
ausgeschaltet ist, funktioniert nur Level-Interrupt.


Oddel schrieb:
> MCUCR = (1<<ISC01);                          // fallende Flanke INT0

Warum schaltest du wieder auf Flanke?

mfg.

von Oddel (Gast)


Lesenswert?

Danke an Alle !

Funktioniert jetzt !
1
       set_sleep_mode(SLEEP_MODE_PWR_DOWN);
2
        sleep_enable();
3
4
        GIMSK |= (1<<INT0);  // auf alle Fälle noch den INT zum wecken aktivieren !
5
        MCUCR &= ~(1<<ISC01);                          // fallende Flanke dekativiert INT0
6
7
        sleep_cpu();
8
        MCUCR = (1<<ISC01);                          // fallende Flanke INT0

set_sleep_mode und sleep_enable waren nicht in der While(1) Schleife und 
wie es scheint wird das Enable nach dem Sleep auf Disable geschaltet , 
ist das so ?

Ich schalte wieder auf Flanke weil ich im Betrieb die fallende Flanke 
vom RFM12 auswerte.

@Michael U. : hast du beim Tiny85 schon einmal das EEPROM beschrieben ?

Gruß
Oddel

von Thomas E. (thomase)


Lesenswert?

Oddel schrieb:
> set_sleep_mode und sleep_enable waren nicht in der While(1) Schleife und
> wie es scheint wird das Enable nach dem Sleep auf Disable geschaltet ,

> ist das so ?
Nein.

Das hat da gar nichts zu suchen. In die Schleife gehört nur sleep_cpu();

Wenn das so nicht funktioniert, ist irgendwas nicht in Ordnung.

mfg.

von Oddel (Gast)


Lesenswert?

ja hast recht , habe gerade noch einmal über den Code geschaut und siehe
da ! ich beschreibe in MCUCR nur ISC01 (fehlendes |= ) somit werden die
SE - Bits überschrieben !

von Michael U. (amiga)


Lesenswert?

Hallo,

> @Michael U. : hast du beim Tiny85 schon einmal das EEPROM beschrieben ?

Bei meinen Sensoren nicht, in anderen Projekten schon, allerdings in 
Assembler. Wüßte jetzt aber nicht, ob es da was Besonderes gibt.

Müßte ich nachschauen...

Gruß aus Berlin
Michael

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.