Forum: Mikrocontroller und Digitale Elektronik Mikrocontroller ohne Quarz langsamer?


von Susanne (Gast)


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 :)

von Eselchen (Gast)


Lesenswert?

das ist ein Witz oder???

von Εrnst B. (ernst)


Lesenswert?

Wenn du den Quarz gespart hast, was hast du dann stattdessen dort 
angeschlossen?
Keramik-Resonator? RC-Kombi?
Wie sind die Fuses gesetzt?

von Paul B. (paul_baumann)


Lesenswert?

Jain! ;-)
Wenn der Quarz eine niedrigere Frequenz hat als der interne Generator
dann ja. Guck mal in das Datenblatt, auf welcher Frequenz er arbeitet,
wenn die Werkseinstellungen noch nicht geändert wurden.

MfG Paul

von spess53 (Gast)


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

von G.a.s.tj (Gast)


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.

von Susanne (Gast)


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.

von andreas (Gast)


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

von Tauwetter (Gast)


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.

von spess53 (Gast)


Lesenswert?

Hi

>Laufen sollte er ja auf 20 Mhz im 5V-Bereich.

Es gibt keinen AVR mit internem 20MHz-Oszillator.

MfG Spess

von Susanne (Gast)


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! :)

von Ich (Gast)


Lesenswert?

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

Quarz nah ran an die Pins und guter Kontakt der Kondensatoren zu GND.

Oder nimm einen Quarzoszillator, sowas hier:
http://www.reichelt.de/?;ACTION=3;LA=2;GROUPID=3174;ARTICLE=13694;

von G.a.s.tj (Gast)


Lesenswert?

Seite 36 im Datenblatt des von dir verwendeten Controllers.
http://www.atmel.com/dyn/resources/prod_documents/doc8011.pdf

Für die Problematik aber momentan nicht wirklich relevant, du legst ja 
keinen allzu großen Wert auf Genauigkeit.

von Thorsten (Gast)


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.

von avr (Gast)


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

von Falk W. (dl3daz) Benutzerseite


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

von Karl H. (kbuchegg)


Lesenswert?

Falk Willberg schrieb:

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

Die AVR haben genau dafür einen ganz speziellen Befehl.
Und natürlich kennt den auch der C-Compiler ....

http://www.mikrocontroller.net/articles/AVR-Tutorial:_IO-Grundlagen#Zugriff_auf_einzelne_Bits

von Susanne (Gast)


Lesenswert?

Wie ist denn der zu sbi / cbi passende Befehl für den C-Compiler?

von termite (Gast)


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

von spess53 (Gast)


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

von Karl H. (kbuchegg)


Lesenswert?

Susanne schrieb:
> Wie ist denn der zu sbi / cbi passende Befehl für den C-Compiler?

Beim avr-gcc

   PORTx |= ( 1 << PIN_NR );

   PORTx &= ~( 1 << PIN_NR );

:-)

von Susanne (Gast)


Lesenswert?

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.

von Karl H. (kbuchegg)


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.

von Thomas K (Gast)


Lesenswert?

Hallo!

>Wie ist denn der zu sbi / cbi passende Befehl für den C-Compiler?

#define sbi(ADDRESS,BIT) ((ADDRESS)|=(1<<(BIT)))
#define cbi(ADDRESS,BIT) ((ADDRESS)&=~(1<<(BIT)))

Gruss
Thomas

von Susanne (Gast)


Lesenswert?

Danke euch allen für die Hilfe und das gigantische Licht, das mir 
aufgegangen ist :)

von Tauwetter (Gast)


Lesenswert?

>...gigantische Licht

Scheint bei Dir etwa die Sonne?

Neid, Neid, Neid,....

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.