STM32底层LL库串口通信LL篇3

Posted:   2020-08-20

Status:   Completed

Tags :   STM32 CUBE LL USART

Categories :   STM32 CUBE LL USART

Previous:   STM32底层LL库GPIO使用输入LL篇2

Next:   STM32底层LL库串口通信之队列LL篇4


配置串口

  • 和HAL库配置一样
  • 在高级设置里为USART1选择LL
  • 生成代码

串口函数

串口结构体分析

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
/**
  * @brief LL USART Init Structure definition
  */
typedef struct
{
  uint32_t BaudRate;                  /*!< This field defines expected Usart communication baud rate.

                                           This feature can be modified afterwards using unitary function @ref LL_USART_SetBaudRate().*/

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

                                           This feature can be modified afterwards using unitary function @ref LL_USART_SetDataWidth().*/

  uint32_t StopBits;                  /*!< Specifies the number of stop bits transmitted.
                                           This parameter can be a value of @ref USART_LL_EC_STOPBITS.

                                           This feature can be modified afterwards using unitary function @ref LL_USART_SetStopBitsLength().*/

  uint32_t Parity;                    /*!< Specifies the parity mode.
                                           This parameter can be a value of @ref USART_LL_EC_PARITY.

                                           This feature can be modified afterwards using unitary function @ref LL_USART_SetParity().*/

  uint32_t TransferDirection;         /*!< Specifies whether the Receive and/or Transmit mode is enabled or disabled.
                                           This parameter can be a value of @ref USART_LL_EC_DIRECTION.

                                           This feature can be modified afterwards using unitary function @ref LL_USART_SetTransferDirection().*/

  uint32_t HardwareFlowControl;       /*!< Specifies whether the hardware flow control mode is enabled or disabled.
                                           This parameter can be a value of @ref USART_LL_EC_HWCONTROL.

                                           This feature can be modified afterwards using unitary function @ref LL_USART_SetHWFlowCtrl().*/

  uint32_t OverSampling;              /*!< Specifies whether USART oversampling mode is 16 or 8.
                                           This parameter can be a value of @ref USART_LL_EC_OVERSAMPLING.

                                           This feature can be modified afterwards using unitary function @ref LL_USART_SetOverSampling().*/

} LL_USART_InitTypeDef;
  • 波特率BaudRate
  • 字长DataWidth
1
2
3
4
5
/** @defgroup USART_LL_EC_DATAWIDTH Datawidth
  * @{
  */
#define LL_USART_DATAWIDTH_8B                   0x00000000U             /*!< 8 bits word length : Start bit, 8 data bits, n stop bits */
#define LL_USART_DATAWIDTH_9B                   USART_CR1_M             /*!< 9 bits word length : Start bit, 9 data bits, n stop bits */
  • 停止位StopBits
1
2
3
4
5
6
7
/** @defgroup USART_LL_EC_STOPBITS Stop Bits
  * @{
  */
#define LL_USART_STOPBITS_0_5                   USART_CR2_STOP_0                           /*!< 0.5 stop bit */
#define LL_USART_STOPBITS_1                     0x00000000U                                /*!< 1 stop bit */
#define LL_USART_STOPBITS_1_5                   (USART_CR2_STOP_0 | USART_CR2_STOP_1)      /*!< 1.5 stop bits */
#define LL_USART_STOPBITS_2                     USART_CR2_STOP_1                           /*!< 2 stop bits */
  • 校验位Parity
1
2
3
4
5
6
/** @defgroup USART_LL_EC_PARITY Parity Control
  * @{
  */
#define LL_USART_PARITY_NONE                    0x00000000U                          /*!< Parity control disabled */
#define LL_USART_PARITY_EVEN                    USART_CR1_PCE                        /*!< Parity control enabled and Even Parity is selected */
#define LL_USART_PARITY_ODD                     (USART_CR1_PCE | USART_CR1_PS)       /*!< Parity control enabled and Odd Parity is selected */
  • 模式选择TransferDirection
1
2
3
4
5
6
7
/** @defgroup USART_LL_EC_DIRECTION Communication Direction
  * @{
  */
#define LL_USART_DIRECTION_NONE                 0x00000000U                        /*!< Transmitter and Receiver are disabled */
#define LL_USART_DIRECTION_RX                   USART_CR1_RE                       /*!< Transmitter is disabled and Receiver is enabled */
#define LL_USART_DIRECTION_TX                   USART_CR1_TE                       /*!< Transmitter is enabled and Receiver is disabled */
#define LL_USART_DIRECTION_TX_RX                (USART_CR1_TE |USART_CR1_RE)       /*!< Transmitter and Receiver are enabled */
  • 硬件流控制选择HardwareFlowControl
1
2
3
4
5
6
7
/** @defgroup USART_LL_EC_HWCONTROL Hardware Control
  * @{
  */
#define LL_USART_HWCONTROL_NONE                 0x00000000U                          /*!< CTS and RTS hardware flow control disabled */
#define LL_USART_HWCONTROL_RTS                  USART_CR3_RTSE                       /*!< RTS output enabled, data is only requested when there is space in the receive buffer */
#define LL_USART_HWCONTROL_CTS                  USART_CR3_CTSE                       /*!< CTS mode enabled, data is only transmitted when the nCTS input is asserted (tied to 0) */
#define LL_USART_HWCONTROL_RTS_CTS              (USART_CR3_RTSE | USART_CR3_CTSE)    /*!< CTS and RTS hardware flow control enabled */
  • 串口过采样OverSampling
