In this tutorial, I will share how to use STM32F4 USART in polling mode. STM32F4 Discovery board has 6 U(S)ART channels (USART1, USART2, USART3, UART4, UART5, and USART6). USART can be used for communication with PC or another device that use USART communication such as bluetooth module, GSM module and so much more. USART 1 and USART6 are connected to APB2 bus and able to communicate at speeds of up to 10.5 Mbit/s. USART2, USART3, UART4, UART5 are connected to APB1 bus and able to communicate at speeds of up to 5.25 Mbit/s.
To interface STM32F4 to your PC with USART, you can use either DB9 port or use USB port (Using USB to RS232 converter or USB to TTL converter). If you use DB9 port, then you must add additional electronic components like MAX232 IC to adjust voltage level.
If you use USB to RS232 converter, then same as when you use DB9 port, you must add additional electronic components like MAX232 because the output signal of DB9 port and USB to RS232 converter is same (RS232 voltage level).
If you use USB to TTL converter then you can directly connect to the STM32F4 because most of I/O pins on STM32F4 (Especially for USART pins) are 5V tolerant. You can also use Arduino as USB to TTL converter in case when you don't have USB to TTL converter device but you have Arduino.
To interface STM32F4 to your PC with USART, you can use either DB9 port or use USB port (Using USB to RS232 converter or USB to TTL converter). If you use DB9 port, then you must add additional electronic components like MAX232 IC to adjust voltage level.
USART on STM32F4 can be configure to several pin that available for that USART as shown in table below.
For this example, I will use USART1 to communicate between STM32F4 board to PC. Here I will make 4 functions that can be use for USART1. The first function is USART_Config(). This function is for initialize USART1 and GPIOB (Tx and Rx).
void USART_Config(void) { // Enable clock for GPIOB RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE); // Enable clock for USART1 RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE); // Connect PB6 to USART1_Tx GPIO_PinAFConfig(GPIOB, GPIO_PinSource6, GPIO_AF_USART1); // Connect PB7 to USART1_Rx GPIO_PinAFConfig(GPIOB, GPIO_PinSource7, GPIO_AF_USART1); // Initialization of GPIOB GPIO_InitTypeDef GPIO_InitStruct; GPIO_InitStruct.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStruct.GPIO_OType = GPIO_OType_PP; GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP; GPIO_Init(GPIOB, &GPIO_InitStruct); // Initialization of USART1 USART_InitTypeDef USART_InitStruct; USART_InitStruct.USART_BaudRate = 9600; USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None; USART_InitStruct.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; USART_InitStruct.USART_Parity = USART_Parity_No; USART_InitStruct.USART_StopBits = USART_StopBits_1; USART_InitStruct.USART_WordLength = USART_WordLength_8b; USART_Init(USART1, &USART_InitStruct); // Enable USART1 USART_Cmd(USART1, ENABLE); }
The second function is USART_PutChar(). This function is for send a character.
void USART_PutChar(char c) { // Wait until transmit data register is empty while (!USART_GetFlagStatus(USART1, USART_FLAG_TXE)); // Send a char using USART1 USART_SendData(USART1, c); }
The third function USART_PutString(). This function is for sending a string. This function is use USART_PutChar() function for send every character of a string.
void USART_PutString(char *s) { // Send a string while (*s) { USART_PutChar(*s++); } }
The last function in this tutorial is USART_GetChar(). This function is for read a character.
uint16_t USART_GetChar() { // Wait until data is received while (!USART_GetFlagStatus(USART1, USART_FLAG_RXNE)); // Read received char return USART_ReceiveData(USART1); }
To test those functions, I have made simple program that send "Hello, World!" to PC and monitoring data from PC. If PC send 'H' then the orange LED (PD13) will turn on. If PC send 'L' then the orange LED will turn off.
#include "stm32f4xx.h" #include "stm32f4xx_rcc.h" #include "stm32f4xx_gpio.h" #include "stm32f4xx_usart.h" int main(void) { // Enable clock for GPIOD (for orange LED) RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE); // Initialization of GPIOD (for orange LED) GPIO_InitTypeDef GPIO_InitDef; GPIO_InitDef.GPIO_Pin = GPIO_Pin_13; GPIO_InitDef.GPIO_Mode = GPIO_Mode_OUT; GPIO_InitDef.GPIO_OType = GPIO_OType_PP; GPIO_InitDef.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_InitDef.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOD, &GPIO_InitDef); // Call USART1 configuration USART_Config(); // Send "Hello, World!" to PC USART_PutString("Hello, World!\n"); while (1) { // Get a char from PC uint16_t data = USART_GetChar(); if (data == 'H') { // If received char is 'H' then turn on orange LED GPIO_SetBits(GPIOD, GPIO_Pin_13); } else if (data == 'L') { // If received char is 'L' then turn off orange LED GPIO_ResetBits(GPIOD, GPIO_Pin_13); } } }
Thank you very much for your introduction about the converters.
ReplyDeleteThis is very useful..but what are the exact connections between the STM32 board and the PC if I am using a USB to TTL converter?
ReplyDeleteThank you so much for this example. It worked right away except for one snag - my actual baud rate is what I specified in "USART_InitStruct.USART_BaudRate = 9600" divided by 3. I specified 57600, and the terminal only displays correctly if I set it to 19200 baud. Only clues as to where might start debugging?
ReplyDeleteChang/define your HSE_VALUE to 8 MHZ there...... It works fine according to your baud rate as you expect.
Deleteon minicom transmit works after definind serial port HW flow to "no"
ReplyDeleteThanks for simple code and explanation.
hello , i am working two uart at a time but not sending data . only usart1 working other one is not sending data . plz reply
ReplyDeletemicroconroller stm32f407 not receiving data for the above code what is the reason
ReplyDelete