STM32F407HAL库-6.串口数据收发-轮询

串口数据收发(轮询)初始化步骤:

第一步:调用HAL_UART_Init函数初始化串口参数,函数如下:

 HAL_StatusTypeDef HAL_UART_Init(UART_HandleTypeDef *huart);

函数传入结构参数如下:

 
typedef struct
{
  USART_TypeDef     *Instance;   // 传入串口的基地址

  UART_InitTypeDef  Init;        // 传入串口初始化参数,波特率、奇偶校验等

  uint8_t           *pTxBuffPtr; // 传入串口发送缓冲区地址
  
  uint16_t          TxXferSize;  // 传入串口发送缓冲区大小
  
  __IO uint16_t     TxXferCount; // 传入串口发送缓冲区数据个数
  
  uint8_t           *pRxBuffPtr; // 传入串口发送缓冲区地址
  
  uint16_t          RxXferSize;  // 传入串口接收缓冲区大小
  
  __IO uint16_t     RxXferCount; // 传入串口接收缓冲区数据个数
  
  DMA_HandleTypeDef  *hdmatx; // 当串口使用DMA传输时,传入发送引脚TX的DMA初始化配置参数
    
  DMA_HandleTypeDef  *hdmarx; // 当串口使用DMA传输时,传入接收引脚RX的DMA初始化配置参数
  
  HAL_LockTypeDef    Lock; // 锁定对象

  __IO HAL_UART_StateTypeDef    gState; // 当前串口Tx引脚状态信息
                                                
  __IO HAL_UART_StateTypeDef    RxState; // 当前串口Rx引脚状态信息
  
  __IO uint32_t                 ErrorCode; // 串口错误代码

}UART_HandleTypeDef;

第二步、重定义HAL_UART_MspInit函数初始化,初始化串口硬件参数。当调用HAL_UART_Init串口初始化函数时,该函数内部会调用HAL_UART_MspInit函数,用来初始化串口使用到的引脚。这实际是HAL库的一个优点,它通过开放一个回调函数HAL_UART_MspInit,让用户自己去编写与串口有关的硬件初始化,而与串口相关的参数配置则放在HAL_UART_Init函数中,这样当我们移植程序到别的STM32平台时,使用串口只需要修改HAL_UART_MspInit函数中配置即可。

第三步、调用串口接收数据库函数HAL_UART_Receive(),实现功能如下:

  ①.函数传入4个参数,分别为串口初始化结构体参数UART_HandleTypeDef、接收数据缓冲区地址pData、接收数据缓冲区宽度Size、和接收数据最大等待时间。

  ②. 函数中首先初始化结构体UART_HandleTypeDef里面错误代码变量“ErrorCode”,接收数据缓冲区大小“RxXferSize”等变量。

