Forum: Mikrocontroller und Digitale Elektronik atmega8 und powersave


von Walter (Gast)


Lesenswert?

Ich habe folgendes Problem:
ich möchte möglichst wenig Strom verbrauchen, also Standby Powersave 
oder ähnliches.
Aufwachen soll der Prozessor auf Tastendruck, das ist nicht schwierig
aber auch nachdem der Timer abgelaufen ist. Wenn ich das Datenblatt 
richtig verstanden habe geht das aber nur wenn ich eine externe Clock 
anlege.

Ist das so oder gibt es noch eine andere möglichkeit sich quarzgenau 
wecken zu lassen?
Notfalls auch mit einem anderen Prozessor??

von Falk B. (falk)


Lesenswert?

@  Walter (Gast)

>Aufwachen soll der Prozessor auf Tastendruck,

geht aus JEDEM Sleepmodus.

>das ist nicht schwierig
>aber auch nachdem der Timer abgelaufen ist.

Geht aus fast jedem. Man muss Timer 2 als asynchronen Timer mit 32 kHz 
Uhrenquarz beschalten.

>Notfalls auch mit einem anderen Prozessor??

Ahhh neee!

MFG
Falk

von Walter (Gast)


Lesenswert?

>>Aufwachen soll der Prozessor auf Tastendruck,

>geht aus JEDEM Sleepmodus.
sag ich ja dass das NICHT schwierig ist

>>das ist nicht schwierig
>>aber auch nachdem der Timer abgelaufen ist.

>Geht aus fast jedem. Man muss Timer 2 als asynchronen Timer mit 32 kHz
>Uhrenquarz beschalten.
When AS2 is written to one, Timer/Counter 2 is clocked from a crystal 
Oscillator connected to the Timer Oscillator 1 (TOSC1) pin.
an diesem hängt aber schon mein Quarz für den Prozessor???
Ich will ja nicht mit 32kHz takten

>>Notfalls auch mit einem anderen Prozessor??

>Ahhh neee!
aber doch, sollte allerdings ein AVR mit mind. genausoviel IO Pins sein

von Tim (Gast)


Lesenswert?

>an diesem hängt aber schon mein Quarz für den Prozessor???

beim Mega8 schon.
dann must du für die Core einen der internen RC-Oszilatoren verwenden.

oder ggf die watchdog zum aufwecken missbrauchen

von Walter (Gast)


Lesenswert?

>>an diesem hängt aber schon mein Quarz für den Prozessor???

>beim Mega8 schon.
>dann must du für die Core einen der internen RC-Oszilatoren verwenden.
ich brauche aber auch einen stabilen Takt für die serielle Schnittstelle

>oder ggf die watchdog zum aufwecken missbrauchen
der ist aber wieder nicht genau

muss ich wohl den idle mode nehmen der aber leider mehr als 1mA braucht

von Sebastian (Gast)


Lesenswert?

>ich brauche aber auch einen stabilen Takt für die serielle Schnittstelle

Du kannst mit dem 32 kHz Quarz die interne Taktquelle kalibrieren.
Dann kannst Du locker Uart betreiben.

Gruß Sebastian

von Walter (Gast)


Lesenswert?

>>ich brauche aber auch einen stabilen Takt für die serielle Schnittstelle

>Du kannst mit dem 32 kHz Quarz die interne Taktquelle kalibrieren.
>Dann kannst Du locker Uart betreiben.

UBRR = fosc/8*BAUD - 1
da komme ich mit 32kHz auf keinen grünen Zweig!?
mind 1200 Baud sollten es sein (gut wären eigentlich 19200)

von Walter (Gast)


Lesenswert?

ach so, meinst du dass ich den internen RC Oszillator auf den Uhrenquarz 
kalibrieren soll?
Aber das hilft doch nicht, denn
fosc: XTAL pin frequency (System Clock).

da drunter verstehe ich doch die Frequenz des Quarzes am XTAL Pin?

von Hagen R. (hagen)


Lesenswert?

Nee,

