Skip to content

9. Embedded programming

  • Group assignment: Compare the performance and development workflows for other architectures

  • Individual assignment: Read a microcontroller data sheet. Program your board to do something, with as many different programming languages and programming environments as possible.


A microcontroller is a microprocessor integrated with memory, input/output interfaces, timers, and other peripherals into one chip. Microcontrollers have different sizes of data bus: 4 bit, 8 bit, 16 bit, 32 bit. 8 bit is the most common. Most microcontrolers are CMOS chips (Complementary Metal Oxide Semiconductor).

Architecture features:

Classification According to Memory Architecture

  • Von-Neuman Architecture: program and data are in the same memory, instructions and data are fetched over the same data bus. Two fetches are needed to execute an instruction (one to get the instruction, one to get (or put) the data).

  • Harvard Architecture: program and data are in separate memories, data bus and instruction bus are separate, can be operated at the same time. Next instruction is fetched while current instruction operates on the data bus. This pre-fetching speeds up processing by a factor of two (except when branching).

Classification According to Instruction Set

  • CISC: Complex Instruction Set Computer - often have over 80 instructions in the instruction set.

  • RISC:: Reduced Instruction Set Computer - Fewer instructions, better performance, smaller chip, lower power consumption.

    • SISC: Simple Instruction Set Computing - The SISC extends the concept of RISC architecture to the fullest degree. Basically, the SISC implements a single, yet extremely powerful, instruction. The result is a flexible, low-cost processor that outperforms many designs containing tens of thousands more transistors.

    • ARM: Advanced RISC machine - is a 32-bit reduced instructions set computer (RISC) microcontroller. Memory options

    Memory options

    • EEPROM: Electrically Erasable Programmable Read Only Memory
  • FLASH: a better version of EEPROM, especially for program memory

  • Battery backed-up static RAM: Fast, no limits on the number of rewrites

  • OTP: One Time Programmable - An EPROM without a window for UV erasing

  • Software protection: chip is engineered so that the program in the chip can’t be read. (But ROMed microcontrollers have backdoors (a test mode) so that the manufacturer can read the program to verify that the ROM was programmed properly. The test mode is kept very confidential.)

Some Hardware features

  • Brownout protection: chip automatically resets itself when voltage is back up after a brownout

  • Idle/Halt modes

  • Chip shuts down, conserving power, except for a few basic functions; onboard oscillator, watchdog logic, clock monitor, idle timer.

  • Chip wakes up when reset, interrupted or some other stimulus.

  • Serial ports - both asynchronous and synchronous

  • Onboard analog to digital conversion (ADC)

  • Onboard digital to analog conversion (DAC)

  • Pulse width modulators (PWM) - often used for cheap analog to digital conversion

  • Interrupts

  • Take the place of polling - more efficient - can be triggered by rising, fall, or constant level of an external signal.

  • Maskable interrupts - interrupts can be enabled or disabled.

  • Vectored interrupts - Instead of the interrupt routine polling the possible causes of the interrupt and taking appropriate action, different kinds of interrupts jump to different sections of interrupt code to take immediate action. Some form of arbitration is needed when two interrupts occur at the same time.

Special microcontroller features

  • Watchdog timer - the chip will reset itself after a certain period of time if the watchdog timer itself is not reset by the program - provides a way to recover from (some) endless loops and hardware problems.

  • Digital signal processors -

  • Clock Monitor - shuts chip down if the clock is running too slowly

  • PIC: PIC microcontrollers from Microchip are very popular microcontrollers. PICs are easily programmable cheap microcontrollers. PIC is the name for the Microchip microcontroller (MCU) family, consisting of a microprocessor, I/O ports, timer(s) and other internal, integrated hardware. The main advantages are low external part count, a wide range of chip sizes (from 8-pin-up), great availability of compilers and source code and easy programming. Flash-type devices are reprogrammable in-circuit, while OTP versions are very cheap to use at the final stage. A wide range of simple programmer hardware and software is downloadable from the net.

  • 8051/8052: The 8051 is an 8-bit microcontroller originally developed by Intel in 1980. It is the world’s most popular microcontroller core, made by many independent manufacturers. A typical 8051 contains CPU with a boolean processor, 5 or 6 interrupts, 2 or 3 16-bit timer/counters, programmable full-duplex serial port, 32 I/O lines, RAM and ROM/EPROM in some models.

  • ARM: ARM is the industry’s leading provider of 16/32-bit embedded RISC microprocessor solutions used in embedded applications. The company licenses its high-performance, low- cost, power-efficient RISC processors, peripherals and system-on-chip (SoC) designs to leading international electronics companies. ARM designs CPUs, peripherals and chips which are licensed to semiconductor partners for manufacture, supply, and support, either in SoCs or standard parts. ARM does not manufacture silicon.

  • Atmel microcontrollers: Atmel manufactures three families of microcontrollers: the popular 8051, the AT91 which is an ARM Thumb, and the Atmel AVR 8-bit RISC devices. Flash varieties are available. Wide development tools support is available for the 8051 & AT91; support for the AVR is building.

    • Atmel has several microcontroller families:

      • 89 Series: ATMEL 89 Series Flash Microcontrollers are microcontrollers based on 8051 microcontroller architecture and Flash memory.

      • AVR Series: AVR-Single-Chip-Processors AT90Sxxxx are excellent for homebrewing every kind of processor-driven electronics. AVR controllers have typically few kilobytes of memory (1-8 typically), UART and SPI interface.

      • TinyAVR Series: The tinyAVR? Flash-based microcontroller family is priced at less than a dollar in high volume and offers an unrivaled combination of price, performance, and flexibility. The available memory is typically 1-2 kilobytes.

      • ATMega Series: This is a powerful microcontroller with lots of on-chip memory (16-128 kilobytes). ATmega series controllers typically have JTAG and SPI interfaces.

