STM32 serial port detailed explanation

table of Contents

01. Features of USART

02. Introduction to USART

2.1, data transmission model

2.2, frame structure

2.3, baud rate

03, STM32's USART

04, code configuration


01. Features of USART

USART is a universal asynchronous receiver/transmitter (UniversalAsynchronous Receiver/Transmitter), usually called UART, is an asynchronous receiver transmitter, is a key module for asynchronous communication between devices. UART is responsible for processing the serial/parallel and parallel/serial conversion between the data bus and the serial port, and specifies the frame format; as long as the communication parties adopt the same frame format and baud rate, they can do without sharing the clock signal , Only two signal lines (Rx and Tx) can complete the communication process, so it is also called asynchronous serial communication.

  • Full-duplex asynchronous communication.

  • Fractional baud rate generator system provides accurate baud rate.

  • Configurable 16 times oversampling or 8 times oversampling provides the possibility of flexible configuration of speed tolerance and clock tolerance.

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

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

  • Configurable to use DMA multi-buffer communication.

  • Separate transmitter and receiver enable bits.

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

  • Multiple flagged interrupt sources. Trigger an interrupt.

  • Others: check control, four error detection flags.

Communication structure

02. Introduction to USART

2.1, data transmission model

2.2, frame structure

Parameters that need to be defined for serial asynchronous communication

① Start bit

② Data bits (8 bits or 9 bits)

③ Parity bit (the 9th bit)

④ Stop bit (1,15,2 bit)

⑤ Baud rate setting

The data with parity check is 9 bits

1. Data packet

The data packet of serial communication is transmitted by the sending device through its own TXD interface to the receiving device to get the RXD interface. The content of the data packet is specified in the protocol layer, including the start bit, body data (8 or 9 bits), and checksum. Bit and stop bit, both parties of the communication must agree on the format of the data packet in order to send and receive data normally.

2. Baud rate

Since there is no clock signal in asynchronous communication, the receiving parties must agree on the baud rate, that is, the number of symbols transmitted per second, in order to decode the signal. Common baud rates are 4800, 9600, 115200, etc. The setting of baud rate in STM32 is realized through the serial port initialization structure.

3. Start and stop signals

The beginning and the end of the data packet are the start bit and the stop bit. The start signal of the data packet is represented by a data bit of logic 0, and the stop bit signal can be represented by 0.5, 1, 1.5, and 2 data bits of logic 1, and both parties need to agree. Unanimous. The setting of the start and stop signals in STM32 is also realized through the serial port initialization structure.

4. Valid data

Valid data specifies the length of the subject data, generally 8 or 9 bits, which is also implemented in STM32 through the serial port initialization structure.

5. Data verification

After the valid data, there is an optional data check bit. Because data communication is relatively more susceptible to external interference, which results in deviations in transmission data, you can add check bits during the transmission process to solve this problem. The check methods are odd, even, 0 check (space), 1 check (mark) and no (noparity). These can also be implemented in the serial port initialization structure.

2.3, baud rate

OVER8 is used to configure oversampling. Normally, OVER8 is set to 0.

If the clock is 84M

USARTDIV = 84000000/(115200*16) = 45.572

Then get:

DIV_Fraction = 16*0.572 = 0x09;

DIV_Mantissa = 45 = 0x2D;

03, STM32's USART

According to the STM32F207 data manual, STM32F207 has a total of 6 serial ports

Below we take USART1 as an example to explain

From Table10. Alternate function mapping in the STM32F207 data sheet, you can see the corresponding pins of USART1. Below, we choose PA9 and PA10 as the pins of USART1.

04, code configuration

Configure the interrupt priority.

  /* Enable the USARTx Interrupt */
  NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority =1;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);

Open the serial port and the corresponding GPIO pin, configure the corresponding serial port information and the working mode of the GPIO pin.

  /* Enable GPIO clock */
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
  /* Enable UART1 clock */
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
  /* Connect PXx to USARTx_Tx*/
  GPIO_PinAFConfig(GPIOA, 9, GPIO_AF_USART1);
  
  /* Connect PXx to USARTx_Rx*/
  GPIO_PinAFConfig(GPIOA, 10, GPIO_AF_USART1);
  
  /* Configure USART Tx as alternate function  */
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
  
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(GPIOA, &GPIO_InitStructure);
  
  /* Configure USART Rx as alternate function  */
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
  GPIO_Init(GPIOA, &GPIO_InitStructure);

