Forum: Mikrocontroller und Digitale Elektronik AVR (AT90USB162) - Sleep Mode und PCINT


von Mirko (mirkomikro)


Angehängte Dateien:

Lesenswert?

Hallo,

ich habe hier einen AT90USB162 und möchte ihn nach dem Schlafenlegen mit 
einem Pin Change Interrupt an PB4 wieder aufwecken. Das soll mit einer 
LED an PB5 optisch angezeigt werden. Leider lässt sich der Contrller 
nicht mehr aufwecken, nachdem er im Power Down Modus ist.

Kann mir jemand vielleicht erlären woran das liegen kann?
1
/*
2
 *
3
 *  Program for sleep mode with pin change interrupt
4
 *  2024
5
 *
6
 */
7
8
#ifndef F_CPU        // Include guards
9
#define F_CPU 8000000UL    // AT90USB162 runs at 8 MHz clock speed - unsigned long
10
#endif            // Include guards
11
12
//#include <stdint.h>    // Integer variable
13
#include <avr/io.h>      // I/O ports
14
#include <util/delay.h>    // Delay function
15
#include <avr/sleep.h>    // Sleep mode
16
#include <avr/interrupt.h>  // Interrupt implemention
17
//#include <avr/wdt.h>    // Watchdog timer
18
19
20
/***************************************************
21
 *
22
 *  Description: Interrupt service routine
23
 *
24
 ***************************************************/
25
ISR(PCINT0_vect){      // Port B, PCINT0 - PCINT7
26
}
27
28
29
/***************************************************
30
 *
31
 *  Description: Main program
32
 *
33
 ***************************************************/
34
int main(void){
35
  
36
  DDRB &= ~(1 << PB4);  // PB4/Button as input
37
  DDRB |= (1 << PB5);    // PB5/LED as output
38
  
39
  cli();
40
  PCICR |= (1 << PB4);    // turn on port b
41
  PCMSK0 |= (1 << PB4);    // turn on pin PB4, which is PCINT4
42
  sei();
43
  
44
  PORTB |= (1<<PB5);    // PB5/LED on - LOW -> HIGH
45
  _delay_ms(500);      // Delay
46
  PORTB &= ~(1<<PB5);    // PB5/LED off - HIGH -> LOW
47
  _delay_ms(500);      // Delay
48
49
50
  // Sleep mode list
51
    set_sleep_mode(SLEEP_MODE_PWR_DOWN);
52
  //  set_sleep_mode(SLEEP_MODE_PWR_SAVE);
53
  //  set_sleep_mode(SLEEP_MODE_STANDBY);
54
  //  set_sleep_mode(SLEEP_MODE_EXT_STANDBY);
55
  //  set_sleep_mode(SLEEP_MODE_IDLE);
56
  //  set_sleep_mode(SLEEP_MODE_ADC);
57
  //  sleep_bod_disable();
58
59
  sleep_mode();    // Start sleep mode
60
}

: Verschoben durch Moderator
von Harald K. (kirnbichler)


Lesenswert?

Mirko schrieb:
> Kann mir jemand vielleicht erlären woran das liegen kann?

Forum: Projekte & Code

Hier könnt ihr Projekte, Schaltungen oder Codeschnipsel vorstellen. 
Projekte bitte nur mit Code oder Schaltplan posten (falls ihr nur Fotos 
vorstellen möchtet, bitte in "Zeigt her eure Kunstwerke").
Bitte hier keine Fragen posten.

Diese Formulierung ist offenbar zu komplizert.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Ich habe den Thread verschoben.

von Peter D. (peda)


Lesenswert?

Mainloop vergessen.
Er wacht auf und verläßt das Main.

von S. L. (sldt)


Lesenswert?

> PCICR |= (1 << PB4);    // turn on port b
Stimmt auch nicht, stattdessen: 'PCICR |= (1<<PCIE0);'

von Mirko (mirkomikro)


Lesenswert?

Hallo


Peter D. schrieb:
> Mainloop vergessen.
> Er wacht auf und verläßt das Main.

Danke, eigentlicht logisch...


S. L. schrieb:
>> PCICR |= (1 << PB4);    // turn on port b
> Stimmt auch nicht, stattdessen: 'PCICR |= (1<<PCIE0);'

