You are on page 1of 24

STM32 Microcontrollers

Tutorial #2.5 : Monitoring an Analog Input Rev : 0


Author(s) : Laurent Latorre Date : 22-08-2015

Contents
1. Copy and rename an existing CoIDE project ................................................................................... 2
1.1. Make a copy of your project folder ......................................................................................... 2
1.2. Clean up and edit project files ................................................................................................ 3
1.3. Check the duplicated project .................................................................................................. 6
2. Add ADC libraries............................................................................................................................. 7
2.1. Get ADC libraries from repository ........................................................................................... 7
2.2. Get sample code from ST lib ................................................................................................... 8
2.3. Make the sample code working in your project.................................................................... 11
2.4. Adapt the sample code to your needs .................................................................................. 12
3. Write and debug the main() function............................................................................................ 15
4. Real-time monitoring with STM Studio ......................................................................................... 17
4.1. Make global the variable you want to monitor .................................................................... 17
4.2. Setup STM Studio .................................................................................................................. 18
4.3. Monitor ADC result................................................................................................................ 22
5. Summary........................................................................................................................................ 24
1. Copy and rename an existing CoIDE project

1.1. Make a copy of your project folder

For this tutorial, we are going to take the previous project (dbg_console) as starting point as it
actually features most of the basic stuff we basically always need for any project:

• Core libs, startup files


• Clock configuration
• RCC, GPIO, USART libs
• Implementation of printf function

Unfortunately, there is no “Save As” in the CoIDE project menu. When you want to use an existing
project as a base for a new project, you have to move files manually.

Open your workspace folder in the windows explorer:

Copy and paste here the folder associated with the project you want to use as a template
(dbg_console here):
Rename the copy with the name of our new project (analog_mon)

1.2. Clean up and edit project files

Then open analog_mon folder:


We will first clean the folder from files that are produced during the build process, and keep only
source files and project configuration. Delete the above highlighted file:

• The .cogui file


• The .comaker file
• The dbg_console folder (or more generally, the folder that has the same name as the
project)

Then rename the .coproj file with the name of your new project.
Now, open the renamed .coproj file with any text editor (Notepad++ if available would be perfect)

There are 4 locations where you need to change the old project name by the new one :

So change the file into this:


Save and exit the text editor.

You are done!

Even if the process is not automated, it is still much faster (and safe) than setting up a new project
from within CoIDE.

1.3. Check the duplicated project

Start CoIDE and close any opened project and open the newly copied analog_mon project. For that,
use the menu Project  Open Project… and browse to your analog_mon.coproj file.

You should retrieve all the files you’ve left in the previous tutorial (dbg_console). It is recommended
to open project from CoIDE, and not by double-clicking on the project file from Windows explorer.
Build the project and flash your target board. Open a terminal window using correct COM
port and baud rate. Make sure that everything works fine before going ahead in the tutorial.

2. Add ADC libraries

2.1. Get ADC libraries from repository

Open the Repository and in the PERIPHERAL section add ADC to your selection. Check your project
file structure to make sure that libraries have been correctly added to your project:
In the component window, select ADC and go surfing into the Help window in order to get a first idea
of what functions are available.

2.2. Get sample code from ST lib

As for any peripheral, the first task is to perform the initialization. Initialization basically configures
the peripheral according to our needs, and then turns on the peripheral.

When working with a new peripheral, it is always very instructive to have a look on some sample
code. Of course, the web if full of such wonderful pieces of code… But as beginners, you should take
much care of self-declared gurus.

As a start, a good source of inspiration is directly provided by ST together with the standard
peripherals library that you already downloaded.

Using Windows explorer, open your ST library folder:


Then, browse to the folder .\Projects\STM32F0xx_StdPeriph_Examples\ADC\ADC_BasicExample

You have here some source file that you can open with any text editor, and get some idea on what
you have to do.

Open this main.c file with a text editor (Notepad++), and scroll down to the ADC_Config() function.
Copy the whole function into the clipboard, and paste-it at the bottom of your own main.c file within
CoIDE:
2.3. Make the sample code working in your project

Hit the build button… and look at the console:

Hey! What did you expect?

Actually, doing this is a good approach to tackle problems one by one. Reported errors are our
friends. Always consider the very first reported error or warning in the list. Solving it will probably
remove a lot of subsequent errors.

First error reports “error: unknown type name 'ADC_InitTypeDef' “. Any idea?

The compiler is not finding the definition of the type 'ADC_InitTypeDef'. This type is probably defined
in the ADC header file. Let us include this header in our main.c file:
Then, hit the build button again.

This is magic!

The project now builds fine. The only remaining warning is quite understandable: we have no use of
the ADC_Config() function for the moment. This is normal.

2.4.Adapt the sample code to your needs

Before using the ADC_Config() function, let us focus on what is it doing, and do some cleaning.

Consider the very firsts lines:


Two Init Structure variables are declared, one for the GPIO, one for ADC. Those variables are used
later on to configure GPIO and ADC operating mode. OK.

Then, the clocks are enabled for both peripherals GPIOC and ADC1.

An ADC converts a voltage applied on a pin into a digital representation stored in a register. We can
guess that the pin(s) in use in this example are borrowed from the port C.