Configure USART1.

  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_HardwareFlowControl_None;//配置硬件流控制
  USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;//配置工作模式,收发一起
  
  /* USART configuration */
  USART_Init(USART1, &USART_InitStructure);// 完成串口的初始化配置

Enable interrupt configuration.

  USART_ITConfig(USART1, USART_IT_TC, ENABLE);
  USART_ITConfig(USART1, USART_IT_RXNE, ENABLE)

We have configured the transmission completion interrupt and the receive data register non-empty interrupt. We can configure many types of interrupts, as seen in the standard library functions provided by ST.

/**
  * @brief  Enables or disables the specified USART interrupts.
  * @param  USARTx: where x can be 1, 2, 3, 4, 5 or 6 to select the USART or 
  *         UART peripheral.
  * @param  USART_IT: specifies the USART interrupt sources to be enabled or disabled.
  *          This parameter can be one of the following values:
  *            @arg USART_IT_CTS:  CTS change interrupt
  *            @arg USART_IT_LBD:  LIN Break detection interrupt
  *            @arg USART_IT_TXE:  Transmit Data Register empty interrupt
  *            @arg USART_IT_TC:   Transmission complete interrupt
  *            @arg USART_IT_RXNE: Receive Data register not empty interrupt
  *            @arg USART_IT_IDLE: Idle line detection interrupt
  *            @arg USART_IT_PE:   Parity Error interrupt
  *            @arg USART_IT_ERR:  Error interrupt(Frame error, noise error, overrun error)
  * @param  NewState: new state of the specified USARTx interrupts.
  *          This parameter can be: ENABLE or DISABLE.
  * @retval None
  */

Finally, enable the serial port.

  /* Enable USART */
  USART_Cmd(USART1, ENABLE);

The main function of main, the function is to display the 10 characters received by the serial port on the LCD (not display if it is not an ascii code), and the serial port returns the received 10 bytes in reverse order.

int main(void)
{
/*省略初始化部分代码*/
  while (1)
  {
    if(LCD_refresh_flg){
      LCD_refresh_flg = 0;
      LCD_ShowString(0,16,receive_data);
      receive_num--;
      USART_SendData(USART1, receive_data[receive_num--]);
      send_flg = 1;
    }
  }
}

Because the interrupt is enabled, we also need to write an interrupt function.

void USART1_IRQHandler(void)
{
  if(USART_GetFlagStatus(USART1, USART_FLAG_TC))
  {
    if(send_flg == 1){
      if(receive_num==0){
        USART_SendData(USART1, receive_data[receive_num]);
        send_flg = 0;
        receive_flg = 1;
      }else{
        USART_SendData(USART1, receive_data[receive_num--]);
      }
    }
    USART_ClearFlag(USART1, USART_FLAG_TC);
  }
  if(USART_GetFlagStatus(USART1, USART_FLAG_RXNE))
  {
    if((receive_flg)&&(send_flg == 0)){
      receive_data[receive_num++] = USART_ReceiveData(USART1);
      if(receive_num==10){
        receive_flg = 0;
        LCD_refresh_flg = 1;
      }
    }
    USART_ClearFlag(USART1, USART_FLAG_RXNE);
  }
}

Download verification

The LCD display can display the received 10 characters, and the PC sends data at 100ms intervals, sends 977 packets and receives 977 packet responses, the test demo is robust enough, and there is no packet loss.

 

Keil and IAR engineering code and hardware PCB open source address:

https://github.com/strongercjd/STM32F207VCT6

 

Click to view the album where this article is located, STM32F207 tutorial

 

Pay attention to the official account, and receive article updates as soon as possible . The comment area cannot be seen in time, you can go to the official account to communicate if you need to communicate

 

Guess you like

Origin blog.csdn.net/Firefly_cjd/article/details/109529573