Tiny85 wacht nicht auf

Gast #2143413
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
#2143499
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
Gast #2143515
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
Gast #2143517
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
#2143572
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.
Gast #2143662
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

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