How to Program an ARM-Based Microcontroller
What is the best programming language?
That’s a trick question and I won’t bother to answer it. That question might be fine in the desktop realm, but it becomes irrelevant when you leave that domain. First, let’s discuss the difference between programming for personal computers and programming for embedded systems.
When you program for personal computers the more important question becomes “what am I programming”. Will the application be used from a command line, or will it have a graphical user interface? Based on that, you pick a Software Development Kit (SDK) and get to work. I have obviously over-simplified the process. If you don’t know the language or languages supported by the SDK then you will need to learn that. There is also a lot of reading of the documentation, utilization of search engines, and something new called stack overflow.
The main thing to note, when it comes to programming for personal computers, is that you program on the same device that the application will run on. Your input and output devices are normally right there for you to test with.
Your input devices are usually a keyboard and a mouse (or trackpad). Your output devices are usually a screen (monitor) and speakers. You could have other input and output devices, but you don’t typically worry about how they work. That level of detail is abstracted away by the operating system on the computer and the device drives for the devices.
When you program for a mobile device, the process changes a little. Now, even the choice of the SDK is limited. The SDK also limits the languages you are able to use. While there have been tremendous efforts to allow for React-Native and the like, I will acknowledge their existence without going into the details.
When you program for mobile devices, you write the code on a personal computer but compile it for the target mobile device platform. The mobile device has its input and output devices on it, but you have to deploy your application onto the target device before you can utilize those.
Some SDKs will give you an emulator so you can test your application functionality, but the ultimate test lies in deploying the application onto the target device.
The primary input device on a mobile device tends to be the touch screen (most modern smart devices do not have a number pad or a keyboard). You might find physical buttons for adjusting the volume on the device, but that implementation is usually at the level of the operating system (OS). The output on those devices includes the screen, the speakers, and sometimes haptic or vibratory feedback.
Programming microcontrollers (MCUs) is similar to programming mobile devices. However all of your inputs and outputs are via general-purpose input-output (GPIO pins). Also, there is no operating system (in most cases), so you will need to deal with the bare metal yourself.
You will be responsible for making all of the choices yourself. For example, if you would like an output that a human can understand, you could blink a light emitting diode (LED) or output text to a screen. However, all of these are just connections to one or more GPIO pins, so you need to know the pin that you are “writing” to. If you would like a screen as part of your deployment then you need to know what communication protocol the screen expects.
In summary, you will write the program on a PC, compile it on the PC, and then deploy it to the target MCU.
In the next section, we will discuss what you need to do to get started.
It’s important to get a high-level overview of the things that need to come together in order for you to successfully program an MCU. A list might look like the following:
Choose a development board
Choose an SDK (if there is more than one)
Master the language of the SDK
Learn the electronics
Development boards make it easy for you to do your prototyping on the microprocessor that you are interested in. We discussed the various Cortex-M microprocessors in an earlier article. If all you want to do is get started, then an MCU built on a Cortex-M0+ microprocessor could be a good place to start. You could go with a Raspberry Pi Pico or an Arduino Nano RP2040 connect.
It is important to note that you can’t upgrade an MCU after you have purchased it, so be sure to go for the largest spec that you can afford for development purposes. When going into production you can always get something smaller.
It is impossible to overempasize the need to read all of the available documentation for any board that you would like to go with. You should start by reading the specification sheet. This will give you a general idea of what the board can do.
While every board can be programmed using C/C++, some boards offer additional language support. If this is important to you, then pay attention at this point.
Software Development Kits (SDK)
The choice of the SDK can make a difference between an experience that is pleasant and one that isn’t.
Arduino boards are made by the company of the same name. The company provides and SDK for programming its boards. However, this SDK can be used for programming some other boards that aren’t manufactured by Arduino. This makes it easy for anyone who started programming with Arduino to cross over to some other boards.
The original set of boards designed by Arduino were not Arm-based. However, they recently started designing some Arm-based boards, such as the following:
Arduino Nano RP2040 Connect
Arduino Nano 33 BLE
Arduino Nano 33 BLE Sense
Arduino Nicla Sense
The Arduino SDK also provides support for boards from other manufacturers, such as:
Raspberry Pi Pico
Most SDKs for embedded development will give you the choice of only one language, but some boards will give you the choice of multiple SDKs.
The Sparkfun Edge development board gives you a choice of two SDK: Arduino and Ambiq SDK. However, both of those are C-based.
The Raspberry Pi Pico development board gives you the choice of two SDK: Arduino (C language) and Thonny (Python language).
It is important to note here that the Sparkfun Edge and the Raspberry Pi Pico are not the same. The former features a Cortex-M4F microprocessor while the latter features a Cortex-M0+ processor. If you wanted a similar board to the Sparkfun Edge with Python support, you would look at the Arduino Nano 33 BLE or the Arduino Nano 33 BLE Sense.
The board and SDK that you settle upon will limit your choice of programming languages. However, a choice of what those languages are could help you with making a board selection. You should pay attention to whether the board you pick is professional or hobbyist. For the choice of languages, you should be aware of the following:
MicroPython and CircuitPython
When you first start programming you get introduced to “Hello World”, which in C prints out the words to your console. The code looks similar to the following.
On an MCU that console or command line doesn’t exits. Instead, you will be dealing with GPIO pins. On most development boards an LED would have been attached to one of those pins. The “Hello World” of microcontrollers is called blinky and as you might have guessed, the task involves blinking the LED.
The code for blinky on Arduino looks similar to the following, in which the main function is missing, but that isn’t a mistake. That is how Arduino is implemented.
The code for blinky in MicroPython looks like the following and does exactly the same thing that the Arduino code does.
The code for an MCU gets compiled into a binary and flashed onto memory. Exactly how that happens in dependent on the board and the SDK, so I won’t go into that here. Regardless of your choice of SDK and language, you should get familiar with the documentation.
Arduino language reference.
Embedded Java details.
Now that you are familiar with the language for programming the board, you should get familiar with the electronics side of embedded programming. There are two components to worry about:
Electronic Pinout refers to how the pins are numbered on the board and what they support. The following image is an example of the pinout for the Raspberry Pi Pico.
If you revisit the MicroPython code, you will notice that the code referred to pin 25. The image above shows that the onboard LED is on pin 25. Every board you choose should have a similar guide.
Also, notice all of the color codes. We see that the LED has a green color code for GPIO and PIO. If you are wondering what SPI and I2C are, then I would recommend the serial communication article from Sparkfun.
The whole point of your MCU is not to blink an LED, except for when that is all you need. MCUs tend to exist along with other components in an electronic circuit. If you don’t know anything about circuits then you are bound to destroy your MCU.
You know that you have pins, but how do you connect other components to those pins? You might get a document that tells you what you need to connect, but how do you read the circuit diagram? How do you communicate what you have prototyped to others? Or document it?
There is no need to panic if all of this is new to you. Sparkfun has an entire series of engineering essentials here, and I won’t bother trying to recreate the wheel.
I have found Fritzing to be useful for documenting circuits. A little search could expose similar tools that you might find useful.
Once you know how to connect your circuits, you will need to get hands-on. MCU development boards come in two variants: those with soldered headers and those without. If you are fine using your hands then you can get a board without soldered headers and do all of the work yourself, otherwise get one with soldered headers.
You might find a solderless breadboard to be handy when it comes to connecting everything together.
Reading can only get you so far. You will need to roll up your sleeves and practice! There are lots of project available both online and in books. Try to go through as many as you can.
The team at Arm Education has done a great job of creating courses that I would also like to recommend. The courses are hosted on EdX and you can access them for free. Do note that you will be given six weeks to complete any courses that you enrol into. Get started here.