HAL_StatusTypeDef HAL_UART_Receive(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout)
{ 
  uint16_t* tmp;
  uint32_t tickstart = 0U;
  
  /* Check that a Rx process is not already ongoing */
  if(huart->RxState == HAL_UART_STATE_READY) 
  { 
    if((pData == NULL ) || (Size == 0)) 
    {
      return  HAL_ERROR;
    }
    
    /* Process Locked */
    __HAL_LOCK(huart);
    
    huart->ErrorCode = HAL_UART_ERROR_NONE;
    huart->RxState = HAL_UART_STATE_BUSY_RX;
	
    /* Init tickstart for timeout managment */
    tickstart = HAL_GetTick();
        
    huart->RxXferSize = Size; 
    huart->RxXferCount = Size;

  ③.接下来根据初始化的接收数据个数变量进行while循环,循环中接收个数递减。

  ④.接下来根据串口初始化的接收数据个数、有无奇偶校验等参数来初始化临时存储数据变量pData。

  ⑤.在while循环中,调用UART_WaitOnFlagUntilTimeout函数,根据接收数据寄存器非空标志位(UART_FLAG_RXNE:当RDR移位寄存器的内容转移到USART_DR寄存器时,硬件将设置此位)状态位依次接收每个字节数据,并判断等待每个字节是否超出溢出时间,如果未超过定义的等待时间,则将数据存储到pData变量中,否则返回错误状态HAL_TIMEOUT。

    /* Check the remain data to be received */
    while(huart->RxXferCount > 0U)
    {
      huart->RxXferCount--;
      if(huart->Init.WordLength == UART_WORDLENGTH_9B)
      {
        if(UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_RXNE, RESET, tickstart, Timeout) != HAL_OK)
        { 
          return HAL_TIMEOUT;
        }
        tmp = (uint16_t*) pData;
        if(huart->Init.Parity == UART_PARITY_NONE)
        {
          *tmp = (uint16_t)(huart->Instance->DR & (uint16_t)0x01FF);
          pData +=2U;
        }
        else
        {
          *tmp = (uint16_t)(huart->Instance->DR & (uint16_t)0x00FF);
          pData +=1U;
        }

      } 
      else
      {
        if(UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_RXNE, RESET, tickstart, Timeout) != HAL_OK)
        { 
          return HAL_TIMEOUT;
        }
        if(huart->Init.Parity == UART_PARITY_NONE)
        {
          *pData++ = (uint8_t)(huart->Instance->DR & (uint8_t)0x00FF);
        }
        else
        {
          *pData++ = (uint8_t)(huart->Instance->DR & (uint8_t)0x007F);
        }
        
      }
    }

3、调用串口发送数据库函数HAL_UART_Transmit(),函数实现与HAL_UART_Receive类似,请参考上面函数。

串口数据收发bsp_uart.c完整程序如下:

#include "bsp_uart.h"

UART_HandleTypeDef UART1_Handler; //UART 句柄

// 初始化串口函数
void UART_Init(void)
{
    UART1_Handler.Instance = USART1; // 串口1
    UART1_Handler.Init.BaudRate = 115200; // 波特率
    UART1_Handler.Init.HwFlowCtl = UART_HWCONTROL_NONE; // 无硬件流控
    UART1_Handler.Init.Mode = UART_MODE_TX_RX; // 收发模式
    UART1_Handler.Init.Parity = UART_PARITY_NONE; // 无奇偶校验
    UART1_Handler.Init.StopBits = UART_STOPBITS_1; // 一个停止位
    UART1_Handler.Init.WordLength = UART_WORDLENGTH_8B; // 字长为8位格式
	
    HAL_UART_Init(&UART1_Handler); // 初始化串口
}

// 初始化低级硬件
void HAL_UART_MspInit(UART_HandleTypeDef *huart)
{
    if(huart->Instance == USART1)
    {
	GPIO_InitTypeDef GPIO_Initure;
		
	__HAL_RCC_GPIOA_CLK_ENABLE(); // 使能GPIO引脚
	__HAL_RCC_USART1_CLK_ENABLE(); // 使能串口
		
	GPIO_Initure.Mode = GPIO_MODE_AF_PP; // 复用推挽模式
	GPIO_Initure.Pin = GPIO_PIN_9|GPIO_PIN_10; // PA9、PA10
	GPIO_Initure.Pull = GPIO_PULLUP;  //上拉
	GPIO_Initure.Speed = GPIO_SPEED_FAST; //高速
	GPIO_Initure.Alternate = GPIO_AF7_USART1; // 复用为 USART1
	HAL_GPIO_Init(GPIOA, &GPIO_Initure); // 初始化 PA9、PA10
    }
}

void UART_Transmit(uint8_t *pData, uint16_t Size)
{
    HAL_UART_Transmit(&UART1_Handler, pData, Size, HAL_MAX_DELAY);
}

void UART_Receive(uint8_t *pData, uint16_t Size)
{
    HAL_UART_Receive(&UART1_Handler, pData, Size, HAL_MAX_DELAY);
}

主函数程序如下:

uint8_t buffer[10];

int main(void)
{
    CLOCLK_Init(); // 配置系统时钟为168M
    UART_Init();
	
    while(1)
    {
	UART_Receive(buffer, 5);
	UART_Transmit(buffer, 5);
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值