Problem Timerinterrupt und Sleepmodus

Gast #4368306
Lesenswert?

Hallo,

ich habe aus Kombination der hier vorgestellten Artikel und 
Beispielcodes versucht, eine LED durch Timerinterrupt langsam togglen zu 
lassen. Das funktioniert soweit. Jetzt möchte ich, dass der AVR zwischen 
den Toggleoperationen schlafen geht.

Mein Code funktioniert nicht. Wenn ich den Inhalt von while() 
auskommentiere, blinkt die LED wie gewünscht, aber eben ohne Sleep 
zwischendurch. Woran liegt das?
1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3
#include <avr/sleep.h>
4
#include <util/delay.h>
5
 
6

7
int main(void)
8
{
9
  DDRB=0xff;
10
  OCR1A = 0xf40;
11

12
  TCCR1B |= (1 << WGM12);
13
  // Mode 4, CTC on OCR1A
14

15
  TIMSK1 |= (1 << OCIE1A);
16
  //Set interrupt on compare match
17

18
  TCCR1B |= (1 << CS12) | (1 << CS10);
19
  // set prescaler to 1024 and start the timer
20

21
  sei();
22
  // enable interrupts
23

24
  while (1)
25
  {
26
    // we have a working Timer
27
    
28
    set_sleep_mode(SLEEP_MODE_EXT_STANDBY);
29
    sleep_enable();
30
    sei();
31
    sleep_cpu();
32
    sleep_disable();
33
  
34
  }
35
  
36
  
37
}
38

39

40
 
41
ISR (TIMER1_COMPA_vect)
42
{
43
  if (PORTB == 0x00)
44
  PORTB = 0xFF;
45
  else
46
  PORTB = 0x00;
47
}
Gast #4368364
Lesenswert?

Ich habe jetzt Timer2 verwendet. Der ist lt. Datenblatt auch zum 
aufwecken. So funktioniert es mit schlafen zwischendurch.
1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3
#include <avr/sleep.h>
4
#include <util/delay.h>
5

6
int c=0;
7

8
int main(void)
9
{
10
  DDRB=0xff;
11
  OCR1A = 0xff;
12
  
13
  ASSR  = (1<< AS2);
14
  _delay_ms(1000);
15

16
  TCCR2B |= (1 << WGM21);
17
  // Mode 2, CTC on OCRA
18

19
  TIMSK2 |= (1 << OCIE2A);
20
  //Set interrupt on compare match
21

22
  TCCR2B |= (1 << CS22) | (1 << CS21) | (1 << CS20);
23
  // set prescaler to 1024 and start the timer
24

25
  sei();
26
  // enable interrupts
27

28
  while (1)
29
  {
30
    // we have a working Timer
31
    
32
    set_sleep_mode(SLEEP_MODE_PWR_SAVE);
33
    sleep_enable();
34
    //sei();
35
    sleep_cpu();
36
    sleep_disable();
37
    
38
  }
39
  
40
  
41
}
42

43

44

45
ISR (TIMER2_COMPA_vect)
46
{
47
  c++;
48
  if (c==20)
49
  {
50
    c=0;
51
    if (PORTB == 0x00)
52
    PORTB = 0xFF;
53
    else
54
    PORTB = 0x00;
55
  }
56
  
57
}

Trotzdem gibt es noch eine Unklarheit: Es ist ein 16 MHz Quarzoszillator 
angeschlossen, entsprechend ist SUT_CKSEL auf EXTOSC_8MHz_XX...... 
eingestellt.
Das Ganze funktioniert, egal ob ich ASSR  = (1<< AS2); aufrufe, oder 
auskommentiere. Meiner Meinung nach dürfte es ohne Asynchronmodus gar 
nicht funktionieren???? Außerdem steht im DB: "The CPU main clock 
frequency must be more than four times the Oscillator frequency." Ist 
bei meinem Aufbau aber nicht so. Es ist 16 MHz angeschlossen, damit wird 
meinem Verständnis nach der Timer2 hochgezählt (mit 1024 prescaler), und 
der Haupttakt ist auch 16 MHz, allerdings mit CKDIV8, also 2 MHz.

Jetzt wollte ich den AVR mit seiner eigenen, integrierten Taktquelle 
8MHz arbeiten lassen, dann passiert aber gar nichts mehr. Liegt das 
vielleicht daran:? "The CPU main clock frequency must be more than four 
times the Oscillator frequency."?
#4368988
Lesenswert?

Rudolfi schrieb:
> Das Ganze funktioniert, egal ob ich ASSR  = (1<< AS2); aufrufe, oder
> auskommentiere.

Natürlich nicht.
Wenn als Taktquelle für deinen 328er Quarzbetrieb eingestellt, steht der 
Asynchronmodus des Timer2 nicht mehr zur Verfügung. Das ginge z.B bei 
einem 644. Der hat verschiedene Anschlüsse für CPU-Takt und 
Asynchrontakt.

Rudolfi schrieb:
> Jetzt wollte ich den AVR mit seiner eigenen, integrierten Taktquelle
> 8MHz arbeiten lassen, dann passiert aber gar nichts mehr. Liegt das
> vielleicht daran:? "The CPU main clock frequency must be more than four
> times the Oscillator frequency."?

Das liegt auch daran, dass der Asynchron-Oszillator den Quarz nicht zum 
Schwingen bekommt. Dieser Oszillator ist für den Betrieb mit einem 
Uhrenquarz gedacht. Womit sich die passenden Frequenzverhältnisse dann 
i.a.R. von selbst ergeben.

mfg.

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