AVR Microcontroller Fuse Bits Configuration. Creating and Uploading in the Flash Memory of Microcontroller the LED Blinking Program.


In this case we will create simple program in C code and burn it into the memory of the microcontroller. We will write our own program and compile the hex file, using the Atmel Studio as the integrated development platform. We will configure fuse bits and upload hex file into the memory of the AVR ATMega328P microcontroller, using our own programmer and software AVRDUDE.

AVRDUDE ‚Äď is a program for downloading and uploading the on-chip memories of Atmel‚Äôs AVR microcontrollers. It can program the Flash and EEPROM, and where supported by the serial programming protocol, it can program fuse and lock bits.

Step 1: Writing Program and Compile the Hex File, Using the Atmel Studio

If you don’t have Atmel Studio, you should download and install it: https://www.microchip.com/mplab/avr-support/atmel-…

This project will use C, so select the GCC C Executable Project option from the template list to generate a bare-bones executable project.

Next, it is necessary to specify which device the project will be developed for. This project will be developed for the AVR ATMega328P microcontroller.

Type the code of program in the Main Source Editor area of Atmel Studio. The Main Source Editor ‚Äď This window is the main editor for the source files in the current project. The editor has spell check and auto complete features.

1. We must tell compiler at what speed our chip is running to that it can calculate delays properly.

#ifndef F_CPU 
#define F_CPU 16000000UL // telling controller crystal frequency (16 MHz AVR ATMega328P) 

2. We include the preamble, which is where we put our include information from other files, which defines global variables and functions.

#include <avr/io.h> //header to enable data flow control over pins. Defines pins, ports, etc.  
#include <util/delay.h> //header to enable delay function in program

3. After the preamble comes the main() function.

