HAL库使用太死板
HAL串口中断接收
HAL库使用起来太不灵活,限制太多,后面如有时间,将使用寄存器和HAL库混合操作的方式。
如使用串口中断接收,在接收到数据后,库里做了关闭接收非空中断RXNEIE,如下
HAL库DMA发送
目前,我用的是DMA发送,本来向直接将数据扔给DMA,不想开发送DMA的中断,但是,HAL库考虑的比较周详,使用HAL库的DMA发送API,就会使用了DMA句柄中的相关标志位,这些标志位得你开了中断后,在DMA发送完成后,才会做相应的清除,并且,使用了__HAL_LOCK(),这样你用了他的库发送,剩下的其他处理你也得用他的库;前面说的,用了库的DMA发送,不开中断,就会因为上次是__HAL_LOCK()状态,导致无法继续执行,并且用了DMA发送后,还会标志几个标志位为BUSY状态,你如果不开中断,也得清除,总的来说,使用起来还是挺麻烦的,平白无故的多开了一个中断。
以下代码为STM32F7串口1的DMA发送和串口接收中断程序
实现代码
/**
******************************************************************************
* @file driver_uart.c
* @author Quentin.Que
* @version V.0
* @date 2017-12-14
* @brief 所有串口底层的配置
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "common_config.h"
#include "stm32f7xx_hal.h"
#include "driver_uart.h"
/* Macros ------------------------------------------------------------------*/
/* Enumerations ------------------------------------------------------------------*/
/* Type Definitions ------------------------------------------------------------------*/
#define DEF_UART1_RX_BUF_SIZE 1
#define DEF_UART1_DMA_TX_BUF_SIZE 200
/* Private variables ---------------------------------------------------------*/
static UART_HandleTypeDef m_Uart1Handler;
static DMA_HandleTypeDef m_DmaUart1Handler;
static INT8U Uart1RxBuf[DEF_UART1_RX_BUF_SIZE];
static INT8U Uart1DmaTxBuf[DEF_UART1_DMA_TX_BUF_SIZE];
static UART_RECEIVE_CALLBACK pFunUart1Callback = NULL;
/* Private function prototypes -----------------------------------------------*/
/***********************************************************************
* @brief 初始化串口1
* @param baudrate:波特率
* @retval NONE
***********************************************************************/
static void DRIVER_Uart1Init(INT32U baudrate)
{
m_Uart1Handler.Instance = USART1;
m_Uart1Handler.Init.BaudRate = baudrate;
m_Uart1Handler.Init.HwFlowCtl = UART_HWCONTROL_NONE;
m_Uart1Handler.Init.Mode = UART_MODE_TX_RX;
m_Uart1Handler.Init.Parity = UART_PARITY_NONE;
m_Uart1Handler.Init.StopBits = UART_STOPBITS_1;
m_Uart1Handler.Init.WordLength = UART_WORDLENGTH_8B;
HAL_UART_Init(&m_Uart1Handler); /* 串口初始化 */
HAL_UART_Receive_IT(&m_Uart1Handler, (INT8U *)Uart1RxBuf, DEF_UART1_RX_BUF_SIZE); /* 开中断,设置接收buf和大小 */
}
/**************************************************************************************
* @brief 设置串口1接收中断
* @param revice_callback:接收回调函数
* @retval NONE
**************************************************************************************/
static void DRIVER_Uart1SetReviceCallback(UART_RECEIVE_CALLBACK revice_callback)
{
pFunUart1Callback = revice_callback;
}
/***************************************************************************************
* @brief DRIVER_UART1SendData
* @param 串口1发送
* @retval NONE
***************************************************************************************/
static BOOLEAN DRIVER_UART1SendData(INT8U* pdata, INT16U len)
{
INT16U real_len = 0;
real_len = len > DEF_UART1_DMA_TX_BUF_SIZE ? DEF_UART1_DMA_TX_BUF_SIZE : len; /* 强制截取 不能超过定义的缓存大小 */
memcpy(Uart1DmaTxBuf, pdata,real_len);
while(0 != __HAL_DMA_GET_COUNTER(&m_DmaUart1Handler)) /* 等待发送完成 */
{
}
do
{
}while(HAL_OK != HAL_UART_Transmit_DMA(&m_Uart1Handler, Uart1DmaTxBuf, real_len));
return TRUE;
}
/***************************************************************************************
* @brief HAL_UART_MspInit 会被HAL_UART_Init()调用
* @param 串口句柄
* @retval NONE
***************************************************************************************/
void HAL_UART_MspInit(UART_HandleTypeDef *huart)
{
GPIO_InitTypeDef GPIO_Initure;
if(USART1 == huart->Instance)
{
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_USART1_CLK_ENABLE();
__HAL_RCC_DMA2_CLK_ENABLE();
GPIO_Initure.Pin=GPIO_PIN_9;
GPIO_Initure.Mode=GPIO_MODE_AF_PP;
GPIO_Initure.Pull=GPIO_PULLUP;
GPIO_Initure.Speed=GPIO_SPEED_FAST;
GPIO_Initure.Alternate=GPIO_AF7_USART1;
HAL_GPIO_Init(GPIOA,&GPIO_Initure);
GPIO_Initure.Pin=GPIO_PIN_10;
HAL_GPIO_Init(GPIOA,&GPIO_Initure);
/* Peripheral DMA init*/
m_DmaUart1Handler.Instance = DMA2_Stream7;
m_DmaUart1Handler.Init.Channel = DMA_CHANNEL_4;
m_DmaUart1Handler.Init.Direction = DMA_MEMORY_TO_PERIPH;
m_DmaUart1Handler.Init.PeriphInc = DMA_PINC_DISABLE;
m_DmaUart1Handler.Init.MemInc = DMA_MINC_ENABLE;
m_DmaUart1Handler.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
m_DmaUart1Handler.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
m_DmaUart1Handler.Init.Mode = DMA_NORMAL;
m_DmaUart1Handler.Init.Priority = DMA_PRIORITY_LOW;
HAL_DMA_DeInit(&m_DmaUart1Handler);
HAL_DMA_Init(&m_DmaUart1Handler);
__HAL_LINKDMA(huart,hdmatx,m_DmaUart1Handler);
HAL_NVIC_SetPriority(DMA2_Stream7_IRQn, 3, 0);
HAL_NVIC_EnableIRQ(DMA2_Stream7_IRQn);
HAL_NVIC_EnableIRQ(USART1_IRQn);
HAL_NVIC_SetPriority(USART1_IRQn,3,0);
}
}
/********************************************************************************
* @brief HAL_UART_RxCpltCallback 进入中断后HAL库会调用这个函数
* @param 串口句柄
* @retval NONE
*********************************************************************************/
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
if(USART1 == huart->Instance)
{
if(NULL != pFunUart1Callback)
{
pFunUart1Callback(Uart1RxBuf[0]); /* 将接收到的数据通过回调传出 */
}
do
{
}while(HAL_OK != HAL_UART_Receive_IT(&m_Uart1Handler, (INT8U *)Uart1RxBuf, DEF_UART1_RX_BUF_SIZE)); /* 开中断,设置接收buf和大小 */
}
}
/*******************************************************************************
* @brief USART1_IRQHandler 串口1中断函数
* @param 串口句柄
* @retval NONE
*********************************************************************************/
void USART1_IRQHandler(void)
{
HAL_UART_IRQHandler(&m_Uart1Handler);
}
/*******************************************************************************
* @brief DMA2_Stream7_IRQHandler 串口1DMA发送中断
* @param NONE
* @retval NONE
*********************************************************************************/
void DMA2_Stream7_IRQHandler(void)
{
HAL_DMA_IRQHandler(&m_DmaUart1Handler);
}
/***********************************************************************
* @brief 初始化串口
* @param port:串口号 baudrate:波特率 prx_fun:接收回调函数
* @retval TRUE:成功 FALSE:失败
***********************************************************************/
BOOLEAN DRIVER_UARTInit(INT8U port, INT32U baudrate, UART_RECEIVE_CALLBACK prx_fun)
{
switch(port)
{
case DRIVER_UART_PORT1:
DRIVER_Uart1Init(baudrate);
DRIVER_Uart1SetReviceCallback(prx_fun);
break;
default:
return FALSE;
}
return TRUE;
}
/***********************************************************************
* @brief 串口发送
* @param port:串口号 pdata:数据起始地址 len:长度
* @retval TRUE:成功 FALSE:失败
***********************************************************************/
BOOLEAN DRIVER_UARTWrite(INT8U port, INT8U* pdata, INT16U len)
{
switch(port)
{
case DRIVER_UART_PORT1:
return DRIVER_UART1SendData(pdata, len);
default:
return FALSE;
}
}
上一篇:STM32串口发送不正常
下一篇:STM32F10X USART 中断接受+发送,测试无误
推荐阅读最新更新时间:2024-03-16 16:05