AVR Fuse Bits Explained

Every AVR microcontroller, from the ATtiny in your thermostat to the ATMega in your Arduino, stores its configuration in a series of fuse bits. These fuse bits control settings such as the multiplier of the internal oscillator (and thus the speed of the chip), or if the reset pin can be used as a GPIO pin. [YS] just put up an awesome tutorial for understanding these fuse/lock bits, and it’s just the reference guide you’ll need when you find your AVR is running 8 times slower than you would like.

As an example, [YS] uses the ATMega48 default settings. From the factory, the ‘Mega48 ships with it’s fuse bits set to use an 8MHz internal RC oscillator with the CKDIV8 bit set. This results in the chip operating at 1MHz, a bit slow for [YS]’ liking.

By looking at the datasheet for the ATMega48, [YS] found the CKDIV8 fuse was the 7th bit in the low fuse byte. From the factory, the default value for this byte is 0b01100010. To remove the ‘divide clock by 8’ bit, [YS] needed to change the low byte to 0b11100010, or 0xE2. This is done via AVRdude by appending lfuse:w:0xE2:m to the commands entered when programming.

Fuse bits don’t need to be scary. As long as you can convert between binary and hex, can remember there are 7 bits in a byte (remember to start counting from 0), and have access to an easy to use fuse calculator, it’s possible to change all the settings on any AVR you have on hand.


	            

50 thoughts on “AVR Fuse Bits Explained

      1. Whether you count from zero to seven or from one to eight, you’re still counting eight distinct things, so either way it’s still blatantly incorrect to say there are seven bits in a byte.

    1. There’s a pedagogical value of saying there are 7 bits in a byte.

      Since the fuse bits are labelled from 0 to 7 in the documentation, saying ‘7 bits in a byte’ is enough to jog your mind into saying, ‘wait, wut?’ and (hopefully) coming to the conclusion of ‘oh, yeah. the zeroth bit.’

      That, and I relish drawing the ire of HaD commentors.

      1. I am sure there is pedalogic value to much of what we hear politicians spouting as well… Doesn’t make it correct.

        Admit you made a mistake and move on. You do realize your human, and hence subject to mistakes don’t you?

      2. “There’s a pedagogical value of saying there are 7 bits in a byte.”

        That’s as ludicrous and incorrect as if Mike Szczys said “There’s a pedagogical value of my spelling and grammar errors in every single post I write. The incorrect writing forces the reader to think about what I was really trying to say”.

      3. OMG, anyone here should know what Brian meant, why he wrote it that way, that it was obviously intentional, and no one here should think “wait, that is wrong.” I, for one, found it amusing.

        There are 10 kinds of people in the world, those who understand binary, and those who don’t.

      4. Not everyone who reads this site knows about this kind of stuff. One of the basics when learning about binary is 8 bits in a byte, and seeing “There are 7 bits in a byte” is just plain confusing to someone trying to learn.

      5. I would just like to say that when you have an array of 8 elements and call .length() on it you expect 8 not 7. Yet the indexes of said array start at zero in most programming languages and that the last element is located at the seventh index. Therefore it seems to be the global accepted concept that when we quantify elements we distinctively give the total amount, period.

        It goes to say that this applies to bits and bytes as well if we consider a byte a container of bits.

  1. Avr-libc allows to insert the fuses directly in the code, in a clear, intelligible way. For example :


    FUSES =
    {
    .low = (FUSE_CKSEL0 & FUSE_CKSEL1 & FUSE_CKSEL3 & FUSE_SUT0 & FUSE_CKDIV8),
    .high = HFUSE_DEFAULT,
    .extended = EFUSE_DEFAULT,
    };

    I highly recommend it, since the code is written for specific fuses, they are actually part of the code. That way you can also easily add them to version control.

    Then it’s a matter of writing a Makefile to burn those fuses while programming. I don’t have time to write more about this now but I’ll write a tutorial for this later.

  2. ‘7 bits in a byte’ is confusing for someone who is unfamiliar with this topic, but knows very well that there are usually, but not always, 8 bits in a byte. +1 for updating an otherwise excellent starting point for learning more about fuse bits.

  3. Wow… Seriously? If you don’t get such a thing from the extremely well written documentation in any avr datasheet, should you even consider programming avrs ? Maybe such people should stick to some basic-on-a-chip solution.

    1. This comment leaves no room for beginners….evidently you must jump into this hobby with the full understanding of everything you could possibly run into, or be able to understand every bit of documentation written. I have found the documentation starts at a level 3, skipping 0,1,2 and assuming much knowledge I do not possess.

      1. I tend to agree with you. It took me years to get the point where I feel about 92% comfortable reading datasheets. I’m still a little hazy on the various approaches to how ratings are laid out, especially when it comes to the graphs and equations.

        No matter how well written the documentation, people learn differently and any sufficiently complex thing is likely to have dark corners of confusion. Glad to see people help illuminate those for the rest of us ;-)

    1. originally they were implemented as literal fuse whereby you would apply a high enough current to blow the fuse. this would physically prevent the program memory and ram from being read/written externally via the debug interface or what have you.
      Nowadays it is implemented in microcode. Physically they are switches set by the microcode at boot time before control is handed over to the user. This can be (not easily) circumvented by using a very precise power supply and a precise timer to give the uC just enough power for just enough time to get it into start init but not pass to user. you can then use jtag to read/write whatever ya want ;)

  4. Oh, something went wrong with my ISP, so I had to live without access to net for two days. But now I gonna answer to you all in a batch mode. :)

    First of all, when something is beyond my understanding, I refer to the official papers. :) Looking at the Atmel’s datasheets, one can clearly see that bits are enumerated starting from zero. As there are eight bits in a byte (nowadays :) ) the last bit has a number seven, hence we can refer to it as to seventh bit, right? :)

    @Treehouse Projects: Wow, that’s really interesting coincidence, as even chapter names are almost the same. But I can see you are focusing mostly on clock system options, while I tried to cover fuse bits topic in general.

    @wowme@wtf.com: Why do you think I didn’t used ATtiny13? :) I’ve made an 1-Wire reader using this MCU (for my studies in university).

    1. or 1000 (binary), or 10 (octal) or 32 (trinary). Simply saying there are 7 bits in a byte is wrong, saying there are “7” bits in a byte (using a 0-based decimal counting system as opposed to 1-based) is correct.

Leave a Reply to chanakalinCancel reply

Please be kind and respectful to help make the comments section excellent. (Comment Policy)

This site uses Akismet to reduce spam. Learn how your comment data is processed.