[STM32]STM32 F4 serial communication

concept

  • The serial port, that is, the serial interface, is a device that can convert the parallel data characters received from the CPU into continuous serial data streams and send them out, and at the same time convert the received serial data streams into parallel data characters for the CPU.

  • The concept of serial communication (Serial Communications) is very simple, the serial port sends and receives bytes bit by bit. Although slower than byte-wise parallel communication, a serial port can send data on one wire while receiving data on the other. It is simple and enables long-distance communication.

two ways of communication

  • parallel communication

  • Transmission principle: Each bit of data is transmitted simultaneously.
  • Advantages: fast
  • Disadvantage: Occupies a lot of pin resources (need to occupy 8 io ports at the same time)
  • serial communication

  • Transmission principle: Data is transmitted in bit order.
  • Advantages: occupy less pin resources
  • Cons: relatively slow

three communication directions

  • Simplex

Data transfer only supports data transfer in one direction

  • half duplex

Allows data to be transmitted in two directions, but, at a certain moment, only allows data to be transmitted in one direction, it is actually a simplex communication that switches directions;

  • full duplex

It allows data to be transmitted in two directions at the same time. Therefore, full-duplex communication is a combination of two simplex communication methods, which requires both the sending device and the receiving device to have independent receiving and sending capabilities.

Communication method of serial communication

  • Synchronous communication: with clock synchronous signal transmission. SPI, IIC communication interface.

  • Asynchronous communication: without clock synchronization signal. UART (Universal Asynchronous Transceiver), single bus.

Common serial communication interface

communication standard

Pin Description

way of communication

communication direction

UART

(Universal Asynchronous Transceiver)

TXD: sender

RXD: receiving end

GND: public ground

asynchronous communication

full duplex

single bus

(1-wire)

DQ: sending/receiving end

asynchronous communication

half duplex

SPI

SCK: synchronous clock

MISO: master input, slave output

MOSI: master output, slave input

synchronous communication

full duplex

I2C

SCL: synchronous clock

SDA: data input/output

synchronous communication

half duplex

Serial communication interface of STM32

  • UART: Universal Asynchronous Transceiver

  • USART: Universal Synchronous Asynchronous Transceiver

  • STM32F4XX currently supports up to 8 UARTs, and STM32F407 generally supports 6. For details, please refer to the selection manual and data sheet.

  • STM32F103 currently supports up to 5 UART s

UART asynchronous communication mode pin connection method:

-RXD: Data input pin. Data accepted.

-TXD: Data transmission pin. data sent.

UART asynchronous communication mode pin (STM32F407ZGT6):

Serial number

RXD

TXD

1

PA10(PB7)

PA9(PB6)

2

PA3(PD6)

PA2(PD5)

3

PB11(PC11/PD9)

PB10(PC10/PD8)

4

PC11(PA1)

PC10(PA0)

5

PD2

PC12

6

PC7(PG9)

PC6(PG14)

UART asynchronous communication mode features:

  • Full duplex asynchronous communication.

  • Fractional baud rate generator system that provides precise baud rates.

  • Configurable 16x oversampling or 8x oversampling, thus providing the possibility for flexible configuration of speed tolerance and clock tolerance.

  • Programmable data word length (8 or 9 bits);

  • Configurable stop bits (support 1 or 2 stop bits);

  • Configurable multi-buffer communication using DMA.

  • Separate transmitter and receiver enable bits.

  • Detection flag: ① Receive buffer ② Send buffer is empty ③ Transmission end flag

  • Multiple flagged interrupt sources. Trigger an interrupt.

  • Miscellaneous: Checksum control, four error detection flags.

STM32 serial port communication process:

STM32 serial port asynchronous communication needs to define parameters:

① Start bit

②Data bits (8 or 9 bits)

③ Parity bit (9th bit)

④ Stop bit (1, 15, 2 bits)

⑤ Baud rate setting

PCLK1=42MHz
PCLK2=84MHz
PCLK1 for USART2~5;
PCLK2 for USART1 and USART6;

Commonly used serial port related registers

  • USART_SR Status Register

