Atmel chips have present some internal registers that can be used to set up several particular features of the microcontroller, i.e. the options to choose the clock source, to reserve a part of the Flash memory to the bootloader, to activate internal circuits like the WatchDog (WD) or the Brown-out Detector (BOD), to set the behavior of the reset pin and so on. These registers are called Fuses, like the fuses used in electronics, even there’s nothing that is burned inside the memory of the microcontroller: they are so called because they are stored into Flash, a non volatile memory of the chip, so that they don’t loose their value when the micro is powered down. Moreover, user can change them only by using an external programmer so that they cannot be modified by the software of by accidents (to be honest, they should not be..).
Depending of the microcontroller, fuses registers are generally stored into 2 or 3 8-bits memory cells (not al the bits are used) called: Low Fuse, High Fuse, and Extended Fuse. The latter is present only on the most recent MCUs from Atmel. In this article we will take a look at the Atmega328P fuses, but remember that more of the infos that you will read can be applied to other MCUs too.
[notice]IMPORTANT: when you modify the fuses, keep in mind that to activate a certain function you have to clear the corresponding bit (write a “0“, zero, in it), while when you want to deactivate it you have to set that bit (i.e. write a “1“, one, in it).[/notice]
[important]In-depth: this non-logical way of work (we usually intend “1” for “on” and “0” for “off”) has its roots into the internal architecture of the Flash memories: every bit of them is represented by a memory cell built on a MOSFET with 2 gates (instead of 1): the first gate is called Control Gate (CG) and is insulated with 2 layers of silicon oxyde from the underlying drain and source by the second gate, that is called Floating Gate (FG). The FG is a sort of a capacitor, meaning that it is able to maintain an electric charge for a very long time. All the CG of a single word of the Flash memory are connected to the same electrical line. When the FG does not retain an electric charge, the MOSFET doesn’t conduct and the interface reads this state as “1”. When the FG receices an electric charge, the MOSFET starts conducting and the interface reads this state as “0”. To delete a cell a voltage of 12/13V is used to “extract” the charge from the FG, resetting the MOSFET to its clear state (“1”). You can easily understand that the non conductive state of the MOSFET is electrically more stable then the other one; this is the reason why a Flash memory has their bits filled up with “1” after an erase. That’s the “secret” behind the strange logic of this kind of memory.[/important]
Low Fuse
Bit |
Name |
Description |
Default value |
Arduino value |
7 |
CKDIV8 |
Divide clock by 8 |
0 |
0 |
6 |
CKOUT |
Clock output on pin CLKO (on the 328, it’s PB0) |
1 |
0 |
5 |
SUT1 |
Select start-up time |
1 |
0 |
4 |
SUT0 |
Select start-up time |
0 |
0 |
3 |
CKSEL3 |
Select Clock source |
0 |
0 |
2 |
CKSEL2 |
Select Clock source |
0 |
0 |
1 |
CKSEL1 |
Select Clock source |
1 |
0 |
0 |
CKSEL0 |
Select Clock source |
0 |
0 |
Let’s look at the various bits:
- CKDIV8:this bit divides per 8 the signal clock from the selected source. I.e, if we choose the internal oscillator that works at 8 MHz, with this bit set the effective system clock will be 1 MHz (8 MHz / 8 = 1 MHz).
- CKOUT:this bit set if the micro has to present the internal clock on a particular pin. On the Atmega328P, this pin is PB0 (digital pin 8 of the Arduino).
- SUT1..0:these two bits set the start-up time of the microcontroller after a reset or a sleep state (energy saving). When a power souce is provided to an oscillating circuit like the internal oscillator, a certain time and a certain number of oscillations must pass before it is stable enough to be used and the frequency as close as possible to its default value. Moreover, the MCU needs a certain number of clock cycles to wake up all the internal peripherals. The SUT1..0 bits set the time before this cycle can be considered finished (with a delay of a certain number of milliseconds and clock cycles): the longer this time is the slower the process is to be completed. Keep in mind that a longer time ensures more stability for the MCU at the end of the process while shorter times could lead to MCU instability and freezes during the start-up. Default values for SUT1 and SUT0 are “1” e “0”, to give the longer time to the MCU to wake up. If you need quicker wake ups you can try to set 0/1 for SUT1/SUT0 but in this case the MCU could have problems to finish the process. In the last case (bits 0/0 for SUT1/SUT0) you could have a freezed MCU because it could not have the necessary time to start-up correctly. The time set with SUT1..0 is added to the delay set with CKSEL0 bit.
- CKSEL3..0:the CKSEL3..1 bits set the clock source while the CKSEL0 introduces another delay to the time used by the MCU to start choosen by the SUT1..0 bits. You can choose between 8 MHz internal oscillator, 128 kHz internal oscillator (this is used only in particular applications and it is not compatible with the Arduino environment)
Bit
Name
Description
Default value
Arduino value
7
RSTDISBL
Disable External Reset
1
1
6
DWEN
Enable debugWIRE
1
1
5
SPIEN
Enable SPI communications
0
0
4
WDTON
Watchdog Timer Always On
1
1
3
EESAVE
EEPROM memory is preserved through the Chip
Erase
1
1
2
BOOTSZ1
Select Boot Size
0
1
1
BOOTSZ0
Select Boot Size
0
1
0
BOOTRST
Select Reset Vector
1
0
Let’s look at the various bits:
- RSTDISBL:
every microcontroller has a particular pin that doesn’t work as an I/O line but it’s connected to the internal reset circuit. When a LOW signal is applied to it, the microcontrollers resets itself. If you set this bit, the reset circuit will be disconnected and that pin will be used as a normal GPIO (even with an higher internal impedance): this can be useful i.e. when you need another I/O pin on a small MCU (like an ATtiny). Be careful, because as soon as this pin will be set to be a GPIO you won’t be able anymore to reprogram the microcontroller with the usual ways like the ISP programming. To reactivate the reset functionalities you’ll need to use an hardware programmer capable to use high voltage levels (12V) (i.e. AvrDragon).
- DWEN:
this bit sets the debugWIRE serial com, a debug protocol alternative to JTAG, developed by Atmel and supported by several Atmel programmers like AVR Dragon, AVR JTAGICE mkII, AVR JTAGICE 3, and AVR One.
- SPIEN:
the SPIEN bits enables the SPI communication. If you disables it, the microcontroller won’t be able anymore to dialoge with other SPI devices; moreover, you won’t be able to program the MCU anymore using the ISP programming as it uses the SPI serial interface.
- WDTON:
like other microcontrollers, the ATmega328P has an interna WatchDog Timer used to reset the chip. If you enable this circuit, the user must ensure that at regular intervals the code will reset the watchdog timer before it overflows otherwise a reset will occour. This is useful in critical applications where the user cannot be reach the circuit in short times so that a dead-lock condition in the code won’t freeze the CPU. If you disable the Watchdog, you still will be able to enable/disable it through software.; instead, if you set this bit, the watchdog will be permanently enabled.
- EESAVE:
Atmel microcontrollers has 3 different kinds of memory: Flash, SRAM, and EEPROM. The first one contains the user’s code; the second one the variables created by the program; in the third one the user can store datas that should not get lost when the circuit is switched off. Flash and EEPROM are separated memories that can be read/written/erased separately by avrdude (the tool used to program the Atmel microcontrollers). Otherwise, there is a paramether of avrdude (“-e”) that can force a chip erase, leading in the lost of all the datas stored in both the Flash and EEPROM memories. To preserve the EEPROM contents, you can set this bit.
- BOOTSZ1..0:
these bits are used to reserve a part of the Flash memory of the microcontroller to create a protected area for a separated program. Usually, the Flash memory is fully used by the user’s code, that it is started as soon as the microcontroller is powered up. Some applications, like Arduino, use to reserve this part of Flash to store a program called “bootloader”, a little program that is started before the main code: in the case of Arduino bootloader, this program simply checks if the IDE is sending a new sketch through the serial port. If yes, it provides to write the new program into the flash over the old one. After this operation, or if no new sketch is coming, the bootloader passes the control of the CPU to the user’s code. The BOOTSZ1..0 bits are used to create that reserved area, whose size is related to the microcontroller you’re using. For the Atmega328P, the size of the bootloader section can be of 512 (values of “1” and “1” for BOOTSZ1 and BOOTSZ0), 1024 (“1” and “0”), 2048 (“0” and “1”), and 4096 (“0” and “0”) bytes. The Arduino reserves a section of 512 bytes for the UNO boards and an area of 2048 bytes for the old Duemilanove. Pay attenction on the fact that the datasheet refers to sizes in words, not in bytes, because the Flash memory is made of 16 bits wide cells, so to reserve 512 bytes for the UNO bootloader you have to refer to the settings for 256 words.
- BOOTRST:
usually when the microcontrollerstart executing the code, the first location where it look for an executable instruction is the first memory location (exadecimal $0000). This is the default set . When you set this bit the microcontroller will start executing the code located at the first memory location of the reserved area set with BOOTSZ1..0 bits. On the Atmega328P this address is $3F00, $3E00, $3C00, and $3800, respectively for a bootloader section of 512/1024/2048/4096 bytes. Important: this address is also expressed in words, because of the memory that is organized in 16 bits cells, so the address $3F00 correspondes to the 32256th byte because $3F00=16128 words=32256 bytes. In fact, the Atmega328P has 32 kB of Flash memory, or 32768 bytes, so if oyou subtracts the size of the bootloader section used on the Arduino UNO boards, 512 bytes, you get 32256, that is the room available for the users sketches and the address of the first byte of the memory where the bootloader is stored.
Extended Fuse
Bit
Name
Description
Default value
Arduino value
7
Not used
6
Not used
5
Not used
4
Not used
3
Not used
2
BODLEVEL2
Brown-out Detector trigger level
1
1
1
BODLEVEL1
Brown-out Detector trigger level
1
0
0
BODLEVEL0
Brown-out Detector trigger level
1
1
Let’s look at the various bits:
- bit 7..3: not used
- BODLEVEL2..1:this bits enables the so-called Brown-Out Detector (BOD), a circuit that monitors the power supply voltage of the microcontroller. The microcontroller can work in a range of voltage values that, for an Atmega328P, vary from a minimal value of 1.8V to a maximal value of 5.5V. The clock frequency can vary too, from a minimal value of 1 MHz to a maximal value of 20 MHz. Otherwise, not all the combinations of voltage and frequency are valid. In fact, there’s a problem: the stability. The higher the frequency is the higher the voltage must be, otherwise the microcontroller won’t be stable enough to work properly. The datasheet of the microcontroller has some graphics where you can find the correct combinations of voltage and frequency to ensure stability: if the voltage of the power line goes under a specific value, the BOD circuit will reset the MCU and will keep in reset until the voltage won’t go up again. I.e., on the Arduino boards the microcontroller works at 16 MHz. At this clock, the MCU needs to work at least at 4.5V. So, the chip has its BOS set to run at 4.3V. Available BOD levels are 4.3 V (bits “1-0-0” for BODLEVEL2..0), 2.7V (“1-0-1”) and 1.8V (“1-1-0”).
[notice]due to the fact the some bits are not used, their value can float, so after a writing process they can be read as “0” or “1” randomly, getting an error during the verifying process. In this case, please only consider the value of the used bits. I.e., in the case of the extended fuse, only the first 3 bits are used and the suggestion is to set the value of the other ones to “0”. In the case of the Arduino, this fuse has a factory value of $05.[/notice]
- RSTDISBL:
ciao Leonardo,
complimenti per le tante guide.
in merio ai fuses di atmega328, come si fa ad impostarli ???
come si fa ad impostare un clock source di 128KHz?
grazie
Massimo
Con un programmatore esterno ed avrdude, il programma con cui si caricano anche i firmware sul micro da terminale. Alternativamente puoi usare un frontend, ossia un programma che fa da interfaccia grafica ad avrdude. Per compiere l’operazione hai necessità di un programmatore oppure di una scheda Arduino Uno con il firmware ArduinoISP caricato sopra.