Mikrocontroller ohne Quarz langsamer?

Gast #1550391
Lesenswert?

Hallo zusammen :)

Bisher war mir der Takt des Mikrocontrollers immer relativ egal, da 
weder Performance noch Timing ausschlaggebend waren. Für etwas aktuelles 
ist zwar das Timing wieder eher uninteressant (in einem vernünftigen 
Rahmen), Performance dafür umso wichtiger.
Ich verwende dafür einen ATMega 644P, der ja seine 20Mhz schaffen sollte 
bei 5V. Den Quarz habe ich mir allerdings wieder gespart.

Ich habe jetzt allerdings den Eindruck, dass der Mikrocontroller 
langsamer ist als er sein sollte... :/ kann es sein, dass er (spürbar) 
langsamer taktet, wenn kein Quarz beteiligt ist?

Danke euch :)
Gast #1550398
Lesenswert?

Hi

>Ich habe jetzt allerdings den Eindruck, dass der Mikrocontroller
>langsamer ist als er sein sollte... :/ kann es sein, dass er (spürbar)
>langsamer taktet, wenn kein Quarz beteiligt ist?

Was hast du über die Fuses eingestellt? Und woran merkst du das?

MfG Spess
Gast #1550401
Lesenswert?

> kann es sein, dass er (spürbar) langsamer taktet, wenn kein Quarz beteiligt ist?

Abgesehen davon, dass der interne Oszillator recht instabil ist 
(abhängig von Spannung und Temperatur, siehe Datenblatt) und dessen 
Frequenz demnach auch etwas nach unten abweichen kann, nein. ;)
Wie kommst du überhaupt zu der Aussage? Gemessen? Wenn nicht: Du 
könntest z.B. mal einen Pin timergesteuert togglen und mit einem Oszi 
schauen, ob er Controller das tut, was du denkst.
Gast #1550416
Lesenswert?

Naja, ich schreibe in C, sodass ich nicht genau weiß, wie viel er nun 
wirklich pro Sekunde schaffen sollte. Direkt Pins ändern geht da soweit 
ich weiß ja auch nicht, ohne den ganzen Port neuzuschreiben (was auch 
wieder mehrere Maschinenbefehle sind?).

Es ist kein Quarz angeschlossen, überhaupt nichts der Art. Hat bisher 
immer prima funktioniert :) Die AVRs (oder zumindest alle die ich bisher 
in den Fingern hatte) haben ja alle interne Oszillatoren, oder?

In den Fuses steht er auf "Int. RC Osc.".

Laufen sollte er ja auf 20 Mhz im 5V-Bereich.
Gast #1550417
Lesenswert?

Hi,
der 644P hat einen internal RC Oscillator mit 8MHz die von Werk her 
durch 8 geteilt werden.
==> Wenn du die Fuses nicht verändert hast läuft dein Kontroller also 
mit 1MHz.

Max. kannst du allerdings 8MHz erreichen wobei dieser Clock zwischen 
7.3MHz und 8.1MHz liegen darf. Er ist also ziemlich ungenau aber für die 
meisten Anwendungen genau genug.

Wenn du die 20MHz ausnutzen willst brauchst du schon eine externe 
Taktquelle mit 20MHz.

Servus
Andreas
Gast #1550418
Lesenswert?

Wenn man den internen Oszillator ohne weitere Teiler verwendet und das 
CAL-Byte auf 0xff setzt, kommt man bei einem ATmega8 oder ATmega48 knapp 
auf 16MHz.
Der ATmega644 könnte sich ähnlich verhalten.
Gast #1550426
Lesenswert?

Uff! Sieht aus, als hätte ich Nachhilfe nötig :|

Der lief dann also die ganze Zeit auf 1Mhz... kein Wunder, dass mir das 
langsam vorkam. Mit CKDIV8=0 läuft es schon gleich wesentlich 
schneller.

Was ist das CAL-Byte?

Und was muss ich beim Anschluss eines Quarzes beachten, außer den 
Kondensatoren? Sorry, für mich ist das leider Neuland... :/

Aber schonmal danke für die Erkenntis! :)
Gast #1550566
Lesenswert?

Susanne schrieb:
> Direkt Pins ändern geht da soweit
> ich weiß ja auch nicht, ohne den ganzen Port neuzuschreiben (was auch
> wieder mehrere Maschinenbefehle sind?).

Das Beschreiben geht sogar in einem Takt -- auch mit C.
1
#include <avr/io.h>
2
int main()
3
{
4
   DDRD=_BV(PIN2);
5
   while(1)
6
   {
7
     PIND=_BV(PIN2);
8
   }
9
}

Übersetzt nach Assembler mit z.B. avr-gcc 4.3.3 von Ubuntu:
avr-gcc -g  -S -mmcu=atmega164p -Os  -o toggle.s toggle.c

ergibt ab Zeile 87 :
1
.LM2:
2
  out 41-32,r24
3
  rjmp .L2

Wie man sieht eine wunderbare Schleife, die einfach nur eine Zelle 43-32 
also Zelle 9 mit r24 beschreibt. Der Compiler hat dafür gesorgt, dass in 
Register r24 4  steht.

Wenn man in das Datenblatt  (Version 8011M–AVR–08/09) vom ATmega164P / 
ATmega644P schaut, findet man, dass dies ein Toggeln des Pins D4 bewirkt 
(11.2.2).

Die Tabelle von Kapitel 28 hilft nun voraus zu sagen, dass OUT immer 
genau einen Takt und rjmp immer genau zwei Takte braucht. Alle drei 
Takte wird also einmal getoggelt also ist die Frequenz am Pin genau 
sechs mal kleiner als die des Prozessors.

