STM32F10x Discovery, part 3: Code and run

Files updates

In the project section, update the name “Target 1” to usart_3.
Inside this section, create four groups:

  • StdPeriph_Driver
  • Startup
  • User

Create a new C file, using menu File/New… and save it as main.c into the project directory. Populate each group with required library information, by a right click on each group and “Add Files to group xxx”:

  • StdPeriph_Driver
    • stm32\Libraries\STM32F10x_StdPeriph_Driver\src\stm32f10x_gpio.c
    • stm32\Libraries\STM32F10x_StdPeriph_Driver\src\stm32f10x_rcc.c
    • stm32\Libraries\STM32F10x_StdPeriph_Driver\src\stm32f10x_usart.c
    • stm32\Libraries\CMSIS\CM3\CoreSupport\core_cm3.c
    • stm32\Libraries\CMSIS\CM3\CoreSupport\core_cm3.h
  • Startup
    • stm32\Libraries\CMSIS\CM3\CoreSupport\core_cm3.c
    • stm32\Libraries\CMSIS\CM3\DeviceSupport\ST\STM32F10x\startup\arm\ startup_stm32f10x_md_vl.s
  • User
    • Add previously created main.c file.

For usart_3 project, three files from the StdPeriph_Driver are required. It’s explained later.
All files located under Libraries will remain unchanged as they are intended to be used in many projects.
To configure specifically this project, copy following file into the project location stm32\usart_3:


Include configuration

stm32\stm32f10x_conf.h must restrict include files only needed for this project.
Only GPIO, USART and clock management (RCC) are required.
Modify this file to get only these three drivers:

/* #include "stm32f10x_adc.h"
#include "stm32f10x_bkp.h"
#include "stm32f10x_can.h"
#include "stm32f10x_cec.h"
#include "stm32f10x_crc.h"
#include "stm32f10x_dac.h"
#include "stm32f10x_dbgmcu.h"
#include "stm32f10x_dma.h"
#include "stm32f10x_exti.h"
#include "stm32f10x_flash.h"
#include "stm32f10x_fsmc.h" */
#include "stm32f10x_gpio.h"
/* #include "stm32f10x_i2c.h"
#include "stm32f10x_iwdg.h"
#include "stm32f10x_pwr.h" */
#include "stm32f10x_rcc.h"
/* #include "stm32f10x_rtc.h"
#include "stm32f10x_sdio.h"
#include "stm32f10x_spi.h"
#include "stm32f10x_tim.h" */
#include "stm32f10x_usart.h"
/* #include "stm32f10x_wwdg.h" */

The last file to copy into stm32\usart_3 is


Start the program

This section describes the main.c file. The real programming starts here!

Include and global variables

Include files refers to the project configuration and the standard i/o library for C:

#include "stm32f10x.h"
#include <stdio.h>

As global variable, the USART and GPIO structures are defined here.

USART_InitTypeDef USART_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;

Peripheral configuration

This section of the code verifies the good startup of the external oscillator (and other things…)

ErrorStatus HSEStartUpStatus;
HSEStartUpStatus = RCC_WaitForHSEStartUp();
if (HSEStartUpStatus == SUCCESS) {
	RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);
	while (RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);
	while (RCC_GetSYSCLKSource() != 0x08);

Activate the GPIO clock:


Activate the clock for the UART:

RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);

These GPIO constraints are required for USART output as push-pull, here located on GPIO A9:

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);

RX on port A10 is set as floating:

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_Init(GPIOA, &GPIO_InitStructure);

The main peripheral configuration for USART, which is self understandable:

USART_InitStructure.USART_BaudRate = 115200;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl =
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_Init(USART1, &USART_InitStructure);

Finally, activate the periph:


As this point, three peripheral are used. It corresponds to the file list included before.

fputc retarget

This function override the fputc used by printf in order to redirect chars to USART.

int fputc(int ch, FILE *f)
   /* Place your implementation of fputc here */
   /* e.g. write a character to the USART */
   while (!(USART1->SR & USART_FLAG_TXE));
   USART_SendData(USART1, (uint8_t) ch);
   /* Loop until the end of transmission */
   while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET)
   return ch;

Active code

To send a single Hello World to USART, nothing simple as:

print(“Hello world\n\r”);

Many pages for this result… but the entire configuration is reusable for many project.

Run on target

The project is compiled by hitting the key F7. The build output must return:

Build target 'usart_3'
compiling stm32f10x_gpio.c...
compiling stm32f10x_rcc.c...
compiling stm32f10x_usart.c...
compiling core_cm3.c...
compiling system_stm32f10x.c...
assembling startup_stm32f10x_md_vl.s...
compiling main.c...
Program Size: Code=7520 RO-data=320 RW-data=48 ZI-data=1040
"usart_3.axf" - 0 Error(s), 0 Warning(s).

Due to unexplained problem, the “Load” operation is not working to update the firmware on the target. To do so, start and stop a debug session with CTRL+F5. This download and reset the Discovery target with the fresh compiled firmware.


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s