Forum: Compiler & IDEs timer0, timer2 ATmega32


von TheBeginner (Gast)


Lesenswert?

Hallo, würde gerne zwei timer in meinem Prog. implementieren. Timer 2 
nutze ich zum aufwachen aus dem save-mode. Hab den quellcode aus dem 
Tutorial kopier, funktioniert alles einwandfrei. Jetzt wollte ich einen 
zweiten timer (timer0) einbauen um die dauer des z.B. Sendemodus 
festzulegen. Z.B. Interrupt zum aufwecken kommt alle 250ms, schlafen 
legen möchte ich aber den uC nach 100ms. Leider falle ich in den 
Schalfmodus und wache nicht mehr auf. Bekomme einmal die Ausgabe "rex_1" 
sonst nichts.
1
//***********************TIMER 2 configuration
2
// Analogcomparator ausschalten
3
 
4
    ACSR = 0x80;
5
 
6
// Timer2 konfigurieren
7
 
8
    ASSR  = (1<< AS2);              // Timer2 asynchron takten, 
9
                
10
    _delay_ms(1000);               // Einschwingzeit des 32kHz Quarzes
11
    TCCR2  = 3;                     // Vorteiler 32 -> 0,250s 
12
    while((ASSR & (1<< TCR2UB)));   // Warte auf das Ende des Zugriffs
13
    TIFR   = (1<<TOV2);             // Interrupts löschen (*)
14
    TIMSK |= (1<<TOIE2);            // Timer overflow Interrupt 
15
16
17
18
//***********************TIMER 0
19
20
  TCCR0 =(1<<CS02)|(1<<CS00);  //(1/3686400)*1024*255=~0,07s
21
   TIMSK =(1<<TOIE0);   //enable overflow interrupt
22
23
//***************ISR Timer0
24
25
ISR(TIMER0_OVF_vect)
26
{
27
sleep_timer++;    //overflow every 70ms
28
uart_puts("rex_1\r\n");
29
  if(sleep_timer==5 && i_am_master==1)   //4*70ms, here i_am_master=1
30
  {
31
    uart_puts("rex_4\r\n");
32
    rf12_rxmode_sleep();  //shut down RF12
33
    sleep_function();
34
  }
35
}
36
37
//*****************Timer2
38
ISR(TIMER2_OVF_vect) 
39
{
40
  uart_puts("\r\noverflow_8\r\n");
41
42
  if(i_am_master==0)
43
  {
44
    if(!BUTTON_1)
45
    {
46
      uart_puts("\r\noverflow_1\r\n");
47
      rf12_rxmode();
48
    }
49
  }
50
51
}
52
53
54
int main
55
{
56
57
if(i_am_master==0)  //master, only receiving data
58
     {
59
         "hier daten senden etc. nachdem Daten gesendet, geh schlafen"
60
   
61
          if(!BUTTON_1)//if button was not pressen, then go to sleep mode
62
                {
63
                    rf12_rxmode_sleep();    //shut dwn RF12
64
                    sleep_function();
65
                }
66
67
     }
68
}

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Wird wohl an deiner geheimen Funktion "sleep_function()" liegen.

von TheBeginner (Gast)


Lesenswert?

Die geheime sleep_function() is eigentlich nicht so geheim :)
Habe auch aus dem Tutorial kopiert
1
void sleep_function(void)
2
{
3
    OCR2 = 0;                       // Dummyzugriff
4
          while((ASSR & (1<< OCR2UB)));   // Warte auf das Ende des 
5
    set_sleep_mode(SLEEP_MODE_PWR_SAVE);
6
    sleep_mode();
7
}

also im Sendemodus benutze ich nur den Timer2 zum aufwecken des Systems.
Wenn ich aber, in den Empfangsmodus umschalte,
dann kommt der Timer0 ins spiel. Timer2 wird auf
die Dauer von 1 minute vergrößert. D.h beide Timer fangen gleich an,
Timer0 brings das System nach 250ms in den sleep_mode und
Timer2 (asynchron getaktet) soll das System dann nach
1 sec (250ms+750ms) wieder aufwecken. Leider falle ich ins Komma!
1
//***********************TIMER 2 configuration
2
3
    ACSR = 0x80;
