【stm32外设】封装在hal库上的串口接收驱动

【stm32外设】封装在hal库上的串口接收

串口通讯(Serial Communication)是一种设备间非常常用的串行通讯方式。

这里使用的是基于cubemx生成的代码上,使用的是空闲中断机制(非DMA)来接收数据**。**

cubemx配置操作为

在这里插入图片描述

bsp_usart.c

#include "./usart/bsp_usart.h"

#include <string.h>


/* 缓存串口接收数据的结构体 */
typedef struct stru_usart
{
	unsigned char buf[USART_BUF_SIZE];
	unsigned char flag;
	unsigned int  len;
} stru_usart_t;


#if USART1_EN
	static stru_usart_t usart_1;		/* 缓存串口1接收到的数据 */
#endif

#if USART2_EN
	static stru_usart_t usart_2;		/* 缓存串口2接收到的数据 */
#endif

#if USART3_EN
	static stru_usart_t usart_3;		/* 缓存串口3接收到的数据 */
#endif

#if USART4_EN
	static stru_usart_t usart_4;		/* 缓存串口4接收到的数据 */
#endif

#if USART5_EN
	static stru_usart_t usart_5;		/* 缓存串口5接收到的数据 */
#endif


/* bsp_usart_init:串口接收初始化函数
 * huart	 	想要初始化的串口的句柄
 * huart_type	想要初始化的串口编号,BSP_USART
 * return		成功返回0,失败返回-1 */
int bsp_usart_init
	(
	UART_HandleTypeDef 	*huart,
	unsigned char 		huart_type
	)
{
	switch (huart_type)
	{
		/* 串口1 */
		#if USART1_EN
			case BSP_USART_1:
				/* 开启串口接收中断 */
				HAL_UART_Receive_IT(huart, usart_1.buf, USART_BUF_SIZE);	
				/* 使能空闲中断 */
				__HAL_UART_ENABLE_IT(huart, UART_IT_IDLE);		
				/* 清除第一次空闲中断标志,方便后续接收数据 */
				__HAL_UART_CLEAR_IDLEFLAG(huart);							
				return 0;
		#endif
			
		/* 串口2 */
		#if USART2_EN
			case BSP_USART_2:
				HAL_UART_Receive_IT(huart, usart_2.buf, USART_BUF_SIZE);	
				__HAL_UART_ENABLE_IT(huart, UART_IT_IDLE);					
				__HAL_UART_CLEAR_IDLEFLAG(huart);							
				return 0;
		#endif
		
		/* 串口3 */
		#if USART3_EN
			case BSP_USART_3:
				HAL_UART_Receive_IT(huart, usart_3.buf, USART_BUF_SIZE);	
				__HAL_UART_ENABLE_IT(huart, UART_IT_IDLE);					
				__HAL_UART_CLEAR_IDLEFLAG(huart);							
				return 0;
		#endif
			
		/* 串口4 */
		#if USART4_EN
			case BSP_USART_4:
				HAL_UART_Receive_IT(huart, usart_4.buf, USART_BUF_SIZE);	
				__HAL_UART_ENABLE_IT(huart, UART_IT_IDLE);					
				__HAL_UART_CLEAR_IDLEFLAG(huart);							
				return 0;
		#endif
		
		/* 串口5 */
		#if USART5_EN
			case BSP_USART_5:
				HAL_UART_Receive_IT(huart, usart_5.buf, USART_BUF_SIZE);	
				__HAL_UART_ENABLE_IT(huart, UART_IT_IDLE);					
				__HAL_UART_CLEAR_IDLEFLAG(huart);							
				return 0;
		#endif
	}
	
	return -1;
}


/* bsp_usart_handler:串口接收的中断处理函数
 * huart	 	串口的句柄
 * huart_type	串口编号,BSP_USART
 * return		成功返回0,失败返回-1 */
int bsp_usart_handler
	(
	UART_HandleTypeDef  *huart,
	unsigned char 		huart_type
	)
{
	switch (huart_type)
	{
		#if USART1_EN
			case BSP_USART_1:
				/* 判断是否为空闲中断 */
				if (__HAL_UART_GET_FLAG(huart, UART_FLAG_IDLE) != RESET)	
				{
					usart_1.flag = 1;
					/* 计算获取总共接收到的buf的长度 */
					usart_1.len = USART_BUF_SIZE - (*huart).RxXferCount;	
					/* 清除空闲中断标志,方便后续接收数据 */
					__HAL_UART_CLEAR_IDLEFLAG(huart);		
					/* 停止串口接收中断 */
					HAL_UART_AbortReceive_IT(huart);						
					/* 重新开启串口接收中断 */
					HAL_UART_Receive_IT(huart, usart_1.buf, USART_BUF_SIZE);
					return 0;
				}
		#endif
		
		#if USART2_EN
			case BSP_USART_2:
				if (__HAL_UART_GET_FLAG(huart, UART_FLAG_IDLE) != RESET)	
				{
					usart_2.flag = 1;
					usart_2.len = USART_BUF_SIZE - (*huart).RxXferCount;	
					__HAL_UART_CLEAR_IDLEFLAG(huart);						
					HAL_UART_AbortReceive_IT(huart);						
					HAL_UART_Receive_IT(huart, usart_2.buf, USART_BUF_SIZE);
					return 0;
				}
		#endif
		
		#if USART3_EN
			case BSP_USART_3:
				if (__HAL_UART_GET_FLAG(huart, UART_FLAG_IDLE) != RESET)	
				{
					usart_3.flag = 1;
					usart_3.len = USART_BUF_SIZE - (*huart).RxXferCount;	
					__HAL_UART_CLEAR_IDLEFLAG(huart);						
					HAL_UART_AbortReceive_IT(huart);						
					HAL_UART_Receive_IT(huart, usart_3.buf, USART_BUF_SIZE);
					return 0;
				}
		#endif
		
		#if USART4_EN
			case BSP_USART_4:
				if (__HAL_UART_GET_FLAG(huart, UART_FLAG_IDLE) != RESET)	
				{
					usart_4.flag = 1;
					usart_4.len = USART_BUF_SIZE - (*huart).RxXferCount;	
					__HAL_UART_CLEAR_IDLEFLAG(huart);						
					HAL_UART_AbortReceive_IT(huart);						
					HAL_UART_Receive_IT(huart, usart_4.buf, USART_BUF_SIZE);
					return 0;
				}
		#endif
		
		#if USART5_EN
			case BSP_USART_5:
				if (__HAL_UART_GET_FLAG(huart, UART_FLAG_IDLE) != RESET)	
				{
					usart_5.flag = 1;
					usart_5.len = USART_BUF_SIZE - (*huart).RxXferCount;	
					__HAL_UART_CLEAR_IDLEFLAG(huart);						
					HAL_UART_AbortReceive_IT(huart);						
					HAL_UART_Receive_IT(huart, usart_5.buf, USART_BUF_SIZE);
					return 0;
				}
		#endif
	}
	
	return -1;
}