int main(void) {

The main() function is unique and set apart from all other functions. Every C program must have exactly one main() function. Main() is where the AVR starts executing your code when the power first goes on, so it’s the entry point of the program.

4.Set pin 0 of the PORTB as output.

DDRB=0b00000001; //Set PORTB1 as output

We do this by writing a binary number to the Data Direction Register B. The Data Direction Register B allows us to make the bits of register B input or output. Writing a 1 makes them output, while a 0 would make them input. Being that we are attaching an LED to act as output, we write a binary number, making the pin 0 of PORT B as output.

5. Loop.

while (1) {

This statement is a loop, often referred to as the main loop or event loop. This code is always true; therefore, it executes over and over again in an infinite loop. It never ceases. Therefore, LED will be blinking in an infinity, unless power is shut off from the microcontroller or the code is erased from program memory.

6. Turn on LED attached to port PB0

PORTB= 0b00000001; //turns on LED attached to port PB0

This line, gives a 1 to the PB0 of PortB. PORTB is a hardware register on the AVR chip that contains 8 pins, PB7-PB0, going from left to right. Putting a 1 at the end gives a 1 to PB0; this sets PB0 high which turns it on. Therefore, the LED attached to pin PB0 will turn on and light up.

7. Delay

_delay_ms(1000); //creates a 1-second delay

This statement create a 1-second delay, so that the LED turns and stays on for exactly 1 second.

8. Turn off all B pins, including PB0

PORTB= 0b00000000; //Turns off all B pins, including PB0

This line turns off all 8 Port B pins, so that even PB0 is off, so the LED turns off.

9. Another delay

_delay_ms(1000); //creates another 1-second delay

It turns off exactly for 1 second, before starting the loop all over again and encountering the line, which turns it back on, repeating the process all over. This happens infinitely so that the LED constantly blinks on and off.

10. Return statement

  return (0); //this line is never actually reached

The last line of our code is a return(0) statement. Even though this code is never executed, because there is an infinite loop which never ends, for our programs that run on desktop computers, it’s important for the operating system to know whether they ran correctly or not. For that reason, GCC, our compiler, wants every main() to end with a return code. Return codes are needless for AVR code, which runs freestanding of any supporting operating system; nevertheless, the compiler will raise a warning if you don’t end main with return().

The final step is the building the project. It means compiling and finally linking all object files to generate the executable file (.hex) file. This hex file is generated inside the folder Debug which is inside the Project folder. This hex file is ready to be loaded into the microcontroller chip.

Step 2: Changing the Default Configuration of the Micro Controller Fuse Bits

It is important to remember that some of the fuse bits can be used to lock certain aspects of the chip and can potentially brick it (make it unusable).

There are a total of 19 fuse bits that are used in the ATmega328P, and they are separated into three different fuse bytes. Three of the fuse bits are contained in the ‚ÄúExtended Fuse Byte‚ÄĚ, eight are contained in the ‚ÄúFuse High Byte,‚ÄĚ and eight more are contained in the ‚ÄúFuse Low Byte‚ÄĚ. There is also a forth byte that is used to program the lock bits.

Each byte is 8 bits and each bit is a separate setting or flag. When we talk about setting, not setting, programmed, not programmed fuses we are actually using binary. 1 means not set, not programmed and a zero means set, programmed. When programming the fuses you can use binary notation or more commonly hexadecimal notation.

ATmega 328P chips have a built in RC oscillator which has a 8 MHz frequency. New chips are shipped with this set as the clock source and the CKDIV8 fuse active, resulting in a 1 MHz system clock. The startup time is set to maximum and time-out period enabled.

New ATMega 328P chips generally have the following fuse settings:

Low fuse = 0x62 (0b01100010)

High fuse = 0xD9 (0b11011001)

Extended fuse = 0xFF (0b11111111)

We will be use ATmega 328 chip with an external 16MHz crystal. Therefore, we need to program bits of ‚ÄúFuse Low Byte‚ÄĚ accordingly.

1. Bits 3-0 control the oscillator choice, and the default setting of 0010 is to use the calibrated internal RC oscillator, which we don’t want. We want the low power crystal oscillator operation from 8.0 to 16.0 MHz, so bits 3-1 (CKSEL[3:1]) should be set to 111.

2.Bits 5 and 4 control the startup time, and the default setting of 10 is for a startup delay of six clock cycles from power-down and power-save, plus an additional startup delay of 14 clock cycles plus 65 milliseconds from reset.

To be on the safe side for a low power crystal oscillator, we want the maximum delay possible of 16,000 clock cycles from power-down and power-save, so SUT[1] should be set to 1, plus an additional startup delay of 14 clock cycles plus 65 milliseconds from reset, so SUT[0] should be set to 1. In addition, CKSEL[0] should be set to 1.

3. Bit 6 controls the clock output to PORTB0, which we don’t care about. So, bit 6 can be left set to 1.

4. Bit 7 controls the divide-by-8 operation and the default setting of 0 has the feature enabled, which we don’t want. So, bit 7 needs to be changed from 0 to 1.

Therefore, the new Fuse Low Byte should be 11111111 which, in hexadecimal notation, is 0xFF.

To program bits of the ‚ÄúFuse Low Byte‚ÄĚ we can use our programmer (https://www.instructables.com/id/ISP-Programmer-fo‚Ķ) and software¬†AVRDUDE. AVRDUDE is a command-line utility that is used to download from and upload to Atmel microcontrollers.

Download AVRDUDE: http://download.savannah.gnu.org/releases/avrdude/…

First, we must add describe our programmer to the configuration file of AVRDUDE. On Windows the configuration file is usally in the same location as the executable file of AVRDUDE.

Past–Ķ the text in configuration file¬†avrdude.conf:

# ISPProgv1
  id    = " ISPProgv1";
  desc  = "serial port banging, reset=dtr sck=rts mosi=txd miso=cts";
  type  = "serbb";
  connection_type = serial;
  reset = 4;
  sck   = 7;
  mosi  = 3;
  miso  = 8;

Before starting the AVRDUDE, we must connect the microcontroller to the programmer, according to the scheme.

Open DOS prompt window.

1. To view the list of programmer that avrdude is supported type command¬†avrdude -c c. If all is well, the list should have programmer¬†id ‚ÄúISPProgv1‚ÄĚ

2. To view the list of Atmel devices that avrdude is supported type command avrdude -c ISPProgv1. The list should have device m328p for Atmel ATMega 328P.

Next, type¬†avrdude -c ISPProgv1 ‚Äďp m328p,the command tell avrdude what programmer is being used and what Atmel microcontroller is attached. It presents the ATmega328P signature in hexadecimal notation: 0x1e950f. It presents the fuse bit programming currently in the ATmega328P also in hexadecimal notation; in this case, fuse bytes are programmed per factory default.

Next, type¬†avrdude -c ISPProgv1 ‚Äďp m328p ‚ÄďU lfuse:w:0xFF:m, It is a command to tell avrdude what programmer is being used and what Atmel microcontroller is attached and to change the Fuse Low Byte to¬†0xFF.

Now the clock signal should come from low power crystal oscillator.

Step 3: Burning the Program Into the Memory of the ATMega328P Microcontroller

First, copy the hex file of program we made at the beginning of the instruction in to AVRDUDE directory.

Then, type in DOS prompt window the command¬†avrdude ‚Äďc ISPProgv1 ‚Äďp m328p ‚Äďu ‚ÄďU flash:w:[name of your hex file]

The command writes hex file to the microcontroller’s memory. Now, the microcontroller works in accordance with the instructions of our program. Let’s check it out!

Step 4: Check Microcontroller Works in Accordance With the Instructions of Our Program

Connect components in accordance with schematic diagram of the AVR Blinking LED Circuit.

First, we need power, as all AVR circuits do. About 5 volts of power is sufficient for operation of the AVR chip. You can get this either from batteries or a DC power supply. We connect +5V of power to pin 7 and connect pin 8 to ground on the breadboard. In between both pins, we place a 0.1őľF ceramic capacitor to smooth out the power of the power supply so that the AVR chip gets a smooth power line.

The 10Kő© resistor is used to provide Power On Reset (POR) to the device. When the power is switched ON, voltage across capacitor will be zero so the device resets (since reset is active low), then the capacitor charges to VCC and the reset will be disabled.

We connect the anode of our LED to AVR pin PB0. This is pin 14 of the ATMega328P. Since it is an LED, we want to limit current flowing to the LED so it doesn‚Äôt burn out. This is why we place a 330ő© resistor in series with the LED. The cathode of the LED gets connected to ground.

16 MHz crystal is used to provide clock for the Atmega328 microcontroller and 22pF capacitors are used to stabilize the operation of crystal.

These are all the connections necessary to light up the LED. Power supply.

Ok. LED is blinking with one-second delay. The work of the microcontroller corresponds to our tasks.

Step 5: Conclusion

Admittedly, that was a long process for just flashing an LED, but the truth is that you have successfully cleared major hurdles: creating a hardware platform for programming an AVR microcontroller, Using the Atmel Studio as the integrated development platform, using AVRDUDE as software for configuring and programming an AVR microcontroller.

If you want to keep up to date on my base microcontrollers projects, subscribe to my YouTube! Watching and sharing my videos is way to support what I do.

Source: AVR Microcontroller Fuse Bits Configuration. Creating and Uploading in the Flash Memory of Microcontroller the LED Blinking Program.

About The Author

Muhammad Bilal

I am a highly skilled and motivated individual with a Master's degree in Computer Science. I have extensive experience in technical writing and a deep understanding of SEO practices.

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top