Forum: Mikrocontroller und Digitale Elektronik 16Mhz @ 4 Mhz geht das?


von elvis (Gast)


Lesenswert?

Moin,

ich habe einen ATmega16 mit einem 16 Mhz quarz (2x22pF). Nach langen 
rumprobieren läuft er jetzt auch. Ich habe eine LED zu Testen 
angeschlossen und sie blinken lassen. Nach meinem Oszi sind es 4,3xxx 
Mhz.
Ich kann leider den den takt nicht direkt an XTAL2 messen da er dann
aus geht (nicht mehr schwingt).

Meine Vermutung ist, das es am Programm liegt. Sieht wie volgt aus:
1
ISR(TIMER0_OVF_vect)
2
{
3
  TCNT0 = 245;         // 10 Takte warten
4
  if(PORTD == 231)
5
  {
6
    PORTD = 247;
7
  }
8
  else
9
  {
10
    PORTD = 231;
11
  }
12
}
Ist nur die Interrupt routine die die LED ein bzw aus schaltet.
(Prescaler ist aus)
Wandelt WINAVR das evtl so "scheisse" um das es er für die If anweisung
die restlichen Zeit benötigt?? (Gibt es einen eine Möglichkeit in C das 
Komplement des Port Pins direkt zu bilden).
Oder liegt es am Quarz bzw. bzw an der Verdrahtung Masse nicht gleich 
masse usw. (Er liegt allerding direckt an XTALx). Ich kenne mich zwar 
nicht mit quarzen aus aber ich denke mal das das nicht möglich ist das 
der Oszillator dann nur mit 4 Mhz Schwingt.

MFG

von Johannes M. (johnny-m)


Lesenswert?

Was glaubst Du, wie lange es von dem Moment, in dem das Interrupt Flag 
gesetzt wird, dauert, bis der Code im Interrupt-Handler ausgeführt wird? 
Das ist im Vergleich zu den 10 Takten, die Du haben willst, ne halbe 
Ewigkeit...

von Johannes M. (johnny-m)


Lesenswert?

BTW:
Die CPU braucht 4 Takte, um den Programmzähler auf dem Stack zu sichern, 
das I-Bit zu löschen und in den Vektor zu springen. Der Sprung aus dem 
Vektor zum eigentlichen Interrupt-Handler braucht (bei AVRs mit mehr als 
8 KiB Flash, also auch beim Mega16) 3 Takte. Dort angekommen, sichert 
der Compiler erst mal das SREG (in und push, macht noch mal 2 Takte), 
einige wichtige Rechenregister (mindestens 3-4 Takte, eher mehr). Jetzt 
kannste ja mal nachzählen... Selbst in Assembler geht das nicht!

von elvis (Gast)


Lesenswert?

Also liegt es einizg und allein an der Interrupt routine ?!?
Hab mich noch nicht sehr lange mit den Timern beschäftigt allerdings
meine ich im Datenblatt gelesen zu haben das mann eine PWM bzw
einen Funktionsgenerator aufbauen kann.(Läuft dann meine ich auch mit 
Interrupts)
Aber läuft dann wahrscheinlich nur mit geringeren Frequenzen als mit 
nahezu 16Mhz.

Der link geht leider nicht :(

MFG

von elvis (Gast)


Lesenswert?

Ich möchte eigendlich nur wissen wie schnell der Quarz schwing, ob 
errichtig funktioniert.
Gibt es da ne möglichkeit das zu messen.

von Johannes M. (johnny-m)


Lesenswert?

Wenn Du nur einen Pin toggeln willst, dann geht das mit den Frequenzen 
nur hardwaremäßig (Timer im CTC-Modus, OC0 als Ausgang)! Mit Interrupts 
kannste das komplett vergessen. Und nen Timer-Preload macht man beim AVR 
überhaupt nicht! Dafür gibts schließlich die Compare-Einheiten.

Und noch was:
Gewöhne Dir AUF JEDEN FALL wieder ab, Bitmasken für Ports als 
Dezimalwerte zu schreiben! Das kann keine Sau lesen. Muss man immer erst 
rechnen. Entweder hexadezimal oder (falls Dir das lieber ist) binär.

von elvis (Gast)


Lesenswert?

Wusste leider nicht wie ich dem Kompiler das Binärformat beibringe.
Also 0x.. oder bx0101 das ist mein Problem.

Ich werde das mal mit dem Timer1 testen ich glaube das ist der einzige 
bei dem diese geht melde mich dann nochmal :)

MFG

von Johannes M. (johnny-m)


Lesenswert?

elvis wrote:
> Ich möchte eigendlich nur wissen wie schnell der Quarz schwing, ob
> errichtig funktioniert.
> Gibt es da ne möglichkeit das zu messen.
Wenn 16 MHz draufstehen und Du mit dem obigen Programm auf das oben 
beschriebene Verhalten kommst, dann scheint der µC immerhin mit den 16 
MHz zu laufen.

von Johannes M. (johnny-m)


Lesenswert?

WINAVR-Binärsyntax: 0b01010101

Siehe auch Doku und diverse Tutorials!

von elvis (Gast)


Lesenswert?

