Forum: Mikrocontroller und Digitale Elektronik Internen Quarz und externen 32kHz Quarz benutzen auf Atmega128A


von Tymn (werwolf92)


Lesenswert?

Guten Tag,

ich benutze den Atmega128A. Ich möchte dort den internen 8Mhz Quarz 
benutzen und ein 32kHz Uhrenquarz dran anschließen.
Durch den Uhrenquarz soll eine ISR immer wieder auftreten nach so und so 
vielen Sekunden.
Der Quarz ist an XTAL1 und 2 angeschlossen.

Ich habe so etwas schon mit meinem Atmega 88 alles hinbekommen. 
Allerdings ist beim Atmega128A alles irgendwie anders.

Ich poste hier mal meine Init. Kann mir hier jemand helfen was ich 
falsch mache?
1
volat
2
#define trans1 PINC0
3
#define trans2 PINC1
4
#define trans3 PINC2
5
#define trans4 PINC3
6
7
#define F_CPU 8000000UL
8
//#define F_TOSC 32768
9
10
#define bitOne PIND0
11
#define bitTwo PIND1
12
#define bitThree PIND2
13
#define bitFour PIND3
14
volatile unsigned int test=0;
15
16
17
#include <avr/io.h>
18
#include <util/delay.h>
19
#include <avr/interrupt.h>
20
21
22
ISR (TIMER0_OVF_vect)
23
{
24
//  TCNT0 = 128;    // vorladen auf 128.
25
  test++;
26
}
27
28
int main(void)
29
{
30
//----------------------------------------------------------------------------
31
32
  
33
  TIMSK &= ~((1<<OCIE0)|(1<<TOIE0));    // um sicher zu gehen das die aus sind
34
  ASSR = (1<<AS0);            // Asynchron mode on
35
  TCCR0 |= ((1 << CS02)|(1 << CS01));    //prescaler 256  
36
  OCR0 = 128;                // CTC
37
  while(ASSR & ((1<<TCN0UB)|(1<<OCR0UB)|(1<<TCR0UB)) )
38
  {
39
  // Abwarten, bis die Busy-Bits geloescht sind
40
  }
41
  TIFR = (1<<OCF0)|(1<<TOV0);
42
43
//_------------------------------------------------------------------------------------
44
  DDRC |= ((1 << trans1) | (1 << trans2) | (1 << trans3) | (1 << trans4));              // Transistoren-Ports auf Ausgänge gesetzt
45
  DDRD |= ((1 << bitOne) | (1 << bitTwo) | (1 << bitThree) | (1 << bitFour));              // Bits für den 7-Segment umsetzer auf Ausgänge gesetzt  
46
  
47
  PORTC &= ~((1 << trans1) | (1 << trans2) | (1 << trans3) | (1 << trans4));              // Alles auf 0 setzen
48
  PORTD &= ~((1 << bitOne) | (1 << bitTwo) | (1 << bitThree) | (1 << bitFour));            // s.o.
49
//  PORTC |= ((1 << trans1));
50
  sei();
51
}

Mein Programm hängt einfach und es passiert gar nichts....
Was muss ich ändern?

: Bearbeitet durch User
von Magnus M. (magnetus) Benutzerseite


Lesenswert?

....ein sei(); hinzufügen?

von Tymn (werwolf92)


Lesenswert?

Ok ich update mal mein Code.
sei(); ist dabei nur weiter unten.

: Bearbeitet durch User
von Thomas E. (thomase)


Lesenswert?

Wer W. schrieb:
> Der Quarz ist an XTAL1 und 2 angeschlossen.

Der Uhrenquarz wird an TOSC1 und TOSC2 angeschlossen. Der Anschluss an 
XTAL1 und XTAL2 beim 88er mit seinen 28/32 Pins an Stelle des 
"Hauptquarzes" ist der Sonderfall.

mfg.

von Tymn (werwolf92)


Lesenswert?

Thomas E. schrieb:
> Wer W. schrieb:
>> Der Quarz ist an XTAL1 und 2 angeschlossen.
>
> Der Uhrenquarz wird an TOSC1 und TOSC2 angeschlossen. Der Anschluss an
> XTAL1 und XTAL2 beim 88er mit seinen 28/32 Pins an Stelle des
> "Hauptquarzes" ist der Sonderfall.
>
> mfg.

Hallo Thomas,

Danke für die Antwort. Mein Programm hängt sich nicht mehr in der Init 
auf! Das ist schonmal super.

Nun allerdings wird meine Variable test nicht hochgezählt. Was mach ich 
den da noch falsch?

von Thomas E. (thomase)


