-         

Ergebnis 1 bis 7 von 7

Thema: Wie schnell rennt mein AVR?

  1. #1
    Erfahrener Benutzer Robotik Einstein Avatar von SprinterSB
    Registriert seit
    09.06.2005
    Ort
    An der Saar
    Beiträge
    2.801

    Wie schnell rennt mein AVR?

    Anzeige

    SMARTPHONES & TABLETS-bis zu 77% RABATT-Kostenlose Lieferung-Aktuell | Cool | Unentbehrlich
    Hallo AVR-Freunde!

    Bei vielen AVR-Projekten muss man wissen, wie schnell der Kamerad getaktet wird. Das braucht man, um etwa Timer richtig zu initialisieren oder die richtigen Werte für Baudrate-Register zu erhalten.

    Wie geht man es aber an, wenn man die Taktrate nicht kennt zur Zeit der Programmerstellung?

    Also AVR aus, anderer Quarz dran oder andere Fuses gesetzt, AVR an und alles geht wie gewohnt, ohne das Programm mit angepasstem Taktwert neu zu übersetzen.

    Mit meiner Lösung schaffe ich das nicht viel genauer als 5%, was für eine UART-Initialisierung leider zu ungenau ist. Eine deutlich bessere Genauigkeit ist erreichbar, aber dann ist der Code von Chip zu Chip unterschiedlich.

    Evtl schafft es ja jemand die Taktrate so genau zu bestimmen, daß sie zur UART-Initialisierung taugt?

    Bin mal gespannt, welche Lösungen ihr hervorzaubert!

    Das ganze soll natürlich ohne extra Hardware/Beschaltung zur Taktbestimmung gehen...
    Disclaimer: none. Sue me.

  2. #2
    Super-Moderator Robotik Visionär Avatar von PicNick
    Registriert seit
    23.11.2004
    Ort
    Wien
    Beiträge
    6.836
    Naja, ohne daß der UART-Widerpart mitspielt, ist das schwierig. Die üblichen Autobaud-Verfahren beruhen darauf, daß ein definiertes Zeichen empfangen wird, und aus dem eventuellen Lesefehler dann die Korrektur abgeleitet wird.
    Aber der zugehörige Code ist ab dann natürlich überflüssig.
    mfg robert
    Wer glaubt zu wissen, muß wissen, er glaubt.

  3. #3
    Erfahrener Benutzer Robotik Einstein Avatar von SprinterSB
    Registriert seit
    09.06.2005
    Ort
    An der Saar
    Beiträge
    2.801
    Zitat Zitat von PicNick
    Naja, ohne daß der UART-Widerpart mitspielt, ist das schwierig.
    Hehe, eigentlich recht einfach.

    Ausserdem geht's ohne extra Hardware. Etwas ohne Hardware auf den UART zu senden wär allerdings schwierig...

    Auto-Baud ist also nicht das Zauberwort.
    Disclaimer: none. Sue me.

  4. #4
    Super-Moderator Robotik Visionär Avatar von PicNick
    Registriert seit
    23.11.2004
    Ort
    Wien
    Beiträge
    6.836
    Vielleicht gibt der EEPROM was her
    mfg robert
    Wer glaubt zu wissen, muß wissen, er glaubt.

  5. #5
    Erfahrener Benutzer Robotik Einstein Avatar von SprinterSB
    Registriert seit
    09.06.2005
    Ort
    An der Saar
    Beiträge
    2.801
    So langsam wird's wärmer...
    Disclaimer: none. Sue me.

  6. #6
    Erfahrener Benutzer Robotik Einstein Avatar von SprinterSB
    Registriert seit
    09.06.2005
    Ort
    An der Saar
    Beiträge
    2.801
    Das EEPROM ist nur Mittel zum Zweck. Durch Schreiben ins EEPROM kommt man an den internen 1MHz RC-Oszillator:

    Zitat Zitat von AVR-Manual
    The calibrated Oscillator is used to time the EEPROM accesses. Table 1 lists the typical programming time for EEPROM access from the CPU.
    Number of Calibrated RC Oscillator Cycles(1): 8448
    Note (1): Uses 1 MHz clock, independent of CKSEL Fuse settings.
    Allzu genau wird das aber nicht. Hier mal als C-Funktion für Mega8:
    Code:
    #include <avr/io.h>
    #include <avr/eeprom.h>
    
    #define EEPROM_CYCLES 8448
    #undef EEPROM_CYCLES
    #define EEPROM_CYCLES 8241 /* nach-kalibriert */
    
    #define EEPROM_LOOP_CYCLES 5
    
    // Ergibt Oszillator-Frequenz in kHz
    uint16_t get_fosc()
    {
    	uint16_t fosc;
    	
    	// EE-Adresse setzen, Datum lesen...
    	eeprom_read_byte ((uint8_t*) 0);
    	
    	fosc = -1;
    	
    	// ...und wieder schreiben
    	__asm__ volatile (
    		"in	__tmp_reg__, __SREG__"  "\n\t"	
    		"cli"                         "\n\t"	
    		"sbi	%2-0x20, 2"             "\n\t"	
    		"sbi	%2-0x20, 1"             "\n\t"	
    		"0:"                          "\n\t"	
    		"adiw %0, 1      ; 2 cycles"  "\n\t"	
    		"sbic	%2-0x20, 1 ; 1 cycle"   "\n\t"	
    		"rjmp	0b         ; 2 cycles"  "\n\t"	
    		"out	__SREG__, __tmp_reg__"
    			: "=w" (fosc)
    			: "0" (fosc), "M" (&EECR)
    			
    	);
    
    	// vermeidet Division
    	const uint32_t x = (EEPROM_CYCLES/2 + 0x10000*EEPROM_LOOP_CYCLES*1000)/EEPROM_CYCLES;
    	
    	return (x*fosc) >> 16;
    }
    Mit einem 16MHz-Quarz erhalte ich damit ca 15.600 kHz, zu ungenau für eine UART-Initialisierung.

    Wenn ich das Verfahren einmal mir einem 16MHz-Quarz kalibriere, dann wird es um einiges genauer (8241 für EEPROM_CYCLES):

    22.1184MHz ............. 22110 kHz
    18 MHz .................... 17971 kHz
    16 MHz .................... 15998 kHz
    10 MHz .................... 9978 kHz
    7.3728 MHz .............. 7361 kHz

    Das sind Fehler von weniger als 0.2%, damit wäre es genau genug für den UART.

    Ein Ersatz für Auto-Baud ist das allerdings nicht. Wenn Daten mit variablen Baudraten reinkommen, hilt das auch nix...

    Woher die Abweichung von über 3% bei dem im Manual angegebenen Wert von 8448 kommt...keine Ahnung. Ebenso, wie groß die Temperaturdrift ist und die Spannungs- und Altersabgängigkeit.
    Disclaimer: none. Sue me.

  7. #7
    Super-Moderator Robotik Visionär Avatar von PicNick
    Registriert seit
    23.11.2004
    Ort
    Wien
    Beiträge
    6.836
    Gut, Baudrate ist ja auch partnerbezogen, der muß ja auch erstmal genau sein. Und das übliche mit <CR> ist ja ausgelegt, aus der standardisierten Baudraten-palette was rauszusuchen und nicht als Feinjustierung.

    Es ist aber schön. daß du das mal durchgezogen hast, da sieht man, was man erwarten kann.
    mfg robert
    Wer glaubt zu wissen, muß wissen, er glaubt.

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •