STM32 Cubemx配置串口收发

文章目录

前言

最近学到了串口收发,简单记录一下注意事项。

注意事项

Cubemx配置

以使用USART1为例。

USART1需配置成异步工作模式Asynchronous

并且需要使能NVIC

printf重定向

我偏向于在stm32f1xx_it.c文件中对printf进行重定向,重定向函数如下。

cpp 复制代码
int fputc(int ch,FILE * fp)
{
	HAL_UART_Transmit(&huart1,(uint8_t * )&ch,1,0xffff);
	return ch;
}

同时需包含头文件路径#include "stdio.h"

修改工程属性

在工程属性Target下,勾选Use MicroLIB

至此,可以由printf语句经USART1发送数据了。

修改源码

  1. 添加变量定义
cpp 复制代码
/* USER CODE BEGIN Private defines */
#define USART_REC_LEN 200
#define RXBUFFERSIZE 1
extern	uint16_t	USART_RX_STA;  
extern	uint8_t		USART_RX_BUF[USART_REC_LEN];
extern	uint8_t		aRxBuffer[RXBUFFERSIZE];
/* USER CODE END Private defines */
  1. 在Cubemx生成的串口初始化函数MX_USART1_UART_Init增加如下语句
cpp 复制代码
HAL_UART_Receive_IT(&huart1, (uint8_t *)aRxBuffer, RXBUFFERSIZE);
  
  1. 在stm32f1xx_it.c文件中添加如下函数
cpp 复制代码
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
	if(huart->Instance==USART1)//
	{
		if((USART_RX_STA&0x8000)==0)//
		{
			if(USART_RX_STA&0x4000)//
			{
				if(aRxBuffer[0]!=0x0a)USART_RX_STA=0;//
				else USART_RX_STA|=0x8000;	//
			}
			else //
			{	
				if(aRxBuffer[0]==0x0d)USART_RX_STA|=0x4000;
				else
				{
					USART_RX_BUF[USART_RX_STA&0X3FFF]=aRxBuffer[0] ;
					USART_RX_STA++;
					if(USART_RX_STA>(USART_REC_LEN-1))USART_RX_STA=0;//
				}		 
			}
		}
	}
}
  1. 在stm32f1xx_it.c文件中找到USART1_IRQHandler并修改为如下函数:
cpp 复制代码
void USART1_IRQHandler(void)
{
	uint32_t timeout=0;
  /* USER CODE BEGIN USART1_IRQn 0 */

  /* USER CODE END USART1_IRQn 0 */
  HAL_UART_IRQHandler(&huart1);
  /* USER CODE BEGIN USART1_IRQn 1 */
	timeout=0;
	while (HAL_UART_GetState(&huart1) != HAL_UART_STATE_READY)//
	{
		timeout++;//
		if(timeout>HAL_MAX_DELAY) break;		

	}

	timeout=0;
	while(HAL_UART_Receive_IT(&huart1, (uint8_t *)aRxBuffer, RXBUFFERSIZE) != HAL_OK)//Ò>>´Î´¦ÀíÍê³ÉÖ®ºó£¬ÖØÐ¿ªÆôÖжϲ¢ÉèÖÃRxXferCountΪ1
	{
		timeout++; //³¬Ê±´¦Àí
		if(timeout>HAL_MAX_DELAY) break;	
	}
  /* USER CODE END USART1_IRQn 1 */
}

测试函数

cpp 复制代码
while (1)
  {
		uint8_t len=0;
		static uint16_t times = 0;
		printf("%d\r\n",times++);
		HAL_Delay(500);
		HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_5);
		HAL_GPIO_TogglePin(GPIOE,GPIO_PIN_5);
		if(USART_RX_STA&0x8000)
		{					    
			len=USART_RX_STA&0x3fff;//µÃµ½´Ë´Î½ÓÊÕµ½µÄÊý¾Ý³¤¶È
			printf("\r\nÄú·¢Ë͵ÄÏûϢΪ:\r\n");
			HAL_UART_Transmit(&huart1,(uint8_t*)USART_RX_BUF,len,1000);	//·¢ËͽÓÊÕµ½µÄÊý¾Ý
			while(__HAL_UART_GET_FLAG(&huart1,UART_FLAG_TC)!=SET);		//µÈ´ý·¢ËͽáÊø
			printf("\r\n\r\n");//²åÈë>>>>ÐÐ
			USART_RX_STA=0;
		}
		else
		{
			if(times%20==0)printf("ÇëÊäÈëÊý¾Ý,ÒÔ>>سµ¼ü½áÊø\r\n");  
			if(times%2==0);//LED0=!LED0;//ÉÁ˸LED,ÌáʾϵͳÕýÔÚÔËÐÐ.
		} 
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
相关推荐
国科安芯1 小时前
火箭传感器控制单元的抗辐照MCU选型与环境适应性验证
单片机·嵌入式硬件·架构·risc-v·安全性测试
-Springer-2 小时前
STM32 学习 —— 个人学习笔记5(EXTI 外部中断 & 对射式红外传感器及旋转编码器计数)
笔记·stm32·学习
LS_learner2 小时前
树莓派(ARM64 架构)Ubuntu 24.04 (Noble) 系统 `apt update` 报错解决方案
嵌入式硬件
来自晴朗的明天3 小时前
16、电压跟随器(缓冲器)电路
单片机·嵌入式硬件·硬件工程
钰珠AIOT3 小时前
在同一块电路板上同时存在 0805 0603 不同的封装有什么利弊?
嵌入式硬件
代码游侠3 小时前
复习——Linux设备驱动开发笔记
linux·arm开发·驱动开发·笔记·嵌入式硬件·架构
代码游侠14 小时前
学习笔记——设备树基础
linux·运维·开发语言·单片机·算法
xuxg200516 小时前
4G 模组 AT 命令解析框架课程正式发布
stm32·嵌入式·at命令解析框架
CODECOLLECT17 小时前
京元 I62D Windows PDA 技术拆解:Windows 10 IoT 兼容 + 硬解码模块,如何降低工业软件迁移成本?
stm32·单片机·嵌入式硬件