cubeIDE配置STM32串口通信及调试问题


本工程使用STM32F407ZET6
串口部分配置套路基本一致,串口接收中断部分提供两种方式,一种只使用一个标志位记录接收状态,另一种定义结构体,分别记录接收发送状态。
printf函数直接使用无输出,和keil有区别,需要添加重定向。


1.添加printf进行重定向

//在main或串口配置文件中添加如下重定向代码

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "stdio.h"
/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */

/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */

#ifdef __GNUC__
/* With GCC, small printf (option LD Linker->Libraries->Small printf
   set to 'Yes') calls __io_putchar() */
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif /* __GNUC__ */

/**
  * @brief  Retargets the C library printf function to the USART.
  * @param  None
  * @retval None
  */
PUTCHAR_PROTOTYPE
{
  /* Place your implementation of fputc here */
  /* e.g. write a character to the USART3 and Loop until the end of transmission */
  HAL_UART_Transmit(&huart3, (uint8_t *)&ch, 1, 0xFFFF);//此处串口号根据实际变更
  return ch;
}
/* USER CODE END PD */

2.串口配置并处理接收数据

方式一数据接收过程:

  • 1.串口接收到数据,进入接收中断;
  • 2.判断是否已经接收到“0x0A”;
  • 3.还没有接收到“0x0A”,判断是否接收到“0x0D”;
  • 7.还没有接收到“0x0D”,并且当前接收的数据不是“0x0D”,将当前接收的数据放到接收缓存USART3_RX_BUF,地址为前一次结束指向的地址,变量USART3_RX_STA加1,表示接收的字节数加1 ;
  • 8.判断如果变量USART3_RX_STA已经超过自定义的最大接收长度(0d,0a不会进入此判断),将此变量清零,接收数据效;
  • 9.继续开启接收中断,新数据存放在USART3_NEW_DATA中;

-------以上循环接收正常数据--------

------以下开始接收“0x0D”,“0x0A”---------

  • 6.还没有接收到“0x0D”,如果当前接收的数据是“0x0D”,将变量USART3_RX_STA[14]位置1,接收的字节数[13:0]保持不变;
  • 4.已经接收到“0x0D”,如果本次接收数据不是“0x0A”,将变量USART3_RX_STA清零,接收错误数据无效。
    or
  • 5.已经接收到“0x0D”,如果本次接收数据是“0x0A”,将变量USART3_RX_STA[15]位置1,表示数据全部接收完成。

由此可以知道变量USART3_RX_STA[15:0]位各个数据位的含义:
USART3_RX_STA[15] = 1 — 接收数据“0x0A”;
USART3_RX_STA[14] = 1 — 接收数据“0x0D”;
USART3_RX_STA[13:0] — 累计接收到非“0x0D”,“0x0A”数据个数,即最多0x3FFF个数据。