ATtiny25/V / ATtiny45/V / ATtiny85/V Datasheet summary

The ATtiny25/45/85 is a low-power CMOS 8-bit microcontroller based on the AVR enhanced RISC architecture. By executing powerful instructions in a single clock cycle, the ATtiny25/45/85 achieves throughputs approaching 1 MIPS per MHz allowing the system designer to optimize power consumption versus processing speed.


  • High Performance, Low Power AVR ® 8-Bit Microcontroller
  • Advanced RISC Architecture
  • 120 Powerful Instructions – Most Single Clock Cycle Execution
  • 32 x 8 General Purpose Working Registers
  • Fully Static Operation
  • Non-volatile Program and Data Memories
  • 2/4/8K Bytes of In-System Programmable Program Memory Flash
    • Endurance: 10,000 Write/Erase Cycles
  • 128/256/512 Bytes In-System Programmable EEPROM
    • Endurance: 100,000 Write/Erase Cycles
  • 128/256/512 Bytes Internal SRAM
  • Programming Lock for Self-Programming Flash Program and EEPROM Data Security
  • Peripheral Features
  • 8-bit Timer/Counter with Prescaler and Two PWM Channels
  • 8-bit High-Speed Timer/Counter with Separate Prescaler
    • 2 High-Frequency PWM Outputs with Separate Output Compare Registers
    • Programmable Dead Time Generator
  • USI – Universal Serial Interface with Start Condition Detector
  • 10-bit ADC
    • 4 Single Ended Channels
    • 2 Differential ADC Channel Pairs with Programmable Gain (1x, 20x)
    • Temperature Measurement
  • Programmable Watchdog Timer with Separate On-chip Oscillator
  • On-chip Analog Comparator
  • Special Microcontroller Features
  • debugWIRE On-chip Debug System
  • In-System Programmable via SPI Port
  • External and Internal Interrupt Sources
  • Low Power Idle, ADC Noise Reduction, and Power-down Modes
  • Enhanced Power-on-Reset Circuit
  • Programmable Brown-out Detection Circuit
  • Internal Calibrated Oscillator
  • I/O and Packages
  • Six Programmable I/O Lines
  • 8-pin PDIP, 8-pin SOIC, 20-pad QFN/MLF, and 8-pin TSSOP (only ATtiny45/V)
  • Operating Voltage
  • 1.8 - 5.5V for ATtiny25V/45V/85V
  • 2.7 - 5.5V for ATtiny25/45/85
  • Speed Grade
  • ATtiny25V/45V/85V: 0 – 4 MHz @ 1.8 - 5.5V, 0 - 10 MHz @ 2.7 - 5.5V
  • ATtiny25/45/85: 0 – 10 MHz @ 2.7 - 5.5V, 0 - 20 MHz @ 4.5 - 5.5V
  • Industrial Temperature Range
  • Low Power Consumption
  • Active Mode:
    • 1 MHz, 1.8V: 300 μA
  • Power-down Mode:
    • 0.1 μA at 1.8V


Programming the microcontroller



To program using AVR C language you have to take care of the datasheet pinout.

When I started to learn to program AVR microcontrollers I used the examples what is given by the Fab Academy platform.

That start was without understanding what exactly is going on inside the code.

The next step was to search something about AVR microcontrollers and I found these two great sources:

This is one example of how an AVR C program looks like.

#include <avr/io.h>                  /* Defines pins, ports, etc */
#include <util/delay.h>             /* Functions to waste time */