Vielen Dank, hätte es aber auch einfach im Datenblatt nachlesen können 
:D Manchmal sieht man den Wald vor lauter Bäumen nicht.


Vielen herzlichen Dank für euren Input. Es scheint jetzt soweit für mich 
zu funktionieren.


Nur noch eine kleine Bonusfrage:
Bei mir reagiert der Controller nicht sofort nachdem er in den Schlaf 
geschickt wurde auf den PCINT. Benötigt der Controller eine Art 
"Einschlafzeit" bis er heruntergefahren ist? Bei mir braucht er etwa 3-4 
Sekunden.

von Peter D. (peda)


Lesenswert?

Mirko schrieb:
> Bei mir braucht er etwa 3-4
> Sekunden.

Klingt nach, Pin floatet (hängt in der Luft).
Luft hat weder high noch low Pegel.

von Mirko (mirkomikro)


Lesenswert?

Peter D. schrieb:
> Mirko schrieb:
>> Bei mir braucht er etwa 3-4
>> Sekunden.
>
> Klingt nach, Pin floatet (hängt in der Luft).
> Luft hat weder high noch low Pegel.

Da muss ich mich zu gegebener Zeit erst noch einlesen. Danke dazu!

Für meinen jetzigen Anwendungsfall als Alarm an einer Kühlschranktür 
funktioniert es soweit ersteinmal.

von Dietrich L. (dietrichl)


Lesenswert?

Mirko schrieb:
> Da muss ich mich zu gegebener Zeit erst noch einlesen. Danke dazu!
>
> Für meinen jetzigen Anwendungsfall als Alarm an einer Kühlschranktür
> funktioniert es soweit ersteinmal.

Wie ist der Eingang PB4 denn beschaltet?
Wenn die Kühlschranktür einen einfachen Kontakt liefert brauchst du 
einen Ziehwiderstand - ja nach Verschaltung nach GND oder VCC.

: Bearbeitet durch User
von Mirko (mirkomikro)


Lesenswert?

Dietrich L. schrieb:
> Mirko schrieb:
>> Da muss ich mich zu gegebener Zeit erst noch einlesen. Danke dazu!
>>
>> Für meinen jetzigen Anwendungsfall als Alarm an einer Kühlschranktür
>> funktioniert es soweit ersteinmal.
>
> Wie ist der Eingang PB4 denn beschaltet?
> Wenn die Kühlschranktür einen einfachen Kontakt liefert brauchst du
> einen Ziehwiderstand - ja nach Verschaltung nach GND oder VCC.

Der PB4 hat einen 10kOhm Pullup Widerstand.

von Peter D. (peda)


Lesenswert?

Mirko schrieb:
> Bei mir reagiert der Controller nicht sofort nachdem er in den Schlaf
> geschickt wurde auf den PCINT.

Die Hauptfrage ist aber, wie stellst Du das fest?

von Mirko (mirkomikro)


Lesenswert?

Peter D. schrieb:
> Mirko schrieb:
>> Bei mir reagiert der Controller nicht sofort nachdem er in den Schlaf
>> geschickt wurde auf den PCINT.
>
> Die Hauptfrage ist aber, wie stellst Du das fest?

Ich habe den Türkontakt mehrmals ausgelöst, direkt nachdem der 
Controller eingeschlafen ist. Eine LED zeigt mir, wann der MCU schläft 
oder wach ist.

Ich kann es aber auch noch gerne nachmessen...


Hmm.. könnte es ein Fehler im Code sein??
1
/*
2
 *
3
 *  Program for a door watch with sleep mode and pin change interrupt wake up
4
 *  2024
5
 *
6
 */
7
8
9
#include <stdint.h>      // Integer variable
10
#include <avr/io.h>      // I/O ports
11
#include <util/delay.h>    // Delay function
12
#include <avr/sleep.h>    // Sleep mode
13
#include <avr/interrupt.h>  // Interrupt implemention
14
#include <avr/wdt.h>    // Watchdog timer
15
16
#ifndef F_CPU        // Include guards
17
#define F_CPU 8000000UL    // AT90USB162 runs at 8 MHz clock speed - unsigned long
18
#endif            // Include guards
19
20
21
/***************************************************
22
 *  Name:        ISR(PCINT0_vect)
23
 *
24
 *  Returns:     Nothing.
25
 *
26
 *  Parameters:  None.
27
 *
28
 *  Description: Interrupt service routine
29
 *
30
 ***************************************************/