Taking a look in the STM32 Datasheet, we can see that PC0, PC1, PC2, PC3, and (not shown here)
PC4, PC5 pins can be used as ADC inputs, on channels 10, 11, 12, 13, 14, 15 respectively. Note that
there are other pins, from other ports, that can also serve as ADC inputs (PA0, PA1, PA2, PA3, PA4,
PA5, PA6, PA7, PB0, PB1) for the channels ranging from 0 to 9.

So far, we have no problem in using one of port C pins for our ADC demo, so let’s go ahead. Next
lines configure the GPIO pin assigned to ADC channel 11 or ADC channel 10 depending on which
EVAL board is targeted.

We don’t care if our code is not portable across various development boards, so let us make it simple
by removing the #ifdef compiler directives, and setting the correct IO pin directly to work with
channel 11 (PC1):
Next lines configure the ADC peripheral itself:

The ADC is configured to continuously convert input voltage, with a 12 bits resolution and no
triggering feature. It seems OK for our purpose. The scan direction refers to multiple channels
conversion and is not a concern here as we are dealing with only one input. OK.

Again, let us do some cleaning in the remaining lines:

Line 149 actually tells the ADC to take its input from channel 11 (therefore from the PC1 pin). The
remaining code consists in getting calibration data, powering up the ADC, and starting the conversion
process as soon as ADC is ready.

Well, the ADC_Config() function looks fine now.


Before calling ADC_Config() function from within the main() function, we need to add its prototype
at the beginning of the file:

3. Write and debug the main() function

Finally, edit the main() function. If you look back at the sample code from ST libs, you will discover
the “inspiration” source…

“EOC” stands for End Of Conversion. It is clever to wait for this flag before asking a new ADC result.
Build the project, verify that you have no errors or warning, and then flash your target
board.
Open a terminal window using correct COM port and baud rate. You should see the results of the
ADC conversion.

Note that you could as well use the debugger to monitor ADC results, but in a less “real-time”
fashion. To further test the code, one should cook a little bit of hardware.

First, locate the PC1 pin on the Nucleo board header:

PC1 corresponds to the A4 “Arduino” pin. Leaving PC1 floating may produce random conversion
results. Connecting PC1 to GND should display 0 for the ADC value. Connecting PC1 to the +3.3V pin
should display 4095 (0x0FFF, the full range for a 12 bits value). If these simple tests succeed, then it
seems that everything is working fine.
To modulate the ADC input continuously, you need to wire a potentiometer this way:

4. Real-time monitoring with STM Studio

4.1.Make global the variable you want to monitor

STM Studio is a software that can display program variable in real-time. Of course, there are few
limitations. Basically, you can monitor:

• Global variables only


• At 1kHz maximum sample rate (1ms)

This is still an incredibly powerful way for finding out bugs or tuning computation loop in control
applications (ex. tuning a PID controller)

Because we can only monitor global variable, let’s move the declaration of the ADC result variable
outside the main() function:
Build the project, verify that you have no errors or warning, and then flash your target
board. Check in your terminal that the program is working just as well as before.

4.2. Setup STM Studio

Start STM Studio application from Windows start menu.


Change the ST-Link protocol to SWD (Serial Wire Debug Interface)

Go to the main menu File  Import variables or click

In the Import variables from executable windows, use the button on the right of the Excutable
file field to browse for your .elf project executable file.

You will find the .elf file in the following subdirectory:

{your_workspace}\analog_mon\analog_mon\Debug\bin\analog_mon.elf
STM Studio then reports a list of all the variables that you can “spy”:

Select ADC1ConvertedValue, and then click the Import button. Then Close this window.

Drag & drop the ADC1ConvertedValue variable from the Variable settings zone to the VarViewer 1
zone:
Then set the Viewer range according to what you expect from the variable:
Now go to the menu Option  Acquisition Settings or click

Set the Graphical refresh rate to 5ms, and uncheck the Log to file option. Click OK to close the
window.

4.3. Monitor ADC result


Go to menu Run  Start or click the button.

You can now monitor the fluctuations of the voltage applied on PC11 pin, just like with an
oscilloscope. You can even make sure that STM Studio and the data you print in the console are the
same (as it should be).

Now, you can play with the various options you have to display data (Curve, Bar Graph, Table)

You can also change the acquisition settings, you can zoom (in/out) curves, and even record data to a
file for further analysis or reporting purposes (Excel, Matlab…).

Note that you cannot flash the code while STM Studio is running. You don’t have to close STM Studio,
just hit the stop button before flashing a new code and then restart monitoring process. STM
Studio is linked with your .elf file now, and will change variable addresses by himself if necessary
(what a wonderful tool).
5. Summary

By now, you are able to

• Setup a new project from nothing


• Configure the system clock
• Include and configure ST standard peripheral libraries
• Compile/Link and use the debugger to track unexpected behaviors
• Perform basic tasks with GPIO, USART, ADC
• Setup a debug terminal with printf capability
• Launch STM Studio and monitor your variables in real-time
• Duplicate/rename a CoIDE project
• Find help when required, and use ST sample code to develop your own

In short, you have in your hands all the necessary tools to master STM32 development. Coming
tutorials just involve more peripherals, but regarding the workflow, you have it all.

Be aware that next tutorials will not detail anymore all the operations that you’re supposed to
master…