STM32F407HAL库-7.串口数据收发-中断

串口数据收发(中断)初始化步骤:

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

 
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库中,供串口中断数据收发的函数分别如下:

  • 接收数据中断函数:
HAL_StatusTypeDef HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size);

函数实现功能如下:

①:函数中传入3个参数,分别为串口初始化结构体参数UART_HandleTypeDef、接收数据缓冲区地址pData、接收数据缓冲区宽度Size。

②:函数首先判断Rx进程是否处于正常运行状态,如果不是则退出函数,返回错误。

③:初始化串口结构体UART_HandleTypeDef,将函数传入参数,分别赋值给结构体变量,并初始化错误代码变量“Errorcode”和Rx进程的状态。

④:使能串口错误中断(包括:帧错误、噪声错误、溢出错误)

⑤:使能串口校验错误和接收寄存器非空中断。

HAL_StatusTypeDef HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
{
  /* 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->pRxBuffPtr = pData;
    huart->RxXferSize = Size;
    huart->RxXferCount = Size;
    
    huart->ErrorCode = HAL_UART_ERROR_NONE;
    huart->RxState = HAL_UART_STATE_BUSY_RX;
    
    /* Process Unlocked */
    __HAL_UNLOCK(huart);
        
    /* Enable the UART Error Interrupt: (Frame error, noise error, overrun error) */
    SET_BIT(huart->Instance->CR3, USART_CR3_EIE);

    /* Enable the UART Parity Error and Data Register not empty Interrupts */
    SET_BIT(huart->Instance->CR1, USART_CR1_PEIE | USART_CR1_RXNEIE);
    
    return HAL_OK;
  }
  else
  {
    return HAL_BUSY; 
  }
}
  • 发送数据中断函数:
HAL_StatusTypeDef HAL_UART_Transmit_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size);

函数实现功能如下:

①:函数中传入3个参数,分别为串口初始化结构体参数UART_HandleTypeDef、发送数据缓冲区地址pData、发送数据缓冲区宽度Size。

②:函数首先判断Tx进程是否处于正常运行状态,如果不是则退出函数,返回错误。

③:初始化串口结构体UART_HandleTypeDef,将函数传入参数,分别赋值给结构体变量,并初始化错误代码变量“Errorcode”和Tx进程的状态。

④:使能串口发送寄存器为空中断。

HAL_StatusTypeDef HAL_UART_Transmit_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
{
  /* Check that a Tx process is not already ongoing */
  if(huart->gState == HAL_UART_STATE_READY)
  {
    if((pData == NULL ) || (Size == 0)) 
    {
      return HAL_ERROR;
    }
    
    /* Process Locked */
    __HAL_LOCK(huart);
    
    huart->pTxBuffPtr = pData;
    huart->TxXferSize = Size;
    huart->TxXferCount = Size;

    huart->ErrorCode = HAL_UART_ERROR_NONE;
    huart->gState = HAL_UART_STATE_BUSY_TX;

    /* Process Unlocked */
    __HAL_UNLOCK(huart);

    /* Enable the UART Transmit data register empty Interrupt */
    SET_BIT(huart->Instance->CR1, USART_CR1_TXEIE);
    
    return HAL_OK;
  }
  else
  {
    return HAL_BUSY;   
  }
}

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

#include "bsp_uart.h"

UART_HandleTypeDef UART1_Handler; //UART 句柄

uint8_t buffer; // 串口接收数据

// 初始化串口函数
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); // 初始化串口
		
	// 开启接收中断:标志位UART_IT_RXNE,并且设置接收缓冲区以及接收缓冲区接收最大数据量
	HAL_UART_Receive_IT(&UART1_Handler, &buffer, RXBUFFERSIZE);	
}

// 初始化低级硬件
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

		HAL_NVIC_SetPriority(USART1_IRQn, 2, 1); // 设置串口中断优先级
		HAL_NVIC_EnableIRQ(USART1_IRQn); // 使能串口中断
	}
}

// 串口中断服务函数
void	USART1_IRQHandler(void)
{
	HAL_UART_IRQHandler(&UART1_Handler); // 清空中断标志,取消中断使能,并间接调用回调函数
}

// 串口接收回调函数
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
	UART_Transmit(&buffer, RXBUFFERSIZE); // 将接收到的数据发送出去
	HAL_UART_Receive_IT(&UART1_Handler, &buffer, 1);	// 由于接收一次数据,中断使能会被清除,所以这行代码必须添加	
}

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

 

你可能感兴趣的:(STM32F4外设开发)