int main(void) {                   // -------- Inits --------- //

  DDRB = 0b01000000;             /* Data Direction Register B:
                                       writing a one to the bit
                                       enables output. */

    while (1) {                       // ------ Event loop ------ //

        PORTB = 0b0100000;         /* Turn on seventh LED bit/pin in PORTB */
        _delay_ms(1000);            /* wait */
        PORTB = 0b00000000;         /* Turn off all B pins, including LED */
        _delay_ms(1000);            /* wait */

    }                                   /* End event loop */

    return (0);                       /* This line is never reached */


The main thing that you have to know is that working in pure C programming language is that you have to include in your code this:

  1. Headers files that are libraries of a bunch of functions that help us to code in an easy way.

  2. The main function that is compiled and inside this program you may write what you want your program do for you.

  3. Configuring the registers that your program will use, setting up ports as inputs or outputs, counters, PWM or whatever your microcontroller has and you want to use it.

  4. The loop while that it will be executed “forever”. Inside you will put what your chip is gonna do over and over again.

  5. Your microcontroller task.

  6. this line is not necessary for programming the chip strictly talking but is very helpful during the program debugging process. If does exist any error in the code it will not return a zero (0).

Arduino C++

To program using Arduino C++ language you have to take care of the arduino pinout

void setup() {

  pinMode(2, OUTPUT);       //setting Pin 2 LED as output


void loop() {               // ------ Event loop ------ //

  digitalWrite(2, HIGH);    /* Turn on seventh LED bit/pin in PORTB */
  delay(1000);              /* wait */
  digitalWrite(2, LOW);     /*Turn off seventh LED bit/pin in PORTB */
  delay(1000);              /* wait */

}                           /* End event loop */
  1. The Setup loop is where to set up all your inputs an output as you need it. The difference between this way of coding to the AVR C is that just for only specifics task you will need to include Header files.

  2. Here is where you set up your microcontroller pins.

  3. This is the loop function where you will put your microcontroller tasks.

  4. The microcontroller task. The debugging process is a bit different as the AVR C debugging way because it does not have the return line.

The schematic that I have worked with was this.

For more detail go to 7. Electronic design assignment.


Linux Terminal

What need to burn an AVR microcontroller using avrdude?

So, why this is important? Just because it will help you in the debugging process.

PRG            = hello
OBJ            = hello.o
#MCU_TARGET     = at90s2313
#MCU_TARGET     = at90s2333
#MCU_TARGET     = at90s4414
#MCU_TARGET     = at90s4433
#MCU_TARGET     = at90s4434
#MCU_TARGET     = at90s8515
#MCU_TARGET     = at90s8535
#MCU_TARGET     = atmega128
#MCU_TARGET     = atmega1280
#MCU_TARGET     = atmega1281
#MCU_TARGET     = atmega1284p
#MCU_TARGET     = atmega16
#MCU_TARGET     = atmega163
#MCU_TARGET     = atmega164p
#MCU_TARGET     = atmega165
#MCU_TARGET     = atmega165p
#MCU_TARGET     = atmega168
#MCU_TARGET     = atmega169
#MCU_TARGET     = atmega169p
#MCU_TARGET     = atmega2560
#MCU_TARGET     = atmega2561
#MCU_TARGET     = atmega32
#MCU_TARGET     = atmega324p
#MCU_TARGET     = atmega325
#MCU_TARGET     = atmega3250
#MCU_TARGET     = atmega329
#MCU_TARGET     = atmega3290
#MCU_TARGET     = atmega32u4
#MCU_TARGET     = atmega48
#MCU_TARGET     = atmega64
#MCU_TARGET     = atmega640
#MCU_TARGET     = atmega644
#MCU_TARGET     = atmega644p
#MCU_TARGET     = atmega645
#MCU_TARGET     = atmega6450
#MCU_TARGET     = atmega649
#MCU_TARGET     = atmega6490
#MCU_TARGET     = atmega8
#MCU_TARGET     = atmega8515
#MCU_TARGET     = atmega8535
#MCU_TARGET     = atmega88
#MCU_TARGET     = attiny2313
#MCU_TARGET     = attiny24
#MCU_TARGET     = attiny25
#MCU_TARGET     = attiny26
#MCU_TARGET     = attiny261
#MCU_TARGET     = attiny44
MCU_TARGET     = attiny45
#MCU_TARGET     = attiny461
#MCU_TARGET     = attiny84
#MCU_TARGET     = attiny85
#MCU_TARGET     = attiny861
OPTIMIZE       = -O2

DEFS           =
LIBS           =

# You should not have to change anything below here.

CC             = avr-gcc

# Override is only needed by avr-lib build system.

override CFLAGS        = -g -Wall $(OPTIMIZE) -mmcu=$(MCU_TARGET) $(DEFS)
override LDFLAGS       = -Wl,-Map,$(PRG).map

OBJCOPY        = avr-objcopy
OBJDUMP        = avr-objdump

all: $(PRG).elf lst text eeprom

$(PRG).elf: $(OBJ)
        $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^ $(LIBS)

# dependency:
demo.o: demo.c iocompat.h

        rm -rf *.o $(PRG).elf *.eps *.png *.pdf *.bak
        rm -rf *.lst *.map $(EXTRA_CLEAN_FILES)

lst:  $(PRG).lst

%.lst: %.elf
        $(OBJDUMP) -h -S $< > $@

# Rules for building the .text from images

text: hex bin srec

hex:  $(PRG).hex
bin:  $(PRG).bin
srec: $(PRG).srec

%.hex: %.elf
        $(OBJCOPY) -j .text -j .data -O ihex $< $@

%.srec: %.elf
        $(OBJCOPY) -j .text -j .data -O srec $< $@

%.bin: %.elf
        $(OBJCOPY) -j .text -j .data -O binary $< $@

# Rules for building the .eeprom from images

eeprom: ehex ebin esrec

ehex:  $(PRG)_eeprom.hex
ebin:  $(PRG)_eeprom.bin
esrec: $(PRG)_eeprom.srec

%_eeprom.hex: %.elf
        $(OBJCOPY) -j .eeprom --change-section-lma .eeprom=0 -O ihex $< $@ \
        || { echo empty $@ not generated; exit 0; }

%_eeprom.srec: %.elf
        $(OBJCOPY) -j .eeprom --change-section-lma .eeprom=0 -O srec $< $@ \
        || { echo empty $@ not generated; exit 0; }

%_eeprom.bin: %.elf
        $(OBJCOPY) -j .eeprom --change-section-lma .eeprom=0 -O binary $< $@ \
        || { echo empty $@ not generated; exit 0; }

# Everything below here is used by avr-libc's build system and can be ignored
# by the casual user.

FIG2DEV                 = fig2dev
EXTRA_CLEAN_FILES       = *.hex *.bin *.srec

dox: eps png pdf

eps: $(PRG).eps
png: $(PRG).png
pdf: $(PRG).pdf

%.eps: %.fig
        $(FIG2DEV) -L eps $< $@

%.pdf: %.fig
        $(FIG2DEV) -L pdf $< $@

%.png: %.fig
        $(FIG2DEV) -L png $< $@
  1. Create a file named Makefile, without any extension, just Makefile.

  2. Before you execute this file make sure that you are in the terminal in the same directory of the Makefile and the C file is the same name outside the Makefile.

  3. You have to uncomment the MCU of your preference by removing the # that is before the MCU name.

  4. These are all the available output files from the Makefile.

Here I show you the before an after running the command:

Erase previously compiled files

sudo make file clean

Compile a new file.

sudo make hex

sudo avrdude -F -P usb -c usbtiny -p attiny45 -U flash:w:hello.hex


-c usbtiny could be: -c your_programmer.

-p attiny45 could be: -p your_mcu.

finally, -U flash:w:hello.hex could be: -U flash:w:your_file_name.hex

This is the message of a successful program loading.

Commentaries about loading the program using the terminal

The steps I already showed is not the unique way to do it, in other words, there are many Makefiles around there that you could use instead of this.

Eclipse C/C++

Installation and setup of Eclipse (Xubuntu Linux)


-------------- For 64-bit Architecture --------------


-------------- For 32-bit Architecture --------------

Using Eclipse with AVR-Eclipse
  • Step1: File>New>Project

    1. Select C project a press next

    2. Select Empty Project from AVR Cross Target Static Application and press Next.

    3. Uncheck Debug a press Next

    4. Select the board and its Frequency and press finish.

  • Step2: right click on the project New>Source File

    1. Put the name of the source file and press finish

    2. Be careful selecting the source file name and its extension. Recommended main.c

    3. Here is it will appear.

  • Step3: right click on the project preference>AVR>AVRDude and preference>AVR>Target Hardware

    1. Select the programmer

    2. Load the MCU

    3. This kind of message will appears.

  • Step5:

These are the messages of successful compiling and MCU burning.

Alternatives GUI for programming


AVRISP MK II (avrisp2)

The AVRISP MK II is obsolete now so you can get only a copy or buy a new model that is the ATATMEL-ICE.

USBTinyISP based on ATtiny44 (usbtiny)



This is the video demo of the board working

What I learned this week?

I learned about the microcontrollers families, types and how they are divided.

I learned that behind the Arduino IDE runs the avrdude to load the program to the chip.

I learn that there is a way to program an AVR microcontroller using Pickit2.