void MX_USART3_UART_Init(void)
{

  /* USER CODE BEGIN USART3_Init 0 */

  /* USER CODE END USART3_Init 0 */

  /* USER CODE BEGIN USART3_Init 1 */

  /* USER CODE END USART3_Init 1 */
  huart3.Instance = USART3;
  huart3.Init.BaudRate = 115200;
  huart3.Init.WordLength = UART_WORDLENGTH_8B;
  huart3.Init.StopBits = UART_STOPBITS_1;
  huart3.Init.Parity = UART_PARITY_NONE;
  huart3.Init.Mode = UART_MODE_TX_RX;
  huart3.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  huart3.Init.OverSampling = UART_OVERSAMPLING_16;
  if (HAL_UART_Init(&huart3) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN USART3_Init 2 */
  HAL_UART_Receive_IT(&huart3, (uint8_t *)&USART3_NEW_DATA, 1);		//此处加入uart3开始中断接收
  /* USER CODE END USART3_Init 2 */

}
//添加回调函数,产生中断进入此回调函数,不进入微(weak)回调函数
uint8_t USART3_RX_BUF[USART3_REC_LEN];
uint16_t USART3_RX_STA = 0;//记录接收状态:0a+0d+数据个数
uint8_t USART3_NEW_DATA;//当前中断接收的一个字节缓存

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
	if(huart == &huart3)//1.判断中断源
	{
		printf("%c",USART3_NEW_DATA);
		if((USART3_RX_STA & 0x8000) == 0)//2.
		{
			if(USART3_RX_STA & 0x4000)//3.
			{
				if(USART3_NEW_DATA != 0x0a)//4.
					USART3_RX_STA = 0;
				else
					USART3_RX_STA |= 0x8000;//5.
			}
			else
			{
				if(USART3_NEW_DATA == 0x0d)//6.
					USART3_RX_STA |= 0x4000;
				else
				{
					USART3_RX_BUF[USART3_RX_STA & 0x3fff] = USART3_NEW_DATA;//7.
				    USART3_RX_STA ++;
				    if(USART3_RX_STA > (USART3_REC_LEN - 1))//8.
				    	USART3_RX_STA=0;
				}
			}
		}
		HAL_UART_Receive_IT(&huart3, (uint8_t *)&USART3_NEW_DATA, 1);//9.
	}
}
//处理接收数据
void receive_command(void)
{
	if(USART3_RX_STA & 0x8000)
	{
		USART3_RX_BUF[USART3_RX_STA & 0x3fff] = 0;
		printf("USART3_RX_BUF[0]=%02X\r\n",USART3_RX_BUF[0]);
		printf("USART3_RX_BUF[1]=%02X\r\n",USART3_RX_BUF[1]);
		printf("USART3_RX_BUF[2]=%02X\r\n",USART3_RX_BUF[2]);
		printf("USART3_RX_BUF[3]=%02X\r\n",USART3_RX_BUF[3]);
		printf("USART3_RX_BUF[4]=%02X\r\n",USART3_RX_BUF[4]);
		printf("USART3_RX_BUF[5]=%02X\r\n",USART3_RX_BUF[5]);

		if(strcmp(USART3_RX_BUF,"on")==0) //字符串对比
			LED_Switch(0);
		else if(strcmp(USART3_RX_BUF,"off")==0) //字符串对比
			LED_Switch(1);
		USART3_RX_STA = 0;
	}

方式二相较于方式一更直观,不再描述其执行流程:

//配置方面相同,添加回调函数
UART_TypeDef uart3; //结构体变量

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
	if(huart == &huart3)//判断中断源
	{
		printf("%c",uart3.rx);
		if(uart3.rxComplete == 0)
		{
			uart3.rxBuffer[uart3.rxPoint] = uart3.rx;
			if(uart3.rxPoint < UART_RX_SIZE)
			{
				uart3.rxPoint++;
			}
			if(uart3.rx != 0x0A)
			{
//				HAL_UART_Receive_IT(&huart3, &uart3.rx, 1);
			}
			else
			 {
				uart3.rxComplete = 1;
			 }
		 }
		HAL_UART_Receive_IT(&huart3, &uart3.rx, 1);
	}
}

//库函数添加定义及结构体
#define USART3_REC_LEN 20
#define UART_RX_SIZE	20
#define	UART_TX_SIZE	20
extern UART_TypeDef uart3;

typedef struct
{
	volatile uint8_t rxComplete;		//接收完成标志位1=完成
	volatile uint8_t txComplete;		//发送完成标志位1=完成
	volatile uint16_t rxPoint;			//接收指针
	volatile uint8_t rxinterval;		//最后一个接收字符的间隔时间
	uint8_t rx;							//当前接收内容
	uint8_t rxBuffer[UART_RX_SIZE];		//接收buffer
	uint8_t txBuffer[UART_TX_SIZE];		//发送buffer
}UART_TypeDef;

//字符串比较
uint8_t String_Compare(uint8_t *buffer1,const char *buffer2,uint8_t count)
{
	uint8_t B1 = 0;
	uint8_t B2 = 0;
	while(count--)
	{
		B1 = tolower(*buffer1);
		B2 = tolower(*buffer2);
		if(B1==B2)
		{
			buffer1++;
			buffer2++;
		}
		else break;
	}
	return (B1-B2);
}

//处理接收数据
void receive_command(void)
{
	if(uart3.rxComplete == 1)
	{
		uart3.rxBuffer[uart3.rxPoint] = 0;
		printf("uart3.rxBuffer[0]=%02X\r\n",uart3.rxBuffer[0]);
		printf("uart3.rxBuffer[1]=%02X\r\n",uart3.rxBuffer[1]);
		printf("uart3.rxBuffer[2]=%02X\r\n",uart3.rxBuffer[2]);
		printf("uart3.rxBuffer[3]=%02X\r\n",uart3.rxBuffer[3]);
		printf("uart3.rxBuffer[4]=%02X\r\n",uart3.rxBuffer[4]);
		printf("uart3.rxBuffer[5]=%02X\r\n",uart3.rxBuffer[5]);

		if(String_Compare(uart3.rxBuffer,"on",strlen("on"))==0) //字符串对比
			LED_Switch(0);
		else if(String_Compare(uart3.rxBuffer,"off",strlen("off"))==0) //字符串对比
			LED_Switch(1);
		uart3.rxComplete = 0;
		uart3.rxPoint = 0;
	}
}

3.调试问题

cubeIDE中出现中文乱码或者使用printf函数输出中文时,串口调试助手接收到乱码,可在Project -> Properties -> Resource -> Text file encoding中选择Other选项,并在下拉框中输入GBK(下拉选项中可能没有该选项,可直接输入):
在这里插入图片描述


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值