Lesenswert?

Wer W. schrieb:
> TIMSK &= ~((1<<OCIE0)|(1<<TOIE0));    // um sicher zu gehen das die aus
> sind

Das kannst du dir sparen. Nach Reset sind die ausgeschaltet. Aber du 
musst den OVF-Int irgendwo einschalten.

mfg.

von Tymn (werwolf92)


Lesenswert?

Thomas E. schrieb:
> Wer W. schrieb:
>> TIMSK &= ~((1<<OCIE0)|(1<<TOIE0));    // um sicher zu gehen das die aus
>> sind
>
> Das kannst du dir sparen. Nach Reset sind die ausgeschaltet. Aber du
> musst den OVF-Int irgendwo einschalten.
>
> mfg.

Habe ich nun rausgenommen.

Sorry wenn ich da so doof Frage, ich finde nirgendswo, wo ich den 
OVF-Int einschalte.

Ich gehe nach der Beschreibung aus dem Datenblatt:
1
1. Disable the Timer/Counter0 interrupts by clearing OCIE0 and TOIE0.
2
2. Select clock source by setting AS0 as appropriate.
3
3. Write new values to TCNT0, OCR0, and TCCR0.
4
4. To switch to asynchronous operation: Wait for TCN0UB, OCR0UB, and TCR0UB.
5
5. Clear the Timer/Counter0 Interrupt Flags.
6
6. Enable interrupts, if needed.

Dann ist das ja so richtig oder nicht?
1
ASSR = (1<<AS0)                              // Asynchron mode on
2
TCCR0 |= ((1 << CS02)|(1 << CS01));               //prescaler 256  
3
OCR0 = 128;                  // CTC
4
TCNT0 = 128;                    
5
while(ASSR & ((1<<TCN0UB)|(1<<OCR0UB)|(1<<TCR0UB)) )
6
{
7
// Abwarten, bis die Busy-Bits geloescht sind
8
}
9
TIFR = ((1<<OCF0)|(1<<TOV0));
10
TIMSK &= ~((1<<OCIE0)|(1<<TOIE0));
11
sei();

Müssen noch bestimmte Fuses gesetzt werden? habe im moment 
INTRCOSC_8MHZ_6CK_64MS. Auch CKOPT habe ich gesetzt.

: Bearbeitet durch User
von chris (Gast)


Lesenswert?

Wer W. schrieb:
> Disable the Timer/Counter0 interrupts by clearing OCIE0 and TOIE0.

Entsprechend schaltest du ihn dann halt durch Setzen des TOIE0 ein. 
(Timer Overflow Interrupt Enable 0)

1
TIMSK |= (1<<TOIE0);
2
sei();

von Tymn (werwolf92)


Lesenswert?

Ok habe eine Lösung gefunden allerdings nicht mit OVF sondern mit COMP.
1
int main(void)
2
{
3
//----------------------------------------------------------------------------
4
5
  
6
//  TIMSK &= ~((1<<OCIE0)|(1<<TOIE0));    // um sicher zu gehen das die aus sind
7
  ASSR = (1<<AS0);            // Asynchron mode on
8
  TCCR0 |= ((1 << CS02)|(1 << CS01)|(1<<WGM01));    //prescaler 256  
9
  OCR0 = 128;        // CTC
10
  //TCNT0 = 0;      // CTC                
11
  while(ASSR & ((1<<TCN0UB)|(1<<OCR0UB)|(1<<TCR0UB)|(1<<COM01)|(1<<COM00)) )
12
  {
13
  // Abwarten, bis die Busy-Bits geloescht sind
14
15
  }
16
  TIFR |= ((1<<OCF0)|(1<<TOV0));
17
  TIMSK = (1<<OCIE0);

Die Variablen usw. passen alle nicht über ein, aber meine Test variable 
zählt sich hoch. Den Rest mit Prescaler und vorladen usw. krieg ich 
selber hin, muss mich nur noch schlau lesen!

Danke auch an Chris, habe es aber doch noch zuletzt selber gefunden.

von holger (Gast)


Lesenswert?

>Ich möchte dort den internen 8Mhz Quarz benutzen

In AVRs ist kein Quarz eingebaut;)

von PoloShirt (Gast)


Lesenswert?

Was für ein Uhrenquarz nimmt man denn da am besten?
Der Atmega128 hat an TOSC1 und 2, schon Kapazitäten von 36pf!!
Ich finde nur Uhrenquarze die max. 12,5pf haben sollten.

von PoloShirt (Gast)


Lesenswert?

Oder sind diese nur an wenn die Fuse CKOPT gesetzt sind?

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.