Also ein Zustand (0,1) hält ca. 2,3us Sekunden an. Ein "Takt" 
(Periodendauer sind 62.5 ns. Macht also 36,8 Takte. Also minus meiner 10 
noch 26,8 bearbeitungstakte. Könnte ja hinkommen.

MFG

von Michael G. (linuxgeek) Benutzerseite


Lesenswert?

> Ich möchte eigendlich nur wissen wie schnell der Quarz schwing, ob
> errichtig funktioniert. Gibt es da ne möglichkeit das zu messen.

Mit was misst Du denn? Eigentlich sollte der nicht aufhoeren zu 
schwingen... zumindest nicht wenn Du mit einem Oszi misst - OK die 
Tastkoepfe haben eine Kapazitaet allerdings meine ich dass das kein 
gutes Zeichen ist. Wie hast Du denn den Quarz in Deinem Layout 
platziert? Wo sind die Lastkondenstatoren?


Gruesse,
Michael

von Karl H. (kbuchegg)


Lesenswert?

elvis wrote:
> Ich möchte eigendlich nur wissen wie schnell der Quarz schwing, ob
> errichtig funktioniert.
> Gibt es da ne möglichkeit das zu messen.

Und warum machst du dir dann das Leben so dermassen schwer?
Nimm den 16 Bit Timer her und lass den komplett durchzählen.

16000000 / 65536 = 244 Hz

Ist noch ein bischen zu hoch, also in der Overflow ISR nochmal
durch 122 teilen und eine LED in diesem Takt umschalten.

uint8_t Counter;

ISR( TIMER1_OVF_vect)
{
  Counter++;
  if( Counter == 122 ) {
    Counter = 0;

    PORTD ^= ( 1 << PD4 );
  }
}

Wenn dein Quarz jetzt exakt mit 16 Mhz schwingt, dann leuchtet
deine LED exakt im Sekundentakt auf. Das kann man auch mit
friem Auge sehen.

von elvis (Gast)


Lesenswert?

So ich habe jetzt nochmal ein bischen rumgelötet um mein Board mit dem 
STK500 über ISP programmieren zu können.
Ich lasse jetzt den Timer 255 Schritte machen dann kommt der overflow 
Interrupt. Rechnerisch ergibt sich eine Zeit von 15,95xxxx us und mein 
Oszi zeigt genau das an. Also der Quarz läuft mit 16Mhz.
Das die ISR jetzt noch 20 oder mehr Takte benötigt um den Port Pin zu 
ändern ist egal da das ja immer die Gleiche Zeit in anspruchnehmen 
sollte.

Zum Layout: Der Quarz sitzt direkt an den XTALx pins sowie die die C's.
Die Masse habe ich zum Massepins des ATmega gezogen damit seine masse 
auch die der Kondensatoren ist.

Danke nochmal für die hilfe.

MFG
elvis

von mr.chip (Gast)


Lesenswert?

Kleiner Tipp: Im AVRStudio simulieren! Solche Timing-Aspekte kann man so 
nämlich ganz nett und sehr genau beobachten. Notfalls kannst du dir 
sogar den erzeugten Assemblercode ansehen.

von Rolf Magnus (Gast)


Lesenswert?

> Die CPU braucht 4 Takte, um den Programmzähler auf dem Stack zu
> sichern, das I-Bit zu löschen und in den Vektor zu springen.

Vorher muß er den aktuell ausgeführten Befehl noch fertigmachen.

> Der Sprung aus dem Vektor zum eigentlichen Interrupt-Handler braucht
> (bei AVRs mit mehr als 8 KiB Flash, also auch beim Mega16) 3 Takte.

> Dort angekommen, sichert der Compiler erst mal das SREG (in und push,
> macht noch mal 2 Takte),

Um das SREG in ein Register lesen zu können, muß er das vorher erstmal 
sichern. Außerdem macht ein Push alleine schon zwei Takte. Somit sind 
wir hier insgesamt nicht bei 2, sondern bei 5 Takten.

> einige wichtige Rechenregister (mindestens 3-4 Takte, eher mehr).

Zwei pro Register.

von AVRFan (Gast)


Lesenswert?

>Ich möchte eigendlich nur wissen wie schnell der Quarz schwing, ob
>errichtig funktioniert.
>Gibt es da ne möglichkeit das zu messen.

Klar. Die einfachste Möglichkeit wäre, Deinen Controller dieses 
Assemblerprogramm ausführen zu lassen:
1
_Loop:
2
    ldi   r16, 0
3
    out   PORTB, r16
4
5
    nop
6
    nop
7
    nop
8
9
    ldi   r16, 1
10
    out   PORTB, r16
11
12
    nop
13
    rjmp  _Loop
Wie Du direkt nachzählen kannst, benötigt es vom ersten "out" bis zum 
zweiten genau fünf Taktzyklen, und vom zweiten bis zum ersten ebenfalls 
fünf ("rjmp" nimmt zwei Zyklen in Anspruch, alle anderen Instruktionen 
einen).  Somit toggelt Pin 0 von Port B mit genau *** 1/10 *** der 
Quarzfrequenz.  Frequenzzähler anschließen, ablesen - fertig.

von Johannes M. (johnny-m)


Lesenswert?

@Rolf:
Jau, stimmt natürlich. push braucht ja zwei Takte...

von AVRFan (Gast)


Lesenswert?

Nachtrag: Du musst natürlich vor der Schleife noch den Pin 0 von Port B 
über DDRB als Ausgang konfigurieren:
1
_Reset:
2
    ldi   r16, 1
3
    out   DDRB, r16
4
5
_Loop:
6
    ldi   r16, 0
7
    out   PORTB, r16
8
9
    nop
10
    nop
11
    nop
12
13
    ldi   r16, 1
14
    out   PORTB, r16
15
16
    nop
17
    rjmp  _Loop

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.