Position: Index > Unclassified >

Connecting STM32 USART to standard I/O streams in GCC

2017-11-26 19:16  
Declaration:We aim to transmit more information by carrying articles . We will delete it soon, if we are involved in the problems of article content ,copyright or other problems.

In many situations when working with STM32 microcontrollers you will want to output text strings. There is no need to write special functions that output specially formatted strings as it is hard to keep up with various cases. Simply speaking it is convenient to use standard I/O streams and its library functions that allows sending formatted data streams.

Arm GCC toolchain comes with newlib C library from Redhat and so it isn’t specially designed for embedded toolcain. In order to use stdio functions we have to take care of several syscals so called “stub functions”. These functions normally are provided by operating systems like you would write C programs in Windows or Linux. In our case we aren’t using any OS, os in order to avoid error messages while compiling we have to provide these function declarations where most of them are dummy implementations. It’s not something new pick one that you find on internet. I found on that was written for STM32 Discovery.Named it as newlib_stubs.c and placed in startup directory. Among system functions implementations like _write(), _fstat(), etc. there are also USARTs assigned to standard streams:

#ifndef STDOUT_USART
#define STDOUT_USART 1
#endif
#ifndef STDERR_USART
#define STDERR_USART 2
#endif
#ifndef STDIN_USART
#define STDIN_USART 1
#endif

 

Here stdout/stdin straams are assigned to USART1, stderr to USART2. If you need them to be different

this is a place to do so. Also there are USART routines that writes or reads char.

Initializing USART

This is really easy by using CMSIS and StdPeriph library.Several things have to be taken care of. We are going to use USART for our example. First of all we need to enable clocks for USART1, GPIOA and AFIO with command:

RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE);


Then wee need to set up port pins that are used as USART1 pins. As Tx pins there is PA9 pin used and PA10 as Rx. Tx pin has to be configured as alternative function push-pull while Rx as floating input.

void USART1Init(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	USART_InitTypeDef USART_InitStructure;
	USART_ClockInitTypeDef  USART_ClockInitStructure;
	//enable bus clocks
	/* Enable USART1 and GPIOA clock */
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE);
	//Configure USART1 Tx (PA.09) as alternate function push-pull
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	//Configure USART1 Rx (PA.10) as input floating
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	USART_ClockStructInit(&USART_ClockInitStructure);
	USART_ClockInit(USART1, &USART_ClockInitStructure);
	USART_StructInit(&USART_InitStructure);
	//Configure USART1 basic and asynchronous paramters
	USART_Init(USART1, &USART_InitStructure);
	//Enable USART1
	USART_Cmd(USART1, ENABLE);
}

To initialize USART1 we are going to use couple handy functions from stm32f10x_usart.h library.

USART_ClockStructInit(&USART_ClockInitStructure);

USART_StructInit(&USART_InitStructure);

Instead of writing all parameters like baud rate, parity and mode we can call these StructInit functions that fills structure variables with default parameters (9600 baud, 8-bit, 1 stop, no parity, no HV flow control and enable Tx/Rx).

Then we can simply pass these structures to initialization functions that takes care of proper writing to registers:

USART_ClockInit(USART1, &USART_ClockInitStructure);
USART_Init(USART1, &USART_InitStructure);

And the last command is to enable USART1:

USART_Cmd(USART1, ENABLE);

This is it – we set up USART1 that can be used in main program:

//STM32F103ZET6 Usart Test
#include "stm32f10x.h"
#include "leds.h"
#include "buttons.h"
#include "usart.h"
#include "stm32f10x_it.h"
int main(void)
{
  char i;
	//init leds
  LEDsInit();
  //init buttons t ogenerate interrupts
  ButtonsInitEXTI();
  //initialize USART
  USART1Init();
  //start sys tick timer that also generates interrupts
  SysTick_Config(15000000);
  printf("\r\n USART1 Test \r\n");
while(1	)
	{
	if(USART_GetFlagStatus(USART1,USART_IT_RXNE)==SET)
		{
			i = USART_ReceiveData(USART1);
			printf("  %c",i&0xFF);	   /* print the input char */
		}
	}
}

It simply outputs string message and echoes back chars sent through terminal program. STM32F103ZET6USART


Reprinted Url Of This Article:
http://www.scienceprog.com/connecting-stm32-usart-to-standard-io-streams-in-gcc/