Helloworld In Embedded Systems

Helloworld In Embedded Systems

Unlike other stacks with their peculiar languages whose first project might be printing "Hello world" over the console or terminal, it is quite different from what we are going to learn today. We will be blinking an LED using the C programming language on the ARM cortex-m4 STM32F407VETx microcontroller based breakout board, this could be replicated on ST's Nucleo or Discovery board of choice with little or no modification. Blinking an LED in embedded systems could be likened to conventional "Hello world" in other tech stacks.
Yeah, I know you are enthusiastic to get started and figure out what this project entails. That is totally fine, I mean I was once in your shoes some years ago, grab a coffee let us get started.

What is Embedded system?

An embedded system is a microprocessor- or microcontroller-based system of hardware and software designed to perform dedicated functions and tasks. It is the integration of firmware onto a hardware device with the aim of performing specials task, or specific functions. you can read more on this here tutorialspoint.com/embedded_systems/es_over..

Things you need for this project:

  1. LED
  2. Jump wires
  3. Breadboard
  4. ST-Link V2 (External programmer)
  5. STM32F407VETx breakout board
  6. 1 x Resistor 100 ohms
  7. ST CubeIDE software
  8. STM32F407 datasheet and reference manual

Before we continue let us have a look at the stm32 microcontroller unit(MCU) in use here. The STM32F407VETx MCU is one of the microcontrollers produced by ST. The STM32F407xx family is based on the high-performance ARM® Cortex®-M4 32-bit RISC core operating at a frequency of up to 168MHz. The Cortex-M4 core features a Floating point unit (FPU) single precision which supports all ARM single- precision data-processing instructions and data types. While working with this MCU might look a bit complex, the truth is it is not at all. It has more to do with shifting ones and zeros into addressable registers to enable or disable desired functionality. Below is the block diagram of our MCU.

440px-STM32F4DeviceOverview.jpg

Considering our block diagram, we can see that our GPIO Port peripherals (GPIO Port A, GPIO Port B etc.) are all connected to the AHB1 bus which runs at maximum speed of 168MHz. For this tutorial, we are going to use the CMSIS(Common Microcontroller Software Interfaced Standard) library from ARM technology.

So our first step will be to open our cubeIDE and and create a new project by doing the following:

  • Navigate to file and click on it

  • Click on 'new'

  • stm32 project

  • Select your specific board or MCU type

  • Give your project a name, mine is "TEST-TEST"

  • Select 'STM32Cube' under "target project type", then click finish.

The next step is to find our "main.c" file in our newly created project and double click on it.

Capture-save-me.JPG

So we go ahead and delete all our initializations and comments that came with our 'main.c' file, then include our device specific header file, this informs our CMSIS library the exact type or family-type of MCU we are working with e.g "#include stm32f4xx.h" followed by our main function. Capture-main.JPG

Easy right? go ahead and compile this code just to make sure all is in good shape, right-click on the project and click on build, we should get a message on the console saying the build was successful. Capture-build.JPG

Now we enable the clock access to our preferred GPIO port, say GPIO A. Navigating through our stm32f4 reference manual, this can be done in the Reset and Clock Control(RCC) register of our microcontroller, RCC AHB1 peripheral clock enable register (RCC_AHB1ENR) to be more precise. -rcc1.JPG

let us go ahead and enable the clock for GPIOA by writing bit '1' to the '0'th bit position of the RCC AHB1 peripheral clock enable register (RCC_AHB1ENR).

Capture-RCC-CORRECT.JPG

Then we proceed to the GPIO port mode register, to configure our desired pin as each port is entitled to 16 configurable pins, which ranges from pin 0-15 in this case since we have chosen GPIO PORTA our selection would range from PA0 - PA15. We would configure this desired pin to be in its output mode as to be able to drive our LED. It is important to check your development board's schematic to be sure that your desired pin is free and is not tied to serving any other purpose on your board. So we navigate again to our reference manual to find out how to set our desired pin to output mode.

Capture-real-moder2.JPG

My interest is PA2, yours might differ if your PA2 is serving any other serious purpose on your board. Since I want to configure PA2 to output mode, I will write bit '0' and '1' to the 5th and 4th bit positions of the register respectfully i.e. MODER2[1;0]. Capture-recap.JPG

Our job is almost done, the next step will be to set and clear the 2nd bit position of the GPIO port output data register (GPIOx_ODR), in order to make PA2 high and low thus blinking our LED attached to it. ODR.JPG

So let us go ahead and do this in our code. It is important to note that without any significant delay we will not be able to see our LED blink therefore we need some sort of delay, in-between turning our LED on and off. The best way to have an efficient delay generally in embedded systems, is to utilize the built in timer peripheral(s) in our MCU. This tutorial won't cover that, we would rather use a for loop to cause a significant delay. Capture-delay.JPG

Here is the entire code;

#include <stdint.h>
#include "stm32f407xx.h"

int main(void)
{

    //Enable the RCC of GPIOA
    RCC->AHB1ENR |= (0x1UL << (1)); //Shifting 1 bit to the 0 position


    //Moder register of GPIOA and configure desired pin as output.
    GPIOA->MODER |=  (0x1UL << (4));  //Shifting 1 bit to the 4th positon bit position
    GPIOA->MODER &= ~(0x1UL << (5));  ////Shifting inverse 1 (0)  bit to the 4th positon bit position


    //set and clear ODR2 of the GPIOA ODR register
    GPIOA->ODR |=  (0x1UL << (2));             //turn ON LED
    for(int i = 0; i < 300000; i++){}          //delay using for loop
    GPIOA->ODR &= ~(0x1UL << (2));         //turn OFF LED

}

build the project again in order to have the entire code compiled. now let us load the .bin file into our MCU. Plug the ST-Link V2 into your PC and connect it to your development board using jump wires in this arrangement.

ST-Link V2 Pin ====== Development board Pin

SWDIO ======= ==> SWDIO

GND ====== ==> GND

SCLK ====== ==> SCLK

NRST ====== ==> NRST

Right click on your project on the IDE then click on "Run As" select "STM32 Cortex-M C/C++ Application", that will be all. Go ahead and connect your LED and resistor on your bread board in this arrangement below.

Wrapping up

LED-RESISTOR-2.png Connect the red jump wire, the anode pin of the LED to PA2 or your configured output pin then connect the black jump wire to the GND pin on the board. Press the reset button on your development board, you should see your LED blinking.

Conclusion

That is all for this article, if you encounter any problem please do well to reach out to me via the comment section. Thanks for reading, see you next time.

Twitter: twitter.com/AghaKingsley3

Github: github.com/spizytek

                              #programming   #Tech #embeddedsystems

REFERENCES

  1. st.com/en/development-tools