Professional Documents
Culture Documents
Fuses Avr and Lock
Fuses Avr and Lock
Himanshu Choudhary
Lock bits are set of bits to enable or disable some special security features of a microcontroller.
For example, in some cases you might want to disable the memory read functionality of the
microcontroller, so that the code you have written cannot be stolen by others. The number of
lock bits and their functionality is always given in the datasheet. The controller used here has
three lock bits which can be set or reset depending on the feature.
The reader should know the basics of sending and receiving the single byte in programming
mode. Refer to 8051 Programmer basicsbefore reading this tutorial.
There are 3 lock bits in the controller 89S51 named as LB1, LB2 and LB3 respectively. The
values of each of the lock bit can be either 0 or 1. If it is 0, it is said to be unprogrammed (U)
and if it is 1, it is said to be programmed (P). The following table shows the results of
programming and unprogramming the different lock bits.
ProgramLock Bits
Protection Type
LB1 LB2 LB3
1 U U U No program lock features
MOVC instructions executed from external program
memory are disabled fromfetching code bytes from
internal memory, EA is sampled and latched on reset,
2 P U U and further programming of the Flash memory is
disabled
3 P P U Same asmode 2, but verify is also disabled
Same asmode 3, but external execution isalso
4 P P P
disabled
When the lock bit 1 is programmed the memory reading feature of the controller is
disabled, i.e., the memory cannot be read. In case an attempt is made to read the
memory after setting the lock bit 1, the buffer will always show the value FF in every
memory location. However the microcontroller will carry out its normal operations.
Written By:
Himanshu Choudhary
The table above shows the instruction corresponding to setting the lock bits. We can either write
the lock bits or read the status of lock bits. Reading lock bits is quite simple you have to send
the instruction corresponding to the reading lock bit and the fourth byte gives the status of lock
bits.
Setting the lock bit is bit tricky. The two bits B1 and B2 in the second byte of the instruction
corresponding to write lock bit are used to program or unprogram the lock bits B1 B2 B3.
The above block shows the bit pattern to program or unprogram the lock bits. The important
thing to note here is that at one point of time only one lock bit can be programmed. Also the
programming needs to be done sequentially i.e., in order to program the lock bit 3, the lock bit 1
and 2 must be programmed first and hence instruction corresponding to mode1, mode 2 and
mode 3 needs to be sent before mode 4.
The low byte fuse deals with the clock source, how fast the chip will
run, and how long it waits at startup. 1 byte equals 8 bits. So there are
8 bits in the low fuse byte. These 8 bits are explained here:
Now we are left with two more bits to set : CKOUT and CKDIV8. I
don't need any clock pulse output on PB0. So I will set this to 1
(unprogrammed).
Now combining all the 8 bits, ourrequired low fuse byte is 11100010.
High byte Fuses
The high byte fuse is explained below. You can simply skip this part.
Here I have only explained the high fuse bits. We don't need to
change the high fuse bits in order to change the clock source and
operating frequency. But if your are interested to know about the high
byte fuses then go through the below paragraph.
There are 8 bits in the high byte fuse also. These are:
PC6 of Atmega328 is a reset pin, hold it low (to ground) and the chip
will reset. This is how the switch on the Arduino works. When you
press the reset button it connects PC6 to ground and resets the chip.
PC6 can also be used as a regular IO pin but this means disabling the
reset function which in turns means the chip can no longer be inline
programmed (in line programming requires a reset). This is one of the
options it is better not to change. I imagine RSTDISBL is implemented
for security reasons to stop the chip being reprogrammed or the
firmware being downloaded. When RSTDISBL is programmed the
start up time (SUT1 SUT0) is increased to 14CK + 4.1ms to ensure
the programming mode can be entered.
By default, the setting is RSTDISBL = 1 (unprogrammed).
This is one of the fuses you should take care with. If you enable
DWEN and also enable the lock bits you can no longer program the
chip in the normal way.
The watchdog is basically a timer that will cause the chip to reset if it
does not receive an OK signal at specific times. This can be useful
when you have unstable code or have a system that must not be
allowed to permanently lock up. When the watchdog timer is enabled,
should a sketch crash or freeze then the timer will time out and reset
the chip causing a restart similar to pressing the reset button an a
running Arduino. The Watchdog Timer can be activated in software so
the fuse settings doesn’t really need to be used. By default, the
watchdog timer is off, WDTON = 1 (unprogrammed).
The ATmega chips have the ability to use a boot loader, this is a small
program that runs when the chip is first started or when it is reset.
Boot loaders are normally used to initialize the device and check for
external communication. The Arduino uses a boot loader to talk to a
connected computer to see if there is a new program to be uploaded.
This is the reason the Arduino resets when you upload new code, the
reset runs the boot loader, the boot loader checks to see if you have
new code.
The boot loader is stored in program memory, the same memory used
for the user application and since the boot loader can be different
sizes you can tell the ATmega chip how much space to reserve. The
regular (older) Arduino boot loader is 2 kilobytes (KB) but the newer
Optiboot (used on the UNO) is only 0.5KB (512 bytes). If using
Optiboot and setting the boot loader size accordingly you gain an
extra 1.5KB for your own program. 1.5KB can be a lot of space,
running out of program space is why I started programming stand
alone ATmega chips in the first place. The code for the drop Controller
became too large for the regular Arduino so I removed the boot
loader.
If you have a boot loader then BOOTSZ has to be used in conjunction
with BOOTRST. BOOTRST tells the ATmega chip the memory
address where the boot loader starts. If BOOTRST is not set then the
user application can use the whole of the memory regardless of the
BOOTSZ settings.
ATmega chips can use a boot loader, this is a small program that runs
when the chip is reset. If you have a boot loader then you need to
inform the MCU and this is done by using the BOOTRST fuse setting.
When the BOOTRST Fuse is set, on reset the device will jump to the
Bootloader address. If not set, the chip will jump to the program start
address at 0x0000.
If BOOTRST is not set (no bootloader) then the BOOTSZ fuses are
not used regardless of the value.
The extended fuses are only used to set the brown-out detection level
(BOD). The ATmega chips can become unstable or unreliable when
used with insufficient voltage. For example, the Atmega328/328P can
run safely at 16 MHz if it has at least 4 V supply. Anything below 4V
means the chip is likely to misbehave. This would be a problem if the
device were being used with sensors to take measurements or relied
on accurate timings.
I am not going through each bits of extended fuse byte. By default all
the bits in this byte is set as 1 (unprogrammed).
Okay so now we are familiar with the fuses and already calculated the
fuse bits.
Low byte fuse (lfuse) : 0b11100010
High byte fuse (hfuse) : 0b11011001
Extended fuse (efuse) : 0b11111111
Now you can simply write these in binary or you may convert these to
Hexadecimal. I am going to convert these to hex because I usually
make mistake in typing 0 and 1 repeatedly any you know how much
important these are. If you set wrong fuse bits then you may probably
brick the chip.
lfuse : 0xE2
hfuse : 0xD9
efuse : 0xFF
If you find that calculating fuse from the datasheet is difficult then here
is a fuse calculator. However, changing fuse without having
knowledge in this subject is not recommended.