FlagStatus USART_GetFlagStatus(USART_TypeDef* USARTx, uint16_t USART_FLAG);
The first parameter entry: (select the serial port number)
#define IS_USART_ALL_PERIPH(PERIPH) (((PERIPH) == USART1) || \
                                     ((PERIPH) == USART2) || \
                                     ((PERIPH) == USART3) || \
                                     ((PERIPH) == UART4)  || \
                                     ((PERIPH) == UART5)  || \
                                     ((PERIPH) == USART6) || \
                                     ((PERIPH) == UART7)  || \
                                     ((PERIPH) == UART8))
The second parameter entry: (select interrupt mode)
#define USART_FLAG_CTS                       ((uint16_t)0x0200)
#define USART_FLAG_LBD                       ((uint16_t)0x0100)
#define USART_FLAG_TXE                       ((uint16_t)0x0080)
#define USART_FLAG_TC                        ((uint16_t)0x0040)
#define USART_FLAG_RXNE                      ((uint16_t)0x0020)
#define USART_FLAG_IDLE                      ((uint16_t)0x0010)
#define USART_FLAG_ORE                       ((uint16_t)0x0008)
#define USART_FLAG_NE                        ((uint16_t)0x0004)
#define USART_FLAG_FE                        ((uint16_t)0x0002)
#define USART_FLAG_PE                        ((uint16_t)0x0001)
  • USART_DR status register

void USART_SendData(USART_TypeDef* USARTx, uint16_t Data);
The first parameter entry: (select the serial port number)
#define IS_USART_ALL_PERIPH(PERIPH) (((PERIPH) == USART1) || \
                                     ((PERIPH) == USART2) || \
                                     ((PERIPH) == USART3) || \
                                     ((PERIPH) == UART4)  || \
                                     ((PERIPH) == UART5)  || \
                                     ((PERIPH) == USART6) || \
                                     ((PERIPH) == UART7)  || \
                                     ((PERIPH) == UART8))
The second parameter entry: (data to be sent)

uint16_t USART_ReceiveData(USART_TypeDef* USARTx);
Parameter entry: (select the serial port number)
#define IS_USART_ALL_PERIPH(PERIPH) (((PERIPH) == USART1) || \
                                     ((PERIPH) == USART2) || \
                                     ((PERIPH) == USART3) || \
                                     ((PERIPH) == UART4)  || \
                                     ((PERIPH) == UART5)  || \
                                     ((PERIPH) == USART6) || \
                                     ((PERIPH) == UART7)  || \
                                     ((PERIPH) == UART8))
  • USART_BRR Status Register

void USART_Init(USART_TypeDef* USARTx, USART_InitTypeDef* USART_InitStruct);
The first parameter entry: (select the serial port number)
#define IS_USART_ALL_PERIPH(PERIPH) (((PERIPH) == USART1) || \
                                     ((PERIPH) == USART2) || \
                                     ((PERIPH) == USART3) || \
                                     ((PERIPH) == UART4)  || \
                                     ((PERIPH) == UART5)  || \
                                     ((PERIPH) == USART6) || \
                                     ((PERIPH) == UART7)  || \
                                     ((PERIPH) == UART8))
The second parameter entry
typedef struct
{
  uint32_t USART_BaudRate;            /*!< This member configures the USART communication baud rate.
                                           The baud rate is computed using the following formula:
                                            - IntegerDivider = ((PCLKx) / (8 * (OVR8+1) * (USART_InitStruct->USART_BaudRate)))
                                            - FractionalDivider = ((IntegerDivider - ((u32) IntegerDivider)) * 8 * (OVR8+1)) + 0.5 
                                           Where OVR8 is the "oversampling by 8 mode" configuration bit in the CR1 register. */

  uint16_t USART_WordLength;          /*!< Specifies the number of data bits transmitted or received in a frame.
                                           This parameter can be a value of @ref USART_Word_Length */

  uint16_t USART_StopBits;            /*!< Specifies the number of stop bits transmitted.
                                           This parameter can be a value of @ref USART_Stop_Bits */

  uint16_t USART_Parity;              /*!< Specifies the parity mode.
                                           This parameter can be a value of @ref USART_Parity
                                           @note When parity is enabled, the computed parity is inserted
                                                 at the MSB position of the transmitted data (9th bit when
                                                 the word length is set to 9 data bits; 8th bit when the
                                                 word length is set to 8 data bits). */
 
  uint16_t USART_Mode;                /*!< Specifies wether the Receive or Transmit mode is enabled or disabled.
                                           This parameter can be a value of @ref USART_Mode */

  uint16_t USART_HardwareFlowControl; /*!< Specifies wether the hardware flow control mode is enabled
                                           or disabled.
                                           This parameter can be a value of @ref USART_Hardware_Flow_Control */
} USART_InitTypeDef;

