Ads

Get STM32 tutorial using HAL at $10 for a limited time!

Sunday, April 26, 2015

STM32F4 Discovery Tutorial 6 - USART Polling Mode

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.


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);
        }
    }
}

7 comments :

  1. Thank you very much for your introduction about the converters.

    ReplyDelete
  2. This 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?

    ReplyDelete
  3. Thank 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?

    ReplyDelete
    Replies
    1. Chang/define your HSE_VALUE to 8 MHZ there...... It works fine according to your baud rate as you expect.

      Delete
  4. on minicom transmit works after definind serial port HW flow to "no"
    Thanks for simple code and explanation.

    ReplyDelete
  5. hello , i am working two uart at a time but not sending data . only usart1 working other one is not sending data . plz reply

    ReplyDelete
  6. microconroller stm32f407 not receiving data for the above code what is the reason

    ReplyDelete