STM32 UART收发-中断方式接收-重定向printf函数

STM32 UART串口收发与中断方式接收


环境:
1、STM32CubeMX 5.3
2、Atollic TrueSTUDIO for STM32 9.3.0
3、战舰迷你板(stm32f103rb)


(一)配置串口

波特率:115200
数据长度:8bit
停止位:1位
校验位:无

STM32 UART收发-中断方式接收-重定向printf函数_第1张图片

(二)配置串口接收中断

设置中断分组为第二组,使能串口中断,串口中断优先级设置成主优先级3,次优先级0:
STM32 UART收发-中断方式接收-重定向printf函数_第2张图片

(三)修改代码

在函数MX_USART1_UART_Init中添加如下代码,使能串口中断:

HAL_UART_Receive_IT(&huart1, RecvBuffer, 1);		// 使能接收中断

然后覆写接收中断回调函数:

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
	if (huart->Instance == huart1.Instance)
	{
		HAL_UART_Transmit(&huart1, RecvBuffer, 1, 0xFFFF);		// 将收到的数据在发回去
		HAL_UART_Receive_IT(&huart1, RecvBuffer, 1);			// 再次使能接收中断
	}
}

然后添加如下代码重定向printf函数:

#ifdef __GNUC__
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif
PUTCHAR_PROTOTYPE
{
	HAL_UART_Transmit(&huart1, (uint8_t *) &ch, 1, 100);
	return ch;
}

效果如下图:
STM32 UART收发-中断方式接收-重定向printf函数_第3张图片

(四)使printf函数可以打印浮点数

项目->属性:
STM32 UART收发-中断方式接收-重定向printf函数_第4张图片


(五)重新实现printf函数

void debug_printf(const void* fmt, ...)
{
	static char buf[1024];
    va_list ap;
    va_start(ap, fmt);
    vsprintf(buf, (char *)fmt, ap);
    va_end(ap);
    HAL_UART_Transmit(&huart1, (uint8_t *)buf, strlen(buf), 100);
}

(六)串口接收与处理

#define UART1_RX_LEN 0xFF 				// 串口一次接受数据的最大长度
uint8_t UART1_RX_BUF[UART1_RX_LEN];		// 串口接收缓存
uint8_t UART1_RX_BYTE = 0;				// 串口中断接收一个字节
uint16_t UART1_RX_STA = 0;				// 串口接受状态,第15位表示接收到了换行符,第14为表示接收到了回车符,第0~7位表示本次接收到的数据长度

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
	if (huart->Instance == huart1.Instance)
	{
		if ((UART1_RX_STA & 0x8000) == 0)			// 接收未完毕
		{
			if (UART1_RX_STA & 0x4000)				// 接收到了回车符
			{
				if (UART1_RX_BYTE == '\n')			// 本次接受到的是换行符
					UART1_RX_STA |= 0x8000;			// 标记接收结束
				else
					UART1_RX_STA = 0;				// 否则接收错误,状态置为初始
			}
			else
			{
				if (UART1_RX_BYTE == '\r')			// 本次接收到的是回车符
					UART1_RX_STA |= 0x4000;			// 标记接收到了回车符
				else
				{
					UART1_RX_BUF[UART1_RX_STA & 0x3FFF] = UART1_RX_BYTE;	// 本次接收到的是数据
					if (UART1_RX_STA++ >= UART1_RX_LEN)						// 连续接收到的数据高于最大接收长度,则视为接收错误
						UART1_RX_STA = 0;									// 状态置为初始
				}
			}
		}
		HAL_UART_Receive_IT(&huart1, &UART1_RX_BYTE, 1);					// 再次使能接收中断
	}
}

/**
 * 串口1接收处理函数
 */
void UART1_RecvHandler(void)
{
	if (UART1_RX_STA & 0x8000)							// 有数据收到
	{
		UART1_RX_BUF[UART1_RX_STA & 0x3FFF] = '\0';		// 添加结束符
		printf("%s\r\n", UART1_RX_BUF);					// 串口打印出来
		UART1_RX_STA = 0;								// 状态置为初始
	}
}


ends…

你可能感兴趣的:(STM32)