4
    ASSR  = (1<< AS2);              // Timer2 asynchron takten, 
5
    
6
    _delay_ms(1000);               // Einschwingzeit des 32kHz Quarzes
7
    TCCR2  = 3;                     // Vorteiler 32 -> 0,250s   
8
                              
9
    while((ASSR & (1<< TCR2UB)));   // Warte auf das Ende des Zugriffs
10
    TIFR   = (1<<TOV2);             // Interrupts löschen (*)
11
    TIMSK =(1<<TOIE2);
12
13
//***********************TIMER 0
14
15
  TCCR0 =(1<<CS02)|(1<<CS00);  //(1/3686400)*1024*255=~0,07s
hier komme ich in den Empfangsmodus
1
if(timer_==25)  //timer_=14 are 7sec, button zähler
2
  {
3
  i_am_master=1;    //after pressing button 30 sec,  
4
                           //slave(sender) becames master(receiver)
5
              
6
        timer_=0;      //set timer to 0
7
            
8
         TCCR2 =(1<<CS20)|(1<<CS22);  //wake up period 1s for master  
9
                                        //(128), 1,02s, Timer2
10
11
  TIMSK |=(1<<TOIE0);  //activate interupts for Timer0
12
13
  uart_puts("rxmode!\r\n ");
14
  sleep_timer=0;
15
}

interupt funktionen
1
ISR(TIMER0_OVF_vect)
2
{
3
  sleep_timer++;    //overflow every 65ms
4
  if(sleep_timer==6 && i_am_master==1)  //325ms
5
  {
6
    rf12_rxmode_sleep();  //shut down RF12
7
    sleep_function();
8
  }
9
}
10
11
//******************TIMER OVERFLOW for 32768Hz
12
ISR(TIMER2_OVF_vect) 
13
{
14
  if(i_am_master==0)
15
  {
16
    if(!BUTTON_1)
17
    {
18
      uart_puts("\r\noverflow_1\r\n");
19
      rf12_rxmode();  //fahre das RF12 hoch
20
    }
21
  }
22
23
  else  //if I am master
24
  {
25
      sleep_timer=0;
26
      rf12_rxmode();
27
      uart_puts("\r\nwake_up_timer\r\n");
28
29
  }
30
}

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Du hast an einigen Stellen widersprüchlich zitiert.  Bitte zeige mal
die (ggf. gekürzten) Dateien compilierfähig in einer Form, in der
dein Fehler reproduzierbar ist.  Ob innerhalb des Artikels oder als
Anhang, ist mir ziemlich wurscht, aber sie sollten geschlossen
übersetzbar sein.  (Makefile muss nicht unbedingt sein, die wesentlichen
Compileroptionen genügen mir.)

von TheBeginner (Gast)


Lesenswert?

Also habe jetzt mal das Tutorial genomme und dieses ein bisschen 
erweitert. Rufe jetzt den sleep_mode durch einen Interrupt meines 
Timers0 auf. Dasselbe Problem. Ist der sleep_mode() ind der main 
funktion so funktioniert es einwandfrei.
1
#define F_CPU 1000000
2
 
3
#include <avr/io.h>
4
#include <avr/sleep.h>
5
#include <avr/interrupt.h>
6
#include <util/delay.h>
7
8
9
#include <avr/pgmspace.h>
10
#include <avr/eeprom.h>
11
#include <stdlib.h>
12
13
#include "portbits.h"
14
#include "global.h"
15
#include "uart.h"
16
#include "leds.h"
17
 
18
// globale Variablen
19
 
20
volatile uint8_t flag;
21
volatile unsigned int sleep_timer;
22
unsigned int an_aus=0;
23
24
25
void sleep_function(void);
26
27
// lange, variable Wartezeit, Einheit in Millisekunden
28
 