31
ISR(PCINT0_vect){      // Port B, PCINT0 - PCINT7
32
}
33
34
35
/***************************************************
36
 *  Name:        status
37
 *
38
 *  Returns:     Nothing.
39
 *
40
 *  Parameters:  None.
41
 *
42
 *  Description: Status indication.
43
 *
44
 ***************************************************/
45
void status (){
46
  PORTB |= (1 << PB5);
47
  _delay_ms (1000);
48
  PORTB &= ~(1 << PB5);
49
  _delay_ms (1000);
50
}
51
52
53
/***************************************************
54
 *  Name:        open
55
 *
56
 *  Returns:     Nothing.
57
 *
58
 *  Parameters:  None.
59
 *
60
 *  Description: Indication for door is open.
61
 *
62
 ***************************************************/
63
void open (){
64
  PORTB |= (1 << PB6);
65
  _delay_ms (1000);
66
  PORTB &= ~(1 << PB6);
67
  _delay_ms (1000);
68
}
69
70
71
/***************************************************
72
 *  Name:        alarm
73
 *
74
 *  Returns:     Nothing.
75
 *
76
 *  Parameters:  None.
77
 *
78
 *  Description: Alarm.
79
 *
80
 ***************************************************/
81
void alarm (){
82
  PORTB |= (1 << PB5);
83
  PORTB |= (1 << PB6);
84
  _delay_ms (1000);
85
  PORTB &= ~(1 << PB5);
86
  PORTB &= ~(1 << PB6);
87
  _delay_ms (1000);
88
}
89
90
91
/***************************************************
92
 *  Name:        main(void)
93
 *
94
 *  Returns:     Nothing.
95
 *
96
 *  Parameters:  None.
97
 *
98
 *  Description: Main program
99
 *
100
 ***************************************************/
101
int main(void){
102
103
    // I/O Pin setup
104
    DDRB &= ~(1 << PB4);    // Pin PB4 as input - Button
105
    DDRB |= (1 << PB5);      // Pin PB5 as output - green LED
106
    DDRB |= (1 << PB6);      // Pin PB6 as output - Buzzer/ red LED
107
108
    // Variables
109
    uint8_t counter = 0;    // Variable for counting the clock cycles how long the door was open
110
111
  // Main loop
112
  while (1){
113
114
    status();                      // Status blink
115
116
    if (PINB & (1 << PB4) && (counter < 2)){      // If button PB4 pressed = door open (HIGH -> LOW)
117
      for (uint8_t i = 0; i <= 2; i++){        // Loop until it checks input again (2 times)
118
        open();                    // Door open indication
119
      }
120
      counter += 1;                  // Counts up for how many times is input "door open" checked
121
    }
122
123
    if (PINB & (1 << PB4) && (counter == 2)){      // If button PB4 still pressed = door still open (HIGH -> LOW)
124
      for (uint8_t i = 0; i <= 2; i++){        // Loop until it checks input again (2 times)
125
        alarm();                  // Door to long open -> alarm
126
      }
127
    }
128
129
    if ((!(PINB & (1 << PB4))) && (counter <= 2)){    // If button PB4 released = door closed and wasn't open before or closed for a while (LOW -> HIGH)
130
      counter = 0;                  // Reset counter
131
      
132
      // Pin change interrupt setup
133
      cli();                      // Disable interrupt for programming
134
      PCICR |= (1<<PCIE0);              // Turn on port b
135
      PCMSK0 |= (1 << PB4);              // Turn on pin PB4, which is PCINT4
136
      sei();                      // Enable interrupt
137
138
      // Sleep mode list
139
      set_sleep_mode(SLEEP_MODE_PWR_DOWN);
140
//      set_sleep_mode(SLEEP_MODE_PWR_SAVE);
141
//      set_sleep_mode(SLEEP_MODE_STANDBY);
142
//      set_sleep_mode(SLEEP_MODE_EXT_STANDBY);
143
//      set_sleep_mode(SLEEP_MODE_IDLE);
144
//      set_sleep_mode(SLEEP_MODE_ADC);
145
146
      sleep_mode();                  // Start sleep mode
147
    }
148
  }
149
}

: 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.