Sleep-Mode und PWM

Gast #4390230
Hallo,

ich habe einen DC/DC-Wandler mit einem Atmega88 aufgebaut um damit ein 
Fahrzeuggebläse betreiben zu können, wenn die Standheizung läuft um die 
Wärme aus dem Kühlwasser in den Innenraum zu befördern.

Allerdings habe ich dabei ein Problem, wenn ich den AVR in den 
asynchronen power-save Mode versetze, schaltet sich sporadisch das 
Gebläse ein und nach kurser Zeit wieder ab, obwohl der PWM-Timer 
eigentlich abgeschaltet sein sollte.

Hier wird die PWM-Abschaltung und der Sleepmode bearbeitet.
1
//...
2
switch (status){
3
  case OFF:{
4
    if(calculate_pwm_percent() > 0){
5
      disable_pwm();
6
      print_ign_aux();
7
      draw_bar_graph(calculate_pwm_percent());
8
      off = false;
9
    }else if((vbat.integer*100 + vbat.fraction > 1280)){
10
      print_ign_aux();
11
      dog_write_empty_line(NEW_POSITION(7,0));
12
      off = false;
13
    }else{          
14
      if(off == false){
15
        DISPLAY_PORT &= ~(1<<DISPLAY_LIGHT);
16
        save_pwm_values();
17
        dog_clear_lcd();
18
        dog_transmit(LCD_OFF);
19
        off = true;
20
      }else{
21
        timer1_disable();
22
        timer1_disabled = true;
23
        
24
        OCR2A = 0;                       // Dummyzugriff
25
        while((ASSR & (1<< OCR2AUB)));   // Warte auf das Ende des Zugriffs
26
        sleep_mode();
27
      }
28
      
29
    }
30
    
31
    break;
32
  }        
33
  case IGNITION_ON:{
34
    DISPLAY_PORT &= ~(1<<DISPLAY_LIGHT);
35
    off = false;
36
    print_ign_aux();
37
    dog_write_empty_line(NEW_POSITION(7,0));
38
    break;
39
  }
40
  case AUX_HEAT_ON:{
41
    off = false;
42
    if((adc_value[TEMP_WATER] < 1016)){//check if sensor mounted!
43
      if(water_temp > water_value){  //check water temp
44
        if(!(SH_PIN & (1<<POT_SWITCH))){      //check if fan enabled
45
          pwm_value_aux = adc_value[POT_VALUE];  //start fan
46
          enable_pwm(pwm_value_aux);
47
                          
48
        }else{
49
          disable_pwm();            //stop fan
50
        }
51
      }else{
52
        if(water_temp < (water_value - 10)){
53
          disable_pwm();            //water too cold -> stop fan
54
        }          
55
      }
56
    }else{
57
      //#warning: "TODO: implement delay"
58
      if(second/60 >= delay_value){
59
        pwm_value_aux = adc_value[POT_VALUE];  //start fan
60
        enable_pwm(pwm_value_aux);
61
        second = delay_value*60;
62
      }
63
    }
64
    DISPLAY_PORT |= (1<<DISPLAY_LIGHT);
65
    print_ign_aux();
66
    draw_bar_graph(calculate_pwm_percent());
67
    break;
68
  }
69
//...
70
}

Mit den folgenden Funktionen wird der PWM-Timer ein- bzw. ausgeschaltet:
1
void timer1_init(void){
2
// FastPWM Mode 14 (ICR1 = Top)) from 2 to 33.500 kHz;
3
    TCCR1A = 0x00;
4
    TCCR1B = 0x00;
5
    TCCR1A |= (1<<COM1A1) | (1<<WGM11);    // frequency and phasecorrect, non-inverted PWM
6
    TCCR1B |= (1<<WGM13) | (1<<WGM12);    
7
}
8
void timer1_disable(void){
9
  // FastPWM Mode 14 (ICR1 = Top)) from 2 to 33.500 kHz;
10
    TCCR1A = 0x00;
11
    TCCR1B = 0x00;
12
}

Was kann ich tun, damit mir die PWM nicht sporadisch das Gebläse 
einschatet? Danke.
Angehängte Dateien:
(Firma: matzetronics)
Die Kernroutinen enable_pwm() und disable_pwm() hast du leider nicht 
gepostet. Wie schaltest du denn die PWM ab?
Zuverlässig funktioniert hier die Abschaltung dadurch, das ich den PWM 
Ausgang auf Eingang umschalte. Das setzt allerdings voraus, das mittels 
Pullup oder Pulldown der Pin auf den inaktiven Pegel gezogen wird.
Gast
Danke. Der Hinweis auf die Datenrichtung ist die Lösung.

In den enable und disable Funktionen werden (nach einer Glättung für 
langsames Anfahren und Abregeln) einfach nur das OCR1A-Register gesetzt.

Problem gelöst. :D
Gast
Wenn die Standheizung gerade nicht läuft und das Auto sanft beleuchtet 
unter Laterne steht, darf der AVR ruhig schlafen. In der Zeit würde die 
Endstufe ja auch Strom verbrauchen.
Es gibt ja einen Zustand "Standheizung laeuft nicht". Von einem Timer 
vorgegeben, darf auch ein RTC sein. Und waehrend dieser Zeit kann man 
die ganze Endstufe abschalten, den PWM sowieso. Waehrend einem Sleep 
muss der controller ja nur alle N sekunden aufwachen, und den Timer mit 
der Vorgabe vergleichen.
Heisst : Sleep und PWM sehen sich nie.
Gast
Genau adrauf zielte meine Frage ja auch ab. Genau diesen Zustand hatte 
ich gesucht und dadurch dass ich den PWM-Modus nicht 100%ig (DDR musste 
noch angepasst werden) abgeschaltet hatte, kam das Gebläse immer mal 
beim Wake mit.
Im TCCR kann man den Pin wieder in den normal Mode setzen und dann eine 
0 auf den Ausgang geben zusätzlich auch den Timer anhalten.

Habe das Datenblatt des ATMega88 nicht zur Hand beim ATMega16M1 kann man 
mit dem PRR (Power Reduce Register) einzelne Pheriperiebauteile wie z.B. 
CAN, LIN, SPI, ADC, Timer... gezielt abschalten.

Vielleicht gibts das beim Atmegga88 ja auch schon.

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 10 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.