STM32 笔记 01:如何使用 CubeMX 配置串口中断接收不定长数据

一. 前言

  • 测试时使用的 MCU 是:STM32F103C8Tx
  • 测试时使用的 CubeMX 版本是:6.1

二. CubeMX 配置

1. 串口配置

image-20210419123159640

image-20210419123211857

2. 时钟配置

image-20210419123225483

三. 主要代码

1. 在 .h 中定义串口控制类,与相关宏

/* code begin define */
#define	USART_2_RECV_DATA_BUF_ROW_NUM  2  // 串口 2 数据接收缓存行数。
#define	USART_2_RECV_DATA_BUF_COL_NUM  10 // 串口 2 数据接收缓存列数。
/* code end define */

/* code begin data type */
typedef	struct
{
	UART_HandleTypeDef* huart;      // 串口句柄
	
	uint8_t indexForRecvDataBufRow;// 数据接收缓存的行索引。                                                   
	uint8_t indexForRecvDataBufCol;// 数据接收缓存的列索引。   
	
	uint8_t recvDataBuf[USART_2_RECV_DATA_BUF_ROW_NUM][USART_2_RECV_DATA_BUF_COL_NUM];// 数据接收缓存。
	
	void (*sendData)(uint8_t* data, uint16_t data_len);// 发送数据。
	void (*recvDataInIntrrupt)(void);                  // 在中断中接收数据。该方法需要放在 USART2_IRQHandler 函数中。
	void (*processData)(void);                         // 处理数据、需要自己填写如何解析,处理数据。该方法可放在 while 循环或 recvDataInIntrrupt 中。  	
}objUsart2;// 串口 2 控制类。
/* code end data type */

2. 在 .c 中创建串口控制类对象,声明需要实现的相关方法

/* code begin variable definition */
objUsart2 userUsart2;
/* code end variable definition */

/* code begin function statement */
void initUserUsart2(void);                                        
static void userUsart2_sendData(uint8_t* data, uint16_t data_len);
static void userUsart2_recvDataInIntrrupt(void);                
static void userUsart2_processData(void);                   
/* code end function statement */

3. 在 .c 中实现具体方法

/* code begin function body */
void initUserUsart2(void)
{
	userUsart2.huart                  = &huart2;
	userUsart2.indexForRecvDataBufRow = 0;
	userUsart2.indexForRecvDataBufCol = 0;
	
	memset(userUsart2.recvDataBuf, 0, USART_2_RECV_DATA_BUF_ROW_NUM * USART_2_RECV_DATA_BUF_COL_NUM);        // 清空缓存。
	
	userUsart2.sendData           = userUsart2_sendData;
	userUsart2.recvDataInIntrrupt = userUsart2_recvDataInIntrrupt;
	userUsart2.processData        = userUsart2_processData;
	
  __HAL_UART_ENABLE_IT(userUsart2.huart, UART_IT_RXNE); // 使能接收中断。
  __HAL_UART_ENABLE_IT(userUsart2.huart, UART_IT_IDLE); // 使能空闲中断。
}
static void userUsart2_sendData(uint8_t* data, uint16_t data_len)
{
  HAL_UART_Transmit(userUsart2.huart, data, data_len, 0xff);
}
static void userUsart2_recvDataInIntrrupt(void)
{
	// 判断缓存是否还有空间。
	if(userUsart2.indexForRecvDataBufRow  < USART_2_RECV_DATA_BUF_ROW_NUM && userUsart2.indexForRecvDataBufCol < USART_2_RECV_DATA_BUF_COL_NUM)
	{	
		if(__HAL_UART_GET_FLAG(userUsart2.huart, UART_FLAG_RXNE) != RESET)// 判断是否触发接收中断。
		{
			// 从串口寄存器中读取一个字节保存到 ch。注意以下这段代码必须放在接收中断中。
			uint8_t ch;
			HAL_UART_Receive(userUsart2.huart, &ch, 1, 1000);
			
			userUsart2.recvDataBuf[userUsart2.indexForRecvDataBufRow][userUsart2.indexForRecvDataBufCol++] = ch;
			
			__HAL_UART_CLEAR_FLAG(userUsart2.huart, UART_FLAG_RXNE);
		}
		
		if(__HAL_UART_GET_FLAG(userUsart2.huart, UART_FLAG_IDLE) != RESET)// 判断是否触发空闲中断。
    {
			userUsart2.indexForRecvDataBufRow++;
      userUsart2.indexForRecvDataBufCol = 0;
			
      __HAL_UART_CLEAR_IDLEFLAG(userUsart2.huart);
    }
	}
}
static void userUsart2_processData(void)
{
	if(userUsart2.indexForRecvDataBufRow > 0)// 如果缓存中存在数据,则处理它。
	{
		uint8_t row = userUsart2.indexForRecvDataBufRow - 1;
		userUsart2.sendData(&userUsart2.recvDataBuf[row][0], USART_2_RECV_DATA_BUF_COL_NUM);
		
		memset(&userUsart2.recvDataBuf[row][0], 0, USART_2_RECV_DATA_BUF_COL_NUM);
		userUsart2.indexForRecvDataBufRow--;
	}
}
/* code end function body */

4. 在 .h 中声明串口控制类对象,与串口初始化函数

/* code begin variable statement */
extern objUsart2 userUsart2;// 串口 2 控制类对象。
/* code end variable statement */

/* code begin function statement */
void initUserUsart2(void);// 初始串口 2.
/* code end function statement */
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Simple Man ZHR

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值