- Systemclock auf interen RC-Oszillator einstellen, zb. 8Mhz
- 32k Quarz an XTAL
- Fuses richtig setzen, CPOL (oä.) nicht vergessen
- internen RC-Oszillator mit 32K Quarz justieren
- UART läuft dann über internen RC mit 8MHz Systemtakt

Aber! die Kalibration ist dann wirklich wichtig, sie muß sauber laufen 
und sollte von Zeit zu Zeit durchgeführt werden, driftet.

Der Asynchrone Timer wird dann mkit 32K getaktet auch wenn der Prozessor 
im Powerdown Modus ist. Deshalb ja asynchroner Timer.

Gruß Hagen

von Sebastian M. (izaseba)


Lesenswert?

Genaso wie Hagen sagt.
Man läßt einfach den asynchronen Timer mit einem zweitem Timer, der vom 
internem Takt erzeugt wird gleichzeitig laufen und dreht solange an 
OSCCAL, bis beide Timer etwa gleich laufen, fertig.
Ich poste Dir eine Funktion vom Butterfly, das klappt dann einwandfrei.
1
void OSCCAL_calibration(void)
2
{
3
    unsigned char calibrate = FALSE;
4
    int temp;
5
    unsigned char tempL;
6
7
    CLKPR = (1<<CLKPCE);        // set Clock Prescaler Change Enable
8
    // set prescaler = 8, Inter RC 8Mhz / 8 = 1Mhz
9
    CLKPR = (1<<CLKPS1) | (1<<CLKPS0);
10
    
11
    TIMSK2 = 0;             //disable OCIE2A and TOIE2
12
13
    ASSR = (1<<AS2);        //select asynchronous operation of timer2 (32,768kHz)
14
    
15
    OCR2A = 200;            // set timer2 compare value 
16
17
    TIMSK0 = 0;             // delete any interrupt sources
18
        
19
    TCCR1B = (1<<CS10);     // start timer1 with no prescaling
20
    TCCR2A = (1<<CS20);     // start timer2 with no prescaling
21
22
    while((ASSR & 0x01) | (ASSR & 0x04));       //wait for TCN2UB and TCR2UB to be cleared
23
24
    
25
    for (tempL = 0;tempL <=100 ;tempL++)
26
      _delay_ms(10);
27
     
28
    while(!calibrate)
29
    {
30
        cli(); 
31
        
32
        TIFR1 = 0xFF;   // delete TIFR1 flags
33
        TIFR2 = 0xFF;   // delete TIFR2 flags
34
        
35
        TCNT1H = 0;     // clear timer1 counter
36
        TCNT1L = 0;
37
        TCNT2 = 0;      // clear timer2 counter
38
           
39
          // wait for timer2 compareflag    
40
        while ( !(TIFR2 & (1<<OCF2A)) );   // wait for timer2 compareflag
41
42
        TCCR1B = 0; // stop timer1
43
44
        sei(); // enable global interrupt
45
    
46
  if ( (TIFR1 & (1<<TOV1)) )
47
        {
48
            temp = 0xFFFF;      // if timer1 overflows, set the temp to 0xFFFF
49
        }
50
        else
51
        {   // read out the timer1 counter value
52
            tempL = TCNT1L;
53
            temp = TCNT1H;
54
            temp = (temp << 8);
55
            temp += tempL;
56
        }
57
    
58
        if (temp > 6250)
59
        {
60
            OSCCAL--;   // the internRC oscillator runs to fast, decrease the OSCCAL
61
        }
62
        else if (temp < 6120)
63
        {
64
            OSCCAL++;   // the internRC oscillator runs to slow, increase the OSCCAL
65
        }
66
        else
67
            calibrate = TRUE;   // the interRC is correct
68
69
        TCCR1B = (1<<CS10); // start timer1
70
    }
71
}

Gruß Sebastian

von Walter (Gast)


Lesenswert?

@Hagen und Sebastian

danke für eure kompetenten Tips, werde ich dann so probieren,
hatte auch schon überlegt die UART in Software zu machen, aber die 
eingebaute erspart einem doch einiges ...

Im Datenblatt war das ganze leider doch sehr un- bis mißverständlich wo 
die Clock für die UART herstammt.

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.