C zu verwenden ist also keine Entschuldigung dafür nicht zu wissen, was 
der Prozessor tut -- es gibt sogar Compiler die voraussagen wie viel 
Energie eine Operation kostet und dann die Operationen auswählen, die am 
wenigsten Energie brauchen. Ja, sie können dies sogar im Assembly 
annotieren.


Du soltest daher
 - einen Quarz mit 20 Mhz verwenden, wenn knapp 16 Mhz reichen, weiter 
den RC Oszilator verwenden, s.o.
 - natürlich C weiter verwenden
 - dir die performancekritischen Stellen ruhig den assemblierten Code 
ansehen -- mit der Option -g sieht man sogar die Zeilen nummern des 
C-Programms, so dass man sie leichter zuordnen kann.
 - wenn das dann noch nicht reicht -- nicht Assembler verwenden, sondern 
darüber nachdenken, ob man den Algorithmus nicht umformen oder anders 
heran gehen kann, so dass es trotzdem passen wird.


Schwierig  ist es manchmal für den Compiler Schleifen Invarianten zu 
erkennen und sie dann automatisch außerhalb zu erledigen. Wenn Du zu 
viele  lebendige (1) Variablen benutzt kann es sein, dass er sie nicht 
mehr alle in Registern halten kann. Auch den Wertebereich von 
Parametern zu erraten kann schwierig sein. Wenn Du weißt dass Du für 
manche Operationen nur 8-Bit benötigst, dann sag dem Compiler dies in 
dem Du einen geeigneten Datentyp wählst. Auch ein Cast innerhalb von 
Berechnungen zu einem 8-bit Typ, kann vorausgesetzt es kann nicht zu 
Überläufen kommen, wunder wirken.


 viel Erfolg und Grüße,
  Thorsten


P.S. falls jemand nicht weiß was lebendig bedeutet...
(1) Eine Variable ist lebendig, nachdem sie geschrieben wurde, bis sie 
das letzte mal gelesen wurde, vor dem nächsten Schreiben oder Ende der 
Funktion. Globale Variablen werden in der Regel nicht in Registern 
gespeichert und sind daher teurer. Viele sprechende Variablen Namen zu 
benutzen kostet oft nichts.
Gast #1550626
Lesenswert?

Hallo Susanne,

wenn 8 MHz nicht reichen brauchst du einen Quarz.

Mit dem OSCCAL – Oscillator Calibration Register ist
es möglich den Internen Oszillator zu verstellen.
Das ist aber nur um Einflüsse von Versorgungsspannung
und Temperatur auszugleichen. Ein "Hochdrehen" auf
16 MHz liegt auserhalb der Spezifikation, interne Module
wie AD-Wandler, EEProm etc. arbeiten dann mit falschem
Timing und damit gerne falsch.

Beim Quarz geht es bis 20 MHz, wenn mal UART benötigt
besser "nur" 18,432 MHz (Baudratenquarz).
Kondensatoren (22 pF sollten passen) mit Quarz nahe
an den µC.
Bei den Fuses auf "Full Swing Crystal Oscillator"
(CKSEL3..1  011) und Startzeit nach Versorgungslage
(Datenblatt Tabelle 6.6).

AVR
Persönliche Seite #1550700
Lesenswert?

Thorsten schrieb:
> Susanne schrieb:
>> Direkt Pins ändern geht da soweit
>> ich weiß ja auch nicht, ohne den ganzen Port neuzuschreiben (was auch
>> wieder mehrere Maschinenbefehle sind?).
>
> Das Beschreiben geht sogar in einem Takt -- auch mit C.

...

>
1
> .LM2:
2
>   out 41-32,r24
3
>   rjmp .L2
4
> 
5
>

...
> Wenn man in das Datenblatt  (Version 8011M–AVR–08/09) vom ATmega164P /
> ATmega644P schaut, findet man, dass dies ein Toggeln des Pins D4 bewirkt
> (11.2.2).

Im OP steht ja das Wort Ändern. Wie willst Du in einem Takt (nur) Bit0 
auf 1 setzen?
...

> C zu verwenden ist also keine Entschuldigung dafür nicht zu wissen, was
> der Prozessor tut

Das stimmt natürlich.

Falk
Gast #1550806
Lesenswert?

Moin

Das toggling übernimmt anscheined die HW im AVR

aus dem oben genannten datenblatt.

11.2.2 Toggling the Pin
Writing a logic one to PINxn toggles the value of PORTxn, independent on 
the value of DDRxn.
Note that the SBI instruction can be used to toggle one single bit in a 
port.

AVR ist jar Harvard Architektur mit getrennten Daten und Adress Bussen, 
der Wert der geschrieben wird, kommt aus einem register, somit ist der 
Befehl in einem Takt abarbeit bar. Befehlsdekodierung läuft getrennt.

gruss
Gast #1550828
Lesenswert?

Hi

>11.2.2 Toggling the Pin
>Writing a logic one to PINxn toggles the value of PORTxn, independent on
>the value of DDRxn.
>Note that the SBI instruction can be used to toggle one single bit in a
>port.

Hat nur einen Schönheitsfehler: sbi/cbi sind nur in einem beschränkten 
Adressbereich anwendbar. Und bei einigen AVRs liegen einige Portregister 
außerhalb dieses Adressbereichs.

MfG Spess
#1550883
Lesenswert?

Susanne schrieb:
> So habe ich's bisher auch immer gemacht :)
> Hatte aber iwie angenommen, dass der Compiler das nicht in sbi / cbi
> übersetzt, sondern das Portregister neu berechnet und vollständig neu
> schreibt.

So dämlich sind die Compiler dann auch wieder nicht.
Das ist eine der einfacheren Übungen für einen Optimizer.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren