AVR Fuses

Aus der Mikrocontroller.net Artikelsammlung, mit Beiträgen verschiedener Autoren (siehe Versionsgeschichte)
Wechseln zu: Navigation, Suche

Regelmäßig wiederkehrende Beiträge im Forum zeigen, dass die Fuses der AVR doch einige Tücken in sich bergen. Dieser Artikel kann die Recherche im Datenblatt nicht ersetzen, sondern soll lediglich helfen, auf die Problemstellen aufmerksam zu werden.

Grundsätzliche Vorgehensweise

Bei einem neuen µC ist es grundsätzlich notwendig im Datenblatt genau dieses µCs den Auslieferungszustand der Fuses zu ermitteln. So werden beispielsweise die ATmega mit aktiviertem internen Oszillator ausgeliefert und man darf sich dementsprechend nicht wundern, wenn der µC einfach nicht mit dem angeschlossenen Quarz (XTAL) oszillieren will.

Neueinsteigern wird das Programmieren mit einem "nutzerfreundlichen" Programmer mit GUI empfohlen: z. B. AVR-Studio STK500/AVRISP-Plugin, AVR-Studio AVRProg (für AVR910 Programmer) oder PonyProg. Hier sollten die Fuses erst einmal vom µC ausgelesen werden. Im Vergleich mit dem Datenblatt kann man dann feststellen, ob nun die dargestellten Häkchen invertiert sind oder nicht. Dann ändert man nur die relevanten Bits und schreibt diese in den Controller.

Bei Atmel AVR µCs heisst eine Fuse setzen (programmieren) übrigens, dieses Bit auf Null zu setzen, das wird manchmal gerne falsch verstanden (siehe auch Erklärung in den Forumbeiträgen hier und hier).

Empfehlenswert ist es auch, den AVR Fuse Calculator zu Rate ziehen, um die richtigen Fuse Einstellungen zu finden.

Eine andere Möglichkeit ist die Nutzung der unter http://www.nongnu.org/avr-libc/user-manual/group__avr__fuse.html beschriebenen Funktionen.

Kompatibilitätsfuses und manchmal lästige Defaults

Einige Prozessoren haben eine Werkseinstellung, die zu Problemen führen kann. Wenn der Prozessor JTAG unterstützt (ab Mega16 aufwärts), so ist ab Werk die JTAG Schnittstelle eingeschaltet, was dazu führt, daß einige Portpins nicht wie gewohnt funktionieren (nämlich die an denen das JTAG Interface herausgeführt wird). In so einem Fall ist es das Beste, die entsprechende Fuse JTAGEN umzusetzen, um so das JTAG Interface abzuschalten, wenn es nicht gebraucht wird.

Auf einem Mega128 ist ab Werk immer die sog. M103 Kompatibiliätsfuse gesetzt. Diese Fuse muß unbedingt abgeschaltet werden, ansonsten verhält sich der Prozessor wie ein Mega103 mit völlig anderer Speicherbelegung. Wird in so einen Prozessor ein für den Mega128 programmiertes Programm geladen, so stürzt das Programm beim ersten Unterprogrammaufruf ab, weil der Stack an einer falschen Stelle sitzt.

SPIEN, DWEN und RSTDISBL

Für Anfänger gilt der gut gemeinte Ratschlag: Finger weg von SPIEN, RSTDISBL und DWEN!

Besonders "heimtückisch" ist die auf einigen AVR (Tiny12,13 Tiny26, Mega8 .?.) vorhandene Möglichkeit, den Resetpin zum I/O-Pin zu machen. Wird RSTDISBL programmiert, hat man mit seriellen ISP-Programmieradaptern keinen Zugriff mehr. Man sollte diese Option daher nur nutzen, wenn der zusätzliche I/O-Pin wirklich benötigt wird und der Zugriff auf den µC durch einen funktionierenden Bootloader gesichert ist oder man einen AVR HV-Programmer zur Hand hat. Rücksetzen kann man diese Fuse allerdings nur mehr mit einem HV-Programmer, ein Bootloader kann prinzipiell keine Fuses ändern.

Die Fuse SPIEN für serielles "low voltage" ISP kann per ISP nicht verändert werden. Hat man SPIEN per JTAG oder High-Voltage-Programming deaktiviert, sollte man wieder den Ursprungszustand herstellen, falls der Controller danach wieder per ISP programmiert werden soll.