/* bsp_usart_get:获取串口接收到的数据的函数
 * buf		 	获取到的数据复制到buf里
 * huart_type	串口编号,BSP_USART
 * return		接收到的数据长度,失败返回-1 */
int bsp_usart_get
	(
	unsigned char buf[],
	unsigned char huart_type
	)
{
	int len = -1;
	switch (huart_type)
	{
		#if USART1_EN
			case BSP_USART_1:
				if (usart_1.flag == 1)	/* 判断串口是否有接收到数据 */
				{
					strncpy((char*)buf, (const char*)usart_1.buf, usart_1.len);
					len = usart_1.len;
					memset(&usart_1, 0, sizeof(stru_usart_t));
				}
				break;
		#endif
		
		#if USART2_EN
			case BSP_USART_2:
				if (usart_2.flag == 1)	/* 判断串口是否有接收到数据 */
				{
					strncpy((char*)buf, (const char*)usart_2.buf, usart_2.len);
					len = usart_2.len;
					memset(&usart_2, 0, sizeof(stru_usart_t));
				}
				break;
		#endif
		
		#if USART3_EN
			case BSP_USART_3:
				if (usart_3.flag == 1)	/* 判断串口是否有接收到数据 */
				{
					strncpy((char*)buf, (const char*)usart_3.buf, usart_3.len);
					len = usart_3.len;
					memset(&usart_3, 0, sizeof(stru_usart_t));
				}
				break;
		#endif
		
		#if USART4_EN
			case BSP_USART_4:
				if (usart_4.flag == 1)	/* 判断串口是否有接收到数据 */
				{
					strncpy((char*)buf, (const char*)usart_4.buf, usart_4.len);
					len = usart_4.len;
					memset(&usart_4, 0, sizeof(stru_usart_t));
				}
				break;
		#endif
		
		#if USART5_EN
			case BSP_USART_5:
				if (usart_5.flag == 1)	/* 判断串口是否有接收到数据 */
				{
					strncpy((char*)buf, (const char*)usart_5.buf, usart_5.len);
					len = usart_5.len;
					memset(&usart_5, 0, sizeof(stru_usart_t));
				}
				break;
		#endif
	}
	
	return len;
}

bsp_usart.h

/**
 * author:临木木
 * 适用于stm32裸机的usart接收驱动(非DMA)
 * 主程序启用前运行bsp_usart_init()函数初始化串口配置
 * bsp_usart_handler() 需要放到#include "stm32f1xx_it.c"文件的USARTx_IRQHandler()函数里
 */
#ifndef __BSP_USART_H__
#define __BSP_USART_H__

#include "usart.h"


#define USART_BUF_SIZE	256

/* 启用哪个置1即可 */
#define USART1_EN	1
#define USART2_EN	1
#define USART3_EN	1
#define USART4_EN	0
#define USART5_EN	0

/* huart_type */
enum BSP_USART
{
	BSP_USART_1,
	BSP_USART_2,
	BSP_USART_3,
	BSP_USART_4,
	BSP_USART_5
};


int bsp_usart_init
	(
	UART_HandleTypeDef 	*huart,
	unsigned char 		huart_type
	);
	
int bsp_usart_handler
	(
	UART_HandleTypeDef  *huart,
	unsigned char 		huart_type
	);
	
int bsp_usart_get
	(
	unsigned char buf[],
	unsigned char huart_type
	);


#endif

使用示例:

// 初始化
bsp_usart_init(&huart2, BSP_USART_2);

// 接收数据
while (1)
{
 	static unsigned char usart2_buf[256];
	static int usart2_len = 0;
	
	usart2_len = bsp_usart_get(usart2_buf, BSP_USART_2);
	if (usart2_len != -1)
	{
		HAL_UART_Transmit(&huart2, usart2_buf, usart2_len, 1000);
	}   
}

参考:

  • 9
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值