mikrocontroller.net

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


Autor: elvis (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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:
ISR(TIMER0_OVF_vect)
{
  TCNT0 = 245;         // 10 Takte warten
  if(PORTD == 231)
  {
    PORTD = 247;
  }
  else
  {
    PORTD = 231;
  }
}
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

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht 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...

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht 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!

Autor: elvis (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: elvis (Gast)
Datum:

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

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: elvis (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
WINAVR-Binärsyntax: 0b01010101

Siehe auch Doku und diverse Tutorials!

Autor: elvis (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Michael G. (linuxgeek) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: elvis (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: mr.chip (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: AVRFan (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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:
_Loop:
    ldi   r16, 0
    out   PORTB, r16

    nop
    nop
    nop

    ldi   r16, 1
    out   PORTB, r16

    nop
    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.

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Rolf:
Jau, stimmt natürlich. push braucht ja zwei Takte...

Autor: AVRFan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nachtrag: Du musst natürlich vor der Schleife noch den Pin 0 von Port B 
über DDRB als Ausgang konfigurieren:
_Reset:
    ldi   r16, 1
    out   DDRB, r16

_Loop:
    ldi   r16, 0
    out   PORTB, r16

    nop
    nop
    nop

    ldi   r16, 1
    out   PORTB, r16

    nop
    rjmp  _Loop

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.