Auch DWEN bietet bei modernen AVR-Controllern (z. B. ATmega48, 88, 168, einigen ATtiny) die Möglichkeit sich "auszusperren". Wenn die debugWIRE-Schnittstelle aktiviert ist, ist keine "low voltage" ISP-Programmierung mehr möglich. debugWIRE kann nur über die debugWIRE-Schnittstelle (JTAGICE MKII oder AVR Dragon) oder High-Voltage-Programming deaktiviert werden.

Siehe auch:

Taktquellen Fuse Einstellung

Tabelle aus einem AVR-Datenblatt (Beispiel)
Device Clocking Options Select CKSEL3..0
External Crystal/Ceramic Resonator 1111 - 1010
External Low-frequency Crystal 1001
External RC Oscillator 1000 - 0101
Calibrated Internal RC Oscillator 0100 - 0001
External Clock 0000

Neben dem Abschalten des Resetpins kann man sich allerdings noch durch ungeschicktes Setzen der Taktquelle aus dem Controller aussperren. Dies ist die häufigste Variante, mit der sich Neulinge aus einem AVR aussperren. Dabei wird irrtümlich anstelle eines externen Quarzes ein externer Quarzoszillator (Taktquelle, external Clock) mithilfe der Fusebits eingestellt. Beide Varianten benötigen aber eine unterschiedliche Anpassungschaltung innerhalb des Mikrocontrollers. Mit der Folge, dass ein externer Quarz bei Aktivierung Anpassungsschaltung für einen Quarzoszillator (oder generell für einen externen Takt) einfach nicht mehr anschwingt. Der Mikrocontroller hat somit keine Taktquelle und arbeitet nicht mehr.

Für einen externen Quarz ist die Einstellung External Crystal/Ceramic Resonator notwendig, also eine Einstellung von 1111. Unglücklicherweise ist bei den vielen Fusebit Einstellprogrammen nicht auf den ersten Blick offensichtlich, ob ein gesetztes Häkchen nun eine 1 oder eine 0 bedeutet. Anstatt auf 1111 werden die Fusebits auf 0000 gesetzt und damit ein External Clock eingestellt. Ein External Clock ist aber ein Quarzoszillator. Ein Quarz wird an so einer Einstellung nicht ins Schwingen kommen.

Zum Anschluss von Taktquellen siehe auch:

Reaktivieren bei fehlerhaften Taktquellen-Fuse-Einstellungen

Retten kann man einen AVR bei jeder falschen Taktquellen-Fuseeinstellung (Clock statt Quarz etc.), indem man an XTAL1 einen Takt anlegt. Falls ein weiterer AVR zur Verfügung steht, einfach einen Pin als Ausgang schalten und in einer Endlosschleife auf high/low setzen. Jede andere Art Frequenzgenerator funktioniert auch, am einfachsten ein Quarzoszillator - die Teile mit 4 Beinchen, oder falls ohnehin ein Oszilloskop am Arbeitsplatz steht, dessen Rechtecksignal zum Abgleichen der Tastköpfe. Die Frequenz ist dabei eher unkritisch (<16 bzw. 20 MHz). Wichtig ist dabei die ISP-Frequenz, welche kleiner als 1/4 des CPU Taktes sein muss! Den Ausgang des Generators an XTAL1 des "verfusten" AVR anschliessen, eventuell die im Aufbau noch vorhandene Taktquelle (z. B. Quarz) sicherheitshalber abklemmen. Dann per ISP auf richtige Taktquelle einstellen. Alle GND-Anschlüsse bei allen genutzten Teilen verbinden, ebenso VCC für die gesamte Schaltung am Besten aus einer Quelle. 100nF als Entkoppelkondensator am AVR nicht vergessen, wenn es mal schnell auf einem Steckbrett passieren soll! Alle SEL und SUT-Fuses auf "1" dürfte bei Verwendung eines Quarzes erstmal weiterhelfen. Die Reset-Disable-Fuse und Debugwire-Enable-Fuse kann mit dieser Methode nicht zurückgesetzt werden.

Die CKDIV8-Fuse ist im Auslieferungszustand "programmed"=0, hat also ein Häkchen in PonyProg. Das bedeutet, dass die Quarzfrequenz intern durch 8 geteilt wird. D.h. man kann einen neuen AVR mit theoretisch maximal 250 kHz ISP-Takt programmieren. Praktisch sollte man maximal 125 kHz nutzen, denn durch Toleranzen kann der interne RC-Oszillator auch mal mit 900 kHz laufen, dann geht es mit 250 kHz nicht oder nur sporadisch. Ggf. mit noch niedrigeren Taktraten probieren, wenn das der Programmieradapter erlaubt.

