Forum: Mikrocontroller und Digitale Elektronik Sleep-Mode und PWM


von Robert (Gast)


Angehängte Dateien:

Lesenswert?

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.

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

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.

: Bearbeitet durch User
von Robert (Gast)


Lesenswert?

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

von Pandur S. (jetztnicht)


Lesenswert?

Irgendwie macht es wenig Sinn bei Standheizung, Wasser und 
Luftkreislaeufen den Powerdown Mode zu verwenden. Ob der Luefter nun 
dauernd laeuft, oder nur sporadisch macht die 10mW des Controllers bei 
weitem wett.

von Robert (Gast)


Lesenswert?

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.

von Pandur S. (jetztnicht)


Lesenswert?

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.

: Bearbeitet durch User
von Robert (Gast)


Lesenswert?

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.

von Thomas (kosmos)


Lesenswert?

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.

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.