Summary of Led Blink Code – Hello World Led using atmega16 in C
This article details the initial configuration and programming of an ATmega16 microcontroller to blink an LED. It covers setting fuse bytes via `avrdude` for specific clock speeds, configuring registers (DDRB, PORTB) in C code, and using Programmer's Notepad with a Makefile to compile and upload the firmware using a USBasp programmer.
Parts used in the AVR Atmega16 LED Blink Project:
- ATmega16 Microcontroller
- USBasp Programmer
- LED
- Computer running Command Prompt
- Programmer's Notepad software
- Mfile for generating Makefiles
Configuring the microcontroller before running it the first time:
Fuse bytes : high and low
Program them once before you start using the micro-controller
Disable JTAG to free up PORTC for normal use
Set the correct clock clock option
With the hardware set up, run in Command Prompt :
For 1MHz internal clock:
vrdude -c usbasp -P usb -p m16 -U hfuse:w:0xd9:m -U lfuse:w:0xe1:m
For 16MHz external crystal:
vrdude -c usbasp -P usb -p m16 -U hfuse:w:0xc9:m -U lfuse:w:0xef:m
Refer to datasheet sections on “System clock and clock options” and
“Memory programming” for other clock options and their settings.
Setting the wrong fuse values may render the uC unusable
How We will Program it:
Blink an LED
– Choose a port and a pin
– In the code
1. Set pin direction to output
2. Set pin output to high
3. Wait for 250ms
4. Set pin output to low
5. Wait for 250ms
6. Go to 2
Relevant registers :
DDR – set pin data direction
PORT – set pin output
PIN – read pin input
Blink.C – Code in C Language:
#include <avr/io.h> // contains definitions for DDRB, PORTB
#include <util/delay.h> // contains the function _delay_ms()
int main(void)
{
DDRB = 0b11111111; // set all pins on PortB to output
while(1)
{
PORTB = 0b00000001; // Set PortB0 output high, others low
_delay_ms(250); // Do nothing for 250 ms
PORTB = 0b00000000; // Set all of them low
_delay_ms(250); // Do nothing for 250 ms
}
return 0;
}
/* DDRB is a 8-bit register which sets direction for each pin in PortB
PORTB decides output for output pins
0b – prefix for binary numbers, 0x – hex, no prefix – decimal
Thus, 15 = 0xf = 0b1111
*/
Compiling and Programming
– Save the code as blink.c in a separate folder (not strictly
necessary, just a good practice)
– Create a makefile using Mfile and save in the same folder
– Open it in Programmer’s Notepad and change:
◦ Line 44: MCU = atmega16
◦ Line 65: F_CPU = 1000000
◦ Line 73: TARGET = blink, Line 83: SRC = $(TARGET).c
◦ Alternatively, TARGET = anything_you_want and SRC =
blink.c
◦ Line 278: AVRDUDE_PROGRAMMER = usbasp
◦ Line 281: AVRDUDE_PORT = usb
– In Programmer’s Notepad, Tools > Make All to compile
– Connect USBasp to computer and ATmega16
– Tools > Program to program ATmega16
for more info visit: Led Blinking Code and AVR basic Tutorial
- How do I disable JTAG to free up PORTC?
You must program the fuse bytes once before starting use. - What command sets the 1MHz internal clock?
Run vrdude -c usbasp -P usb -p m16 -U hfuse:w:0xd9:m -U lfuse:w:0xe1:m. - Which registers control pin direction and output?
DDR sets pin data direction while PORT sets pin output. - Can wrong fuse values damage the microcontroller?
Yes, setting the wrong fuse values may render the uC unusable. - What is the best way to configure the Makefile for compilation?
Change MCU to atmega16, F_CPU to 1000000, and set the programmer to usbasp. - Does the code use binary or decimal numbers?
The code uses the 0b prefix for binary numbers like 0b11111111. - How long does the LED stay on during each cycle?
The LED stays high for 250ms before turning low. - Where can I find more information on clock options?
Refer to datasheet sections on System clock and clock options.