Siehe auch:

Reaktivieren beim CLKPR-Problem (Attiny13)

Beim Attiny13 (und anderen) kann man aus dem Programm heraus die Taktquelle mit dem Vorteilerregister CLKPR heruntersetzen. Beim nächsten ISP-Programmieren kann das zu Problemen führen, wenn das Programm anläuft, die Taktquelle sehr langsam schaltet und dann erst in den ISP-Programmiermodus geschaltet wird. Travel Rec. beschreibt wie man mit einem Pull-Down-Widerstand an RESET Anlaufen des problematischen Programms verhindert [1].

Vergleich der Fuses bei verschiedenen Programmen

Die Darstellung der Fuses in den verschiedenen Bedienprogrammen für ISP Geräte weicht voneinander ab und das kann den Anfänger ganz schön irritieren (mich hat es ;-). Daher hier ein Vergleich ausgelesener Werte bei drei verschiedenen Bedienprogrammen und dem gleichen programmierten AVR (ATmega32 mit externer Clock).

Achtung
Das ist nur ein Beispiel! Schaut euch euer Board an, lest in eurer Dokumentation und übernehmt nicht einfach die angezeigten Beispielwerte!


AVR Studio

Am gelungensten ist wohl die Darstellung in AVR Studio: man klickt vorne an, was man will (Häkchen gesetzt oder nicht) und "hinten" kümmert sich AVR Studio um die Fusebits. Ähnlich komfortabel arbeitet der AVR Fuse Calculator von Mark Hämmerling (s.u.), nur dass man die eingestellten Werte noch von Hand-zu-Fuss in seinen ISP Programmer übertragen muss.


Ponyprog2000

Achtung
Die Abbildung soll nur das grundsätzliche Aussehen der Einstelldialogs zeigen. Es ist keine Empfehlung für irgendeine bestimme Einstellung. Die gewünschte Einstellung muss aus dem Datenblatt ermittelt werden!
Vor dem Einstellen der Wunschkonfiguration muss die vorhandene Einstellung per READ aus dem AVR ausgelesen werden (die neuste Version macht das jetzt automatisch). Macht man das nicht, kann (und wird ([2])) es zur Blockade des AVR kommen.
Weiter ist zu beachten, dass bei PonyProg ein gesetztes Häkchen einer 0 im Datenblatt entspricht!
Bei PonyProg entspricht ein gesetztes Häkchen einer 0 im Datenblatt

CKSEL0-CKSEL3: Sind diese, wie in der Abbildung gezeigt, gesetzt, dann wird bei einem ATMega8/ATMega16 ein externer Takt (Oszillator, sonstiger Taktgeber) benutzt. Für einen Quarz sind im PonyProg die Häkchen bei CKSEL0 - CKSEL3 nicht gesetzt. Für andere Prozessoren im Datenblatt die korrekte Einstellung ermitteln. Im Zweifel gilt immer das Datenblatt.

An dieser Stelle noch mal die Warnung: Die Beschaltung der CKSEL Fuses ist kritisch! Lieber mit dem Datenblatt 3 mal abklären ob die Einstellung stimmt. Dabei aber beachten:

  • Ein Quarz ist kein "external clock". Für einen Quarz wird im Datenblatt die Bezeichnung "crystal oscillator" benutzt.
  • Bei PonyProg wird eine 1 aus dem Datenblatt durch ein nicht gesetztes Häkchen symbolisiert.
  • Vor dem Neusetzen der Fuse-Bits unbedingt vorher die momentane Einstellung vom Chip auslesen lassen! Bei einem nagelneuen Prozessor sind die Fuse Bits so gesetzt, dass er mit dem internen Taktgenerator auf 1Mhz arbeitet. Das Muster der Häkchen mit dem vorgegebenen Muster für diese Einstellung im Datenblatt vergleichen (diese Einstellung ist im Datenblatt als Default markiert) um sicher verstanden zu haben, wie das mit den Häkchen funktioniert. Erst dann die Änderung vornehmen und neu schreiben.
  • Fuse Bits werden immer alle gleichzeitig gelesen und geschrieben! Daher immer vor dem Verändern von Fusebits die momentan im Mikrocontroller gespeicherten Fusebits auslesen - die gewünschten Änderungen durchführen - und erst dann die veränderten Werte zurückschreiben!