29
void long_delay(uint16_t ms) {
30
    for (; ms>0; ms--) _delay_ms(1);
31
}
32
 
33
int main (void) {
34
35
    uart_puts("test_0");
36
 
37
// IO konfigurieren
38
 
39
    DDRA = 0xFF;
40
    DDRB = 0xFF;
41
    DDRC = 0xFF;
42
    DDRD = 0xFF;
43
 
44
// Analogcomparator ausschalten
45
 
46
    ACSR = 0x80;
47
 
48
// Timer2 konfigurieren
49
 
50
    ASSR  = (1<< AS2);              // Timer2 asynchron takten
51
    long_delay(1000);               // Einschwingzeit des 32kHz Quarzes
52
   // TCCR2  = 6;                     // Vorteiler 256 -> 2s  
53
                                      //Überlaufperiode
54
     TCCR2 =(1<<CS20)|(1<<CS22);  //wake up period 1s for master 
55
                                     //(128), 1,02s
56
    while((ASSR & (1<< TCR2UB)));   // Warte auf das Ende des Zugriffs
57
    TIFR   = (1<<TOV2);             // Interrupts löschen (*)
58
    TIMSK = (1<<TOIE2)|(1<<TOIE0);            // Timer overflow Interrupt 
59
                                             //freischalten
60
61
    TCCR0 =(1<<CS02)|(1<<CS00);  //(1/3686400)*1024*255=~0,07s
62
    long_delay(1000);               // Einschwingzeit des 32kHz Quarzes
63
64
// Interrupts freigeben
65
 
66
    sei();
67
 
68
// Endlose Hauptschleife
69
 
70
    while(1) 
71
  { 
72
  
73
  }
74
}
75
 
76
// Timer2 overflow Interrupt
77
 
78
ISR(TIMER2_OVF_vect) {
79
80
  if(an_aus==0)
81
  {
82
    PORTD |= (1 << PD5);
83
    an_aus=1;
84
  }
85
  else
86
  {
87
    PORTD &= ~(1 << PD5);               // LED ausschalten
88
    an_aus=0;
89
  }
90
91
  TCNT0=0; //setze inhalt von Timer0 auf null
92
93
}
94
95
96
 
97
ISR(TIMER0_OVF_vect)
98
{  
99
  uart_puts("timer_0");
100
  sleep_timer++;    //overflow every 65ms
101
  if(sleep_timer==30)  //325ms
102
  {
103
    if(an_aus==0)
104
    {
105
      PORTD |= (1 << PD6);
106
107
    }
108
    else
109
    {
110
      PORTD &= ~(1 << PD6);            // LED ausschalten
111
112
    }
113
114
    OCR2 = 0;                       // Dummyzugriff
115
        
116
                while((ASSR & (1<< OCR2UB)));   // Warte auf das Ende des 
117
                                               //Zugriffs
118
    set_sleep_mode(SLEEP_MODE_PWR_SAVE);
119
    sleep_mode();
120
    sleep_timer=0;
121
  }
122
}

von TheBeginner (Gast)


Lesenswert?

1
OCR2 = 0;                       // Dummyzugriff
2
while((ASSR & (1<< OCR2UB)));   // Warte auf das Ende des Zugriffs
3
set_sleep_mode(SLEEP_MODE_PWR_SAVE);
4
sleep_mode();

musste anscheinend außerhalb der Interrupt Routine

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

TheBeginner schrieb:

> OCR2 = 0;                       // Dummyzugriff
> while((ASSR & (1<< OCR2UB)));   // Warte auf das Ende des Zugriffs

Was du damit bezweckst, verstehe ich nicht.

> //wake up period 1s for master
> //(128), 1,02s

Wie kommst du auf "1,02 s"?  Es sind (im Rahmen der Genauigkeit deines
Quarzes) 1,00 s.

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.