Playing with the fuses on any Microcontroller has become a task which many people shy away from, arguably with good reason – I have seen many chips rendered useless by making a slight error in fuse byte calculations by accidentally un-setting the ‘ResetDisable’ bit. However, if you are willing to avoid the temptation to ‘try random bits until it works’, configuring the fuses is very straightforward, so here is very short beginners guide noting the key points that you’ll need to get started.
Find the information specific to your chip
The first step is of course to find the datasheet for your chip. Using Atmel AVR micorcontrollers, the datasheets are all on-line, so it’s simple to just look on your IC, find the part model and number eg ‘ATMega 168’ and ask google for the datasheet. Make sure that you have the right datasheet for your part, as, although similar parts do have similar fuse configurations, there are some exceptions, so make sure to double check.
Once you have found the datasheet you are looking for a section on ‘fuse-bits’. On the example datasheet I have found (ATMega168), the information is under the section heading Memory programming > Fuse Bits .
Here there are two important tables which look like this :
There are 3 in total fuse bytes (each has 8 bits), but only two of them are worth changing – these are the High Fuse Byte and the Low Fuse byte. The above table shows the bits within the High Fuse Byte.
Calculating the fuse byte values
Once you have found the meanings of the fuse bits within each byte from the datasheet as outlined above, its time to start calculating a value for each byte. The important rule is :
This is counter intuitive when you consider how registers etc. work, but this is the way fuses work – this tradition dates back to when ‘real’ fuses were used and could be programmed by burning them out.
We can therefore select/de-select the features we want by un-setting/setting bits in the fuse byte. The datasheet offers a description of what each bit does for example bit 4 (WDTON) puts the watchdog timer into the always-on state; it also states what the default settings for each bit are.
So, as an example, if we wanted to leave everything in its default state except for the watchdog timer which we wanted always on, we could configure the fuse as follows:
|On or Off?||1 (Un-Set)||1 (Un-Set)||0 (Set by default)||0 (Set by us)||1 (Un-Set)||1 (Un-Set)||1 (Un-Set)||1 (Un-Set)|
Stringing the bottom row together, we get 1 1 0 0 1 1 1 1. This is the binary representation of the value of our byte. We can then convert this into a decimal value of 207. This is the decimal value of our high fuse. It is however conventional to represent the fuse values in hexadecimal – a base 16 number system. We can write 207 as CF in hexadecimal.
Note: It is conventional to specify a hexadecimal number with the prefix 0x… so 207 would be written 0xCF
You can then set the fuse to this calculated value to configure the micro-controller in the way that you wish. For example, the AVRDude command for setting the high fuse byte to 0xCF would be :
# avrdude -p m168 -U hfuse:w:0xCF:m
The same rules and process applies to setting the other fuses as well.