Falls man sich doch vertut und dem Prozessor eine falsche Einstellung gegeben hat, dann wird er vom Brennprogramm nicht mehr erkannt, egal welches Programm dies ist. Widerstehen sie aber der Versuchung, dieselbe Einstellung mit einem anderen Prozessor noch einmal zu versuchen. Der ver-fuste Prozessor ist nicht defekt und die falsche Fuse Stellung wird auch mit einem anderen Prozessor nicht funktionieren. Der ver-fuste Prozessor kann wiederbelebt werden!

AVRDUDE

avrdude zeigt den Zustand der Fuses auf dem Terminal

AVRDUDE ist ein Konsolenprogramm und liefert den Zustand der Fuses als HEX-Wert:

avrdude -c PROGRAMMER -P PORT -p DEVICE -n -v

ergibt:

avrdude.exe: Version 5.1
Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/

System wide configuration file is "D:\WINAVR\BIN\avrdude.conf"

Using Port            : com1
Using Programmer      : stk500v2
AVR Part              : ATMEGA32
Chip Erase delay      : 9000 us
PAGEL                 : PD7
BS2                   : PA0
RESET disposition     : dedicated
RETRY pulse           : SCK
serial program mode   : yes
parallel program mode : yes
Timeout               : 200
StabDelay             : 100
CmdexeDelay           : 25
SyncLoops             : 32
ByteDelay             : 0
PollIndex             : 3
PollValue             : 0x53
Memory Detail         :

            Block Poll               Page                       Polled
Memory Type Mode Delay Size  Indx Paged  Size   Size #Pages MinW  MaxW   ReadBack
----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------
eeprom         4    10    64    0 no       1024    4      0  9000  9000 0xff 0xff
flash         33     6    64    0 yes     32768  128    256  4500  4500 0xff 0xff
lfuse          0     0     0    0 no          1    0      0  2000  2000 0x00 0x00
hfuse          0     0     0    0 no          1    0      0  2000  2000 0x00 0x00
lock           0     0     0    0 no          1    0      0  2000  2000 0x00 0x00
signature      0     0     0    0 no          3    0      0     0     0 0x00 0x00
calibration    0     0     0    0 no          1    0      0     0     0 0x00 0x00

Programmer Type : STK500V2
Description     : Atmel STK500 V2
Hardware Version: 15
Firmware Version: 2.10
Topcard         : Unknown
Vtarget         : 0.0 V
Varef           : 5.0 V
Oscillator      : 3.686 MHz
SCK period      : 0.1 us

avrdude.exe: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.00s

avrdude.exe: Device signature = 0x1e9502
avrdude.exe: safemode: lfuse reads as 20
avrdude.exe: safemode: hfuse reads as DB

avrdude.exe: safemode: lfuse reads as 20
avrdude.exe: safemode: hfuse reads as DB
avrdude.exe: safemode: Fuses OK

avrdude.exe done.  Thank you.

Zur Entschlüsselung kann man prima den Online-Rechner AVR Fuse Calculator von Mark Hämmerling nehmen.


Oder man steuert AVRDUDE über ein grafisches User Interface (GUI), z. B. mit dem von Torsten Brischalle in JAVA geschriebenen AVR Burn-O-Mat. Das Programm läuft unter Windows, Linux und anderen Betriebssystemen, für die Java erhältich ist. (Homepage: AVR8 Burn-O-Mat) Auf der Homepage ist auch eine Online-Version, mit der der Hex-Code der Fuses berechnet und die Kommandozeilenparameter für AVRDUDE ausgegeben werden können.

Mittels der Kommandozeile kann man avrdude wie folgt verwenden um die Fuses zu schreiben:

avrdude -c PROGRAMMER -P PORT -p PART -U lfuse:w:0xFF:m -U hfuse:w:0xD9:m

Entsprechend lassen sich die Fuses auslesen und binär direkt auf der Konsole ausgeben (- als Dateiname gibt die Ausgabe auf der Konsole statt in einer Datei aus):

avrdude -c PROGRAMMER -P PORT -p PART -n -U lfuse:r:-:b -U hfuse:r:-:b


Tipps + Tricks

  • Für Android gibt es den AVR Fuse Calculator der ebenfalls die Fuses nach eigenen Vorgaben berechnet.