1
2
3
4
5
6
7
/** @defgroup USART_LL_EC_OVERSAMPLING Oversampling
  * @{
  */
#define LL_USART_OVERSAMPLING_16                0x00000000U            /*!< Oversampling by 16 */
#if  defined(USART_CR1_OVER8)
#define LL_USART_OVERSAMPLING_8                 USART_CR1_OVER8        /*!< Oversampling by 8 */
#endif /* USART_OverSampling_Feature */

常用函数

  • 读总线空闲标志位uint32_t LL_USART_IsActiveFlag_IDLE(USART_TypeDef *USARTx)
  • 读接收标志位uint32_t LL_USART_IsActiveFlag_RXNE(USART_TypeDef *USARTx)
  • 读发送完成标志位uint32_t LL_USART_IsActiveFlag_TC(USART_TypeDef *USARTx)
  • 读发送数据寄存器空标志位uint32_t LL_USART_IsActiveFlag_TXE(USART_TypeDef *USARTx)
  • 清空闲标志位void LL_USART_ClearFlag_IDLE(USART_TypeDef *USARTx)
  • 使能空闲中断void LL_USART_EnableIT_IDLE(USART_TypeDef *USARTx)
  • 使能接收中断void LL_USART_EnableIT_RXNE(USART_TypeDef *USARTx)
  • 接收数据uint8_t LL_USART_ReceiveData8(USART_TypeDef *USARTx)
  • 发送数据void LL_USART_TransmitData8(USART_TypeDef *USARTx, uint8_t Value)
  • 使能串口DMA接收请求void LL_USART_EnableDMAReq_RX(USART_TypeDef *USARTx)
  • 使能串口DMA发送请求void LL_USART_EnableDMAReq_TX(USART_TypeDef *USARTx)
  • 获取串口地址uint32_t LL_USART_DMA_GetRegAddr(USART_TypeDef *USARTx)

代码移植

添加发送函数

  • usart.c添加头文件
1
2
3
/* USER CODE BEGIN 0 */
#include "stdio.h"
/* USER CODE END 0 */
  • 添加发送函数定义
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
/* USER CODE BEGIN 1 */
/*****************  发送一个字节 **********************/
void Usart_SendByte( USART_TypeDef * pUSARTx, uint8_t ch)
{
    /* 发送一个字节数据到USART */
    LL_USART_TransmitData8(pUSARTx,ch);

    /* 等待发送数据寄存器为空 */
    while ( LL_USART_IsActiveFlag_TXE(pUSARTx) == RESET);
}
/****************** 发送8位的数组 ************************/
void Usart_SendArray( USART_TypeDef * pUSARTx, uint8_t *array, uint16_t num)
{
    uint8_t i;

    for(i=0; i<num; i++)
    {
        /* 发送一个字节数据到USART */
        Usart_SendByte(pUSARTx,array[i]);

    }
    /* 等待发送完成 */
    while(LL_USART_IsActiveFlag_TC(pUSARTx)==RESET);
}
///重定向c库函数printf到串口,重定向后可使用printf函数
int fputc(int ch, FILE *f)
{
    /* 发送一个字节数据到串口 */
    LL_USART_TransmitData8(USART1, (uint8_t) ch);

    /* 等待发送完毕 */
    while ( LL_USART_IsActiveFlag_TXE(USART1) == RESET);

    return (ch);
}
/* USER CODE END 1 */
  • usart.h添加发送函数声明
1
2
3
4
/* USER CODE BEGIN Prototypes */
void Usart_SendByte( USART_TypeDef * pUSARTx, uint8_t ch);
void Usart_SendArray( USART_TypeDef * pUSARTx, uint8_t *array, uint16_t num);
/* USER CODE END Prototypes */

使能接收中断和空闲中断

  • 在主函数初始化添加
1
2
3
4
  /* USER CODE BEGIN 2 */
  LL_USART_EnableIT_RXNE(USART1);
  LL_USART_EnableIT_IDLE(USART1);
  /* USER CODE END 2 */

处理中断

  • stm32f1xx_it.c文件中添加头文件包含
1
2
3
/* USER CODE BEGIN Includes */
#include "usart.h"
/* USER CODE END Includes */
  • 添加变量
1
2
3
4
/* USER CODE BEGIN PV */
uint8_t rx_data[50];
uint8_t rx_len=0;
/* USER CODE END PV */
  • USART1_IRQHandler函数中添加
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
/**
  * @brief This function handles USART1 global interrupt.
  */
void USART1_IRQHandler(void)
{
  /* USER CODE BEGIN USART1_IRQn 0 */
    uint8_t ucCh;
    //数据接收完成
    if(LL_USART_IsActiveFlag_RXNE(USART1)!=RESET)
    {
        ucCh  = LL_USART_ReceiveData8( USART1);
        rx_data[rx_len++]=ucCh;
        if(rx_len>=50)
        {
            rx_len=0;
        }
    }

  /* USER CODE END USART1_IRQn 0 */
  /* USER CODE BEGIN USART1_IRQn 1 */
    //数据帧接收完毕
    if ( LL_USART_IsActiveFlag_IDLE(USART1 ) == SET )
    {
        Usart_SendByte(USART1,rx_len);
        Usart_SendArray(USART1,rx_data,rx_len);
        LL_USART_ClearFlag_IDLE(USART1);
        rx_len=0;
    }
  /* USER CODE END USART1_IRQn 1 */
}

下载调试

  • 编译之后下载到开发板
  • 连接开发板串口
  • 打开串口助手
  • 向开发板发送数据,将会看到开发板返回数据长度和完整数据
  • 和SPL,HAL库结果一致