• UFRJ Nautilus

Programming Microcontrollers in C

Updated: May 7


Microcontrollers (MCUs) are small programmable computers that can interact with the physical world. They are used in all kinds of embedded systems, from rockets to household appliances and we give endless possibilities for our projects.

You should be familiar with the Arduino platform, which saves us all the dirty work of low-level programming and allows us to prototype quickly. But why abandon the simplicity of Arduino and take the trouble to program the MCU directly?

Creating your project directly on the MCU, without the abstraction provided by arduino allows you to use its full capacity and run your code much more efficiently. If you intend to have your project commercially available, forget it, the arduino ecosystem license forces you to make your project open source. And finally, programming your microcontroller natively is a great opportunity to fully understand its operation and architecture, and learn how to work based on your limitations.

Now let's meet the microcontroller that will accompany us in this article!

AVR microcontrollers

In this article we will work with 8-bit microcontrollers from the AVR family (the same as your arduinos!), if you've had experiences with Arduino you already know the possibilities they give us, but it won’t hurt remembering.

In this article we will use ATTiny85, but everything is analogous for other MCUs of the same family. If you have any questions, consult the datasheet.

Architecture of MCUs

The 8-bit AVR microcontrollers are based on the RISC architecture, but we don't really need to know what it means, let's focus on the vital parts, common to all microcontrollers.

  • CPU: Responsible for logical and mathematical operations.

  • Memory: We’ve got two kinds:

  • ROM(Flash): Permanent memory, where our code will be stored.

  • RAM: Temporary memory, stores values necessary to execute the code such as variables and results.

  • Peripherals: These are independent modules within the MCU that perform specific functions, the most useful are:

  • I/O: Through the input and output doors we can interact with the outside world using electrical signals.

  • USART, I2C and SPI: They are serial communication protocols, we can communicate the MCU with a computer, sensors and even another MCU.

  • ADC: The famous "analogRead()" in arduinos. Sensors usually give us analog data (a wide range of values, and not the 0s or 1s we work with in the MCU), using this peripheral we can manipulate these values digitally.


Now let's meet our microcontroller! The ATTINY85 has 8kb of Flash memory and 512 bytes of RAM, it may seem little, but the computer that took man to the moon had 4kb of RAM and 32 kb of ROM. We have 6 digital inputs/outputs, 4 analog inputs (4 ADC channels) and up to 2 PWM outputs. The ATTINY85 is known for its very low consumption and can be powered by a coin cell battery for years.

Programming the AVRs

We will need external hardware to program our microcontroller, an ISP programmer, we will use the popular USBasp and the Atmel Studio IDE.