Serial port operation related library function configuration steps

①Serial port clock enable: RCC_APBxPeriphClockCmd();

GPIO clock enable: RCC_AHB1PeriphClockCmd();

②Pin multiplexing mapping:

GPIO_PinAFConfig();

③GPIO port mode setting: GPIO_Init(); mode setting is GPIO_Mode_AF

④Serial port parameter initialization: USART_Init();

⑤ Turn on the interrupt and initialize the NVIC (this step is only required if you need to turn on the interrupt)

NVIC_Init();

USART_ITConfig();

⑥ Enable serial port:

USART_Cmd();

⑦ Write the interrupt handler function:

USARTx_IRQHandler();

⑧Serial port data sending and receiving:

void USART_SendData();//Send data to the serial port, DR

uint16_tUSART_ReceiveData();//Accept data, read received data from DR

⑨Serial port transmission status acquisition:

FlagStatus USART_GetFlagStatus();

void USART_ClearITPendingBit();

void My_UART_Init()
{
    
    GPIO_InitTypeDef  GPIO_Type_USART;
    USART_InitTypeDef USART_Type;
    NVIC_InitTypeDef  NVIC_Type;
    
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE);  //Enable GPIOA clock
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);  //Enable serial port 1 clock
    
    GPIO_PinAFConfig(GPIOA,GPIO_PinSource9,GPIO_AF_USART1);
    GPIO_PinAFConfig(GPIOA,GPIO_PinSource10,GPIO_AF_USART1);
    
    GPIO_Type_USART.GPIO_Pin = GPIO_Pin_9|GPIO_Pin_10;
    GPIO_Type_USART.GPIO_Mode=GPIO_Mode_AF;
    GPIO_Type_USART.GPIO_PuPd=GPIO_PuPd_UP;
    GPIO_Type_USART.GPIO_OType=GPIO_OType_PP;
    GPIO_Type_USART.GPIO_Speed=GPIO_Speed_50MHz;
    
    GPIO_Init(GPIOA,&GPIO_Type_USART);
    
    USART_Type.USART_BaudRate = 115200;  //baud rate
    USART_Type.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//hardware flow control
    USART_Type.USART_Mode = USART_Mode_Rx|USART_Mode_Tx;//model
    USART_Type.USART_Parity = USART_Parity_No;//Parity
    USART_Type.USART_StopBits = USART_StopBits_1;//stop bit
    USART_Type.USART_WordLength = USART_WordLength_8b;//word length
    
    USART_Init(USART1,&USART_Type);   //initialization function
    
    USART_Cmd(USART1,ENABLE);   //enable serial port
    USART_ITConfig(USART1,USART_IT_RXNE,ENABLE); //Set serial port 1 interrupt as receive interrupt
    
    NVIC_Type.NVIC_IRQChannel = USART1_IRQn;
    NVIC_Type.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Type.NVIC_IRQChannelPreemptionPriority = 1;
    NVIC_Type.NVIC_IRQChannelSubPriority = 1;
    NVIC_Init(&NVIC_Type);
    
}
void USART1_IRQHandler(void)
{
    u8 res;
    if(USART_GetITStatus(USART1,USART_IT_RXNE)){
        
        res=USART_ReceiveData(USART1);
        USART_SendData(USART1,res);
        
    }
}

int main(void)
{
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);  //Be sure to group interrupts
    My_UART_Init();
    
  while(1){
        ;
    }
}

Tags: stm32 Single-Chip Microcomputer

Posted by bacarudaguy on Thu, 02 Mar 2023 04:01:16 +0530