Step 3Reading and Writing Fuses
In a previous instructable, I demonstrated how you can read and set your fuses using your programmer and avrdude. Here, I'll show you how to read back your fuses at run time to see how your MCU has actually set them. Note, that this isn't the compile-time setting that you get from the definitions in <avr/io*.h> but the actual fuses as the MCU reads them at run time.
From Table 27-9 in the ATmega328P datasheet (databook, more like it) the bits of the Fuse Low Byte are as follows:
CKDIV8 CKOUT SUT1 SUT0 CKSEL3 CKSEL2 CKSEL1 CKSEL0An interesting thing to note is that with fuses, 0 means programmed and a 1 means that that particular bit is unprogrammed. Somewhat counter-intuitive, but once you know it you know it.
- CKDIV8 sets your CPU clock to be divided by 8. The ATmega328P comes from the factory programmed to use its internal oscillator at 8MHz with CKDIV8 programmed (ie set to 0) giving you a final F_CPU or CPU frequency of 1MHz. On Arduino's, this is changed since they are configured to use an external oscillator at 16MHz.
- CKOUT when programmed will output your CPU clock on PB0, which is digital pin 8 on Arduinos.
- SUT[1..0] specifies the startup time for your AVR.
- CKSEL[3..0] sets the clock source, such as the internal RC oscillator, external oscillator, etc.
root@ATmega328p> read lfuseLower Fuse: 0xffSo, all bits are set to 1. I did the same procedure on an Arduino clone and got the same value. Checking one of my stand-alone AVR systems, I got 0xDA which is the value I had set some time back when configuring the chip.
The same procedure is used for checking the High Fuse Byte, Extended Fuse Byte, and Lock fuses. The calibration and signature fuse bytes have been disabled in the code with an #if 0 preprocessor directive, which you can change if you feel scrappy.
| « Previous Step | Download PDFView All Steps | Next Step » |
![]() |
Add Comment
|











































