mikrocontroller.net

Forum: Compiler & IDEs timer0, timer2 ATmega32


Autor: TheBeginner (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.
//***********************TIMER 2 configuration
// Analogcomparator ausschalten
 
    ACSR = 0x80;
 
// Timer2 konfigurieren
 
    ASSR  = (1<< AS2);              // Timer2 asynchron takten, 
                
    _delay_ms(1000);               // Einschwingzeit des 32kHz Quarzes
    TCCR2  = 3;                     // Vorteiler 32 -> 0,250s 
    while((ASSR & (1<< TCR2UB)));   // Warte auf das Ende des Zugriffs
    TIFR   = (1<<TOV2);             // Interrupts löschen (*)
    TIMSK |= (1<<TOIE2);            // Timer overflow Interrupt 



//***********************TIMER 0

  TCCR0 =(1<<CS02)|(1<<CS00);  //(1/3686400)*1024*255=~0,07s
   TIMSK =(1<<TOIE0);   //enable overflow interrupt

//***************ISR Timer0

ISR(TIMER0_OVF_vect)
{
sleep_timer++;    //overflow every 70ms
uart_puts("rex_1\r\n");
  if(sleep_timer==5 && i_am_master==1)   //4*70ms, here i_am_master=1
  {
    uart_puts("rex_4\r\n");
    rf12_rxmode_sleep();  //shut down RF12
    sleep_function();
  }
}

//*****************Timer2
ISR(TIMER2_OVF_vect) 
{
  uart_puts("\r\noverflow_8\r\n");

  if(i_am_master==0)
  {
    if(!BUTTON_1)
    {
      uart_puts("\r\noverflow_1\r\n");
      rf12_rxmode();
    }
  }

}


int main
{

if(i_am_master==0)  //master, only receiving data
     {
         "hier daten senden etc. nachdem Daten gesendet, geh schlafen"
   
          if(!BUTTON_1)//if button was not pressen, then go to sleep mode
                {
                    rf12_rxmode_sleep();    //shut dwn RF12
                    sleep_function();
                }

     }
}


Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wird wohl an deiner geheimen Funktion "sleep_function()" liegen.

Autor: TheBeginner (Gast)
Datum:

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

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!
//***********************TIMER 2 configuration

    ACSR = 0x80;
    ASSR  = (1<< AS2);              // Timer2 asynchron takten, 
    
    _delay_ms(1000);               // Einschwingzeit des 32kHz Quarzes
    TCCR2  = 3;                     // Vorteiler 32 -> 0,250s   
                              
    while((ASSR & (1<< TCR2UB)));   // Warte auf das Ende des Zugriffs
    TIFR   = (1<<TOV2);             // Interrupts löschen (*)
    TIMSK =(1<<TOIE2);

//***********************TIMER 0

  TCCR0 =(1<<CS02)|(1<<CS00);  //(1/3686400)*1024*255=~0,07s

hier komme ich in den Empfangsmodus
if(timer_==25)  //timer_=14 are 7sec, button zähler
  {
  i_am_master=1;    //after pressing button 30 sec,  
                           //slave(sender) becames master(receiver)
              
        timer_=0;      //set timer to 0
            
         TCCR2 =(1<<CS20)|(1<<CS22);  //wake up period 1s for master  
                                        //(128), 1,02s, Timer2

  TIMSK |=(1<<TOIE0);  //activate interupts for Timer0

  uart_puts("rxmode!\r\n ");
  sleep_timer=0;
}

interupt funktionen
ISR(TIMER0_OVF_vect)
{
  sleep_timer++;    //overflow every 65ms
  if(sleep_timer==6 && i_am_master==1)  //325ms
  {
    rf12_rxmode_sleep();  //shut down RF12
    sleep_function();
  }
}

//******************TIMER OVERFLOW for 32768Hz
ISR(TIMER2_OVF_vect) 
{
  if(i_am_master==0)
  {
    if(!BUTTON_1)
    {
      uart_puts("\r\noverflow_1\r\n");
      rf12_rxmode();  //fahre das RF12 hoch
    }
  }

  else  //if I am master
  {
      sleep_timer=0;
      rf12_rxmode();
      uart_puts("\r\nwake_up_timer\r\n");

  }
}

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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.)

Autor: TheBeginner (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.
#define F_CPU 1000000
 
#include <avr/io.h>
#include <avr/sleep.h>
#include <avr/interrupt.h>
#include <util/delay.h>


#include <avr/pgmspace.h>
#include <avr/eeprom.h>
#include <stdlib.h>

#include "portbits.h"
#include "global.h"
#include "uart.h"
#include "leds.h"
 
// globale Variablen
 
volatile uint8_t flag;
volatile unsigned int sleep_timer;
unsigned int an_aus=0;


void sleep_function(void);

// lange, variable Wartezeit, Einheit in Millisekunden
 
void long_delay(uint16_t ms) {
    for (; ms>0; ms--) _delay_ms(1);
}
 
int main (void) {

    uart_puts("test_0");
 
// IO konfigurieren
 
    DDRA = 0xFF;
    DDRB = 0xFF;
    DDRC = 0xFF;
    DDRD = 0xFF;
 
// Analogcomparator ausschalten
 
    ACSR = 0x80;
 
// Timer2 konfigurieren
 
    ASSR  = (1<< AS2);              // Timer2 asynchron takten
    long_delay(1000);               // Einschwingzeit des 32kHz Quarzes
   // TCCR2  = 6;                     // Vorteiler 256 -> 2s  
                                      //Überlaufperiode
     TCCR2 =(1<<CS20)|(1<<CS22);  //wake up period 1s for master 
                                     //(128), 1,02s
    while((ASSR & (1<< TCR2UB)));   // Warte auf das Ende des Zugriffs
    TIFR   = (1<<TOV2);             // Interrupts löschen (*)
    TIMSK = (1<<TOIE2)|(1<<TOIE0);            // Timer overflow Interrupt 
                                             //freischalten

    TCCR0 =(1<<CS02)|(1<<CS00);  //(1/3686400)*1024*255=~0,07s
    long_delay(1000);               // Einschwingzeit des 32kHz Quarzes

// Interrupts freigeben
 
    sei();
 
// Endlose Hauptschleife
 
    while(1) 
  { 
  
  }
}
 
// Timer2 overflow Interrupt
 
ISR(TIMER2_OVF_vect) {

  if(an_aus==0)
  {
    PORTD |= (1 << PD5);
    an_aus=1;
  }
  else
  {
    PORTD &= ~(1 << PD5);               // LED ausschalten
    an_aus=0;
  }

  TCNT0=0; //setze inhalt von Timer0 auf null

}


 
ISR(TIMER0_OVF_vect)
{  
  uart_puts("timer_0");
  sleep_timer++;    //overflow every 65ms
  if(sleep_timer==30)  //325ms
  {
    if(an_aus==0)
    {
      PORTD |= (1 << PD6);

    }
    else
    {
      PORTD &= ~(1 << PD6);            // LED ausschalten

    }

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


Autor: TheBeginner (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
OCR2 = 0;                       // Dummyzugriff
while((ASSR & (1<< OCR2UB)));   // Warte auf das Ende des Zugriffs
set_sleep_mode(SLEEP_MODE_PWR_SAVE);
sleep_mode();

musste anscheinend außerhalb der Interrupt Routine

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.