cubemx快速使用串口

前言

助力于快速使用串口功能,如果想了解串口协议等知识点等请自行搜索,
这里注明串口下功能实现常用的fputc、字符串发送函数、fgetc函数等函数写法。
实验了三个例子来展示printf函数、串口中断使用、串口基本使用。

一、使用cubemx进行串口基本配置

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

二、说明

一般配置好串口我们就可以实验使用串口向上位机发送内容了,即使用板子与PC端串口调试助手或者其他设备进行信息收发。

而进行信息发送一般使用HAL库自带的发送函数HAL_UART_Transmit
另一种方法便是调用C库中的printf打印函数,而该函数是依照fputc实现的,因此需要重写该函数才可以使用printf函数。而scanf函数是依靠fgetc完成的

下面常用函数详细说明这里不做赘述,喜欢自行查阅资料
重写fputc代码

int fputc(int ch,FILE * fp)
{
 HAL_UART_Transmit(&huart1,(uint8_t * )&ch,1,0xffff);
 return ch;
}
**重写fgetc实现程序可调用scanf及getchar等函数**
int fgetc(FILE *f)
{
int ch;
/* 等待串口输入数据 */
while (__HAL_UART_GET_FLAG(&huart1, UART_FLAG_RXNE) == RESET);
HAL_UART_Receive(&huart1, (uint8_t *)&ch, 1, 0xFFFF);
return (ch);
}

注意:使用时别忘记勾选微库选项,否则printf 不起作用
注意:使用时别忘记勾选微库选项,否则printf 不起作用
注意:使用时别忘记勾选微库选项,否则printf 不起作用
在这里插入图片描述

字符串发送函数

void Usart1_String(char *str)
{ 
	int k=0;
	do
	{
		HAL_UART_Transmit(&huart1,(uint8_t * )(str+k),1,0xffff);
		k++;
	}
	while(*(str+k)!='\0');
	return;
}

接收中断回显服务函数(板级支持包,放入串口中断服务函数中使用)

void TEST_USART_IRQHandler(void) 
{
	uint8_t ch;
	if (__HAL_UART_GET_FLAG( &huart1, UART_FLAG_RXNE ) != RESET)//接收中断
	{
	ch=( uint16_t)READ_REG(huart1.Instance->DR);//读数据寄存器
	WRITE_REG ( huart1.Instance->DR,ch);//写数据寄存器
	} 
}

三、实验内容

1.串口打印

由于cubemx已经将串口的基本配置完成,我们在该基础上进行添加即可。在这里插入图片描述
当添加fputc重写函数报错时别忘了添加头文件#include "stdio.h"
总之当你需要在那个文件中使用printf时别忘记添加头文件#include "stdio.h"
在main函数中添加printf在这里插入图片描述

2.串口中断实现回显

前面已经使用cubemx使能了串口中断,但是我们还未声明串口中断触发方式所以添加该语句: __HAL_UART_ENABLE_IT(&huart1,UART_IT_RXNE);接收中断触发,其他触发方式可以修改函数中的参数。

 void MX_USART1_UART_Init(void)
{

  huart1.Instance = USART1;
  huart1.Init.BaudRate = 115200;
  huart1.Init.WordLength = UART_WORDLENGTH_8B;
  huart1.Init.StopBits = UART_STOPBITS_1;
  huart1.Init.Parity = UART_PARITY_NONE;
  huart1.Init.Mode = UART_MODE_TX_RX;
  huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  huart1.Init.OverSampling = UART_OVERSAMPLING_16;
  if (HAL_UART_Init(&huart1) != HAL_OK)
  {
    Error_Handler();
  }
  __HAL_UART_ENABLE_IT(&huart1,UART_IT_RXNE);//声明以接收中断触发
}

其他设置不变,下一步则要调用中断服务函数,及串口中断触发的入口函数
在文件stm32f1xx_it.c中可以看见串口中断服务函数,该函数内已经嵌套了一个HAL库下写好的串口中断服务函数,但当你跳进去查看会发现内部很复杂且不易改动,似乎找不到用户自行定义中断程序的位置。

void USART1_IRQHandler(void)
{

  /* USER CODE BEGIN USART1_IRQn 0 */
	
  /* USER CODE END USART1_IRQn 0 */
    HAL_UART_IRQHandler(&huart1);//HAL库下的串口服务函数
  /* USER CODE BEGIN USART1_IRQn 1 */

  /* USER CODE END USART1_IRQn 1 */
}

我们可以将上诉代码中的HAL_UART_IRQHandler(&huart1);屏蔽在USART1_IRQHandler(void)函数中写入自己的程序

void USART1_IRQHandler(void)
{

  /* USER CODE BEGIN USART1_IRQn 0 */
	TEST_USART_IRQHandler();//上文提到的接收中断回显服务函数
  /* USER CODE END USART1_IRQn 0 */
  //  HAL_UART_IRQHandler(&huart1);
  /* USER CODE BEGIN USART1_IRQn 1 */

  /* USER CODE END USART1_IRQn 1 */
}

在这里插入图片描述

3.串口接收选择回显内容

在进行该实验建议将中断使能,找到HAL_NVIC_EnableIRQ(IRQn_Type IRQn)语句替换为HAL_NVIC_DisableIRQ(IRQn_Type IRQn)可将使能修改为失能中断即可失效。
在main.c中增加该函数

/************************
函数功能:通过接收上位机发过来的数字选择对应的接收的ch打印,如果输入了1-8其他数字则打印错误报告。
************************/
void Get_LED_CMD(void)
{   
		ch=getchar();
		printf("接收到字符:%c\n",ch);
		switch (ch) 
		{
			case '1':
			printf("ch=%c\r\n",ch);
			break;
			case '2':
			printf("ch=%c\r\n",ch);
			break;
			case '3':
			printf("ch=%c\r\n",ch);
			break;
			case '4':
			printf("ch=%c\r\n",ch);
			break;
			case '5':
			printf("ch=%c\r\n",ch);
			break;
			case '6':
			printf("ch=%c\r\n",ch);
			break;
			case '7':
			printf("ch=%c\r\n",ch);
			break;
			case '8':
			printf("ch=%c\r\n",ch);
			break;
			default:
			printf("ch=err is %c",ch);
			break; 
		}
}

将该函数调用在main函数中while中轮询(别忘记将该函数声明在main函数之前,否则报错找不到)
在这里插入图片描述
测试结果:
在这里插入图片描述
以上Get_LED_CMD(void)函数中可以将switch语句中各个case选项中的printf替换为其他功能即可实现选择各种自己想要的功能,如发送‘1’开1灯,发送‘2’关1灯等…脑洞

版权声明:本文为CSDN博主「弦续北上i」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/CSDN_joker_/article/details/122291869

前言

助力于快速使用串口功能,如果想了解串口协议等知识点等请自行搜索,
这里注明串口下功能实现常用的fputc、字符串发送函数、fgetc函数等函数写法。
实验了三个例子来展示printf函数、串口中断使用、串口基本使用。

一、使用cubemx进行串口基本配置

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

二、说明

一般配置好串口我们就可以实验使用串口向上位机发送内容了,即使用板子与PC端串口调试助手或者其他设备进行信息收发。

而进行信息发送一般使用HAL库自带的发送函数HAL_UART_Transmit
另一种方法便是调用C库中的printf打印函数,而该函数是依照fputc实现的,因此需要重写该函数才可以使用printf函数。而scanf函数是依靠fgetc完成的

下面常用函数详细说明这里不做赘述,喜欢自行查阅资料
重写fputc代码

int fputc(int ch,FILE * fp)
{
 HAL_UART_Transmit(&huart1,(uint8_t * )&ch,1,0xffff);
 return ch;
}
**重写fgetc实现程序可调用scanf及getchar等函数**
int fgetc(FILE *f)
{
int ch;
/* 等待串口输入数据 */
while (__HAL_UART_GET_FLAG(&huart1, UART_FLAG_RXNE) == RESET);
HAL_UART_Receive(&huart1, (uint8_t *)&ch, 1, 0xFFFF);
return (ch);
}

注意:使用时别忘记勾选微库选项,否则printf 不起作用
注意:使用时别忘记勾选微库选项,否则printf 不起作用
注意:使用时别忘记勾选微库选项,否则printf 不起作用
在这里插入图片描述

字符串发送函数

void Usart1_String(char *str)
{ 
	int k=0;
	do
	{
		HAL_UART_Transmit(&huart1,(uint8_t * )(str+k),1,0xffff);
		k++;
	}
	while(*(str+k)!='\0');
	return;
}

接收中断回显服务函数(板级支持包,放入串口中断服务函数中使用)

void TEST_USART_IRQHandler(void) 
{
	uint8_t ch;
	if (__HAL_UART_GET_FLAG( &huart1, UART_FLAG_RXNE ) != RESET)//接收中断
	{
	ch=( uint16_t)READ_REG(huart1.Instance->DR);//读数据寄存器
	WRITE_REG ( huart1.Instance->DR,ch);//写数据寄存器
	} 
}

三、实验内容

1.串口打印

由于cubemx已经将串口的基本配置完成,我们在该基础上进行添加即可。在这里插入图片描述
当添加fputc重写函数报错时别忘了添加头文件#include "stdio.h"
总之当你需要在那个文件中使用printf时别忘记添加头文件#include "stdio.h"
在main函数中添加printf在这里插入图片描述

2.串口中断实现回显

前面已经使用cubemx使能了串口中断,但是我们还未声明串口中断触发方式所以添加该语句: __HAL_UART_ENABLE_IT(&huart1,UART_IT_RXNE);接收中断触发,其他触发方式可以修改函数中的参数。

 void MX_USART1_UART_Init(void)
{

  huart1.Instance = USART1;
  huart1.Init.BaudRate = 115200;
  huart1.Init.WordLength = UART_WORDLENGTH_8B;
  huart1.Init.StopBits = UART_STOPBITS_1;
  huart1.Init.Parity = UART_PARITY_NONE;
  huart1.Init.Mode = UART_MODE_TX_RX;
  huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  huart1.Init.OverSampling = UART_OVERSAMPLING_16;
  if (HAL_UART_Init(&huart1) != HAL_OK)
  {
    Error_Handler();
  }
  __HAL_UART_ENABLE_IT(&huart1,UART_IT_RXNE);//声明以接收中断触发
}

其他设置不变,下一步则要调用中断服务函数,及串口中断触发的入口函数
在文件stm32f1xx_it.c中可以看见串口中断服务函数,该函数内已经嵌套了一个HAL库下写好的串口中断服务函数,但当你跳进去查看会发现内部很复杂且不易改动,似乎找不到用户自行定义中断程序的位置。

void USART1_IRQHandler(void)
{

  /* USER CODE BEGIN USART1_IRQn 0 */
	
  /* USER CODE END USART1_IRQn 0 */
    HAL_UART_IRQHandler(&huart1);//HAL库下的串口服务函数
  /* USER CODE BEGIN USART1_IRQn 1 */

  /* USER CODE END USART1_IRQn 1 */
}

我们可以将上诉代码中的HAL_UART_IRQHandler(&huart1);屏蔽在USART1_IRQHandler(void)函数中写入自己的程序

void USART1_IRQHandler(void)
{

  /* USER CODE BEGIN USART1_IRQn 0 */
	TEST_USART_IRQHandler();//上文提到的接收中断回显服务函数
  /* USER CODE END USART1_IRQn 0 */
  //  HAL_UART_IRQHandler(&huart1);
  /* USER CODE BEGIN USART1_IRQn 1 */

  /* USER CODE END USART1_IRQn 1 */
}

在这里插入图片描述

3.串口接收选择回显内容

在进行该实验建议将中断使能,找到HAL_NVIC_EnableIRQ(IRQn_Type IRQn)语句替换为HAL_NVIC_DisableIRQ(IRQn_Type IRQn)可将使能修改为失能中断即可失效。
在main.c中增加该函数

/************************
函数功能:通过接收上位机发过来的数字选择对应的接收的ch打印,如果输入了1-8其他数字则打印错误报告。
************************/
void Get_LED_CMD(void)
{   
		ch=getchar();
		printf("接收到字符:%c\n",ch);
		switch (ch) 
		{
			case '1':
			printf("ch=%c\r\n",ch);
			break;
			case '2':
			printf("ch=%c\r\n",ch);
			break;
			case '3':
			printf("ch=%c\r\n",ch);
			break;
			case '4':
			printf("ch=%c\r\n",ch);
			break;
			case '5':
			printf("ch=%c\r\n",ch);
			break;
			case '6':
			printf("ch=%c\r\n",ch);
			break;
			case '7':
			printf("ch=%c\r\n",ch);
			break;
			case '8':
			printf("ch=%c\r\n",ch);
			break;
			default:
			printf("ch=err is %c",ch);
			break; 
		}
}

将该函数调用在main函数中while中轮询(别忘记将该函数声明在main函数之前,否则报错找不到)
在这里插入图片描述
测试结果:
在这里插入图片描述
以上Get_LED_CMD(void)函数中可以将switch语句中各个case选项中的printf替换为其他功能即可实现选择各种自己想要的功能,如发送‘1’开1灯,发送‘2’关1灯等…脑洞

版权声明:本文为CSDN博主「弦续北上i」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/CSDN_joker_/article/details/122291869

生成海报
点赞 0

弦续北上i

我还没有学会写个人说明!

暂无评论

发表评论

相关推荐

ESP32-GY_30光照强度传感器

GY_30光照强度传感器介绍 GY-30光强传感器特点及使用介绍 一、连接引脚 GY_30光照强度传感器使用I2C传输数据 。 5根引脚,名称与功能如下; vcc 为外接供电电源输入端 GND 地线 SCL I2C通信模式时钟

初学STM32之串口通信

一、背景知识 1. 处理器与外部通信的两种方式 并行通信:数据各个位同时传输 优点速度快;缺点占用引脚资源多串行通信:数据按位顺序传输 优点占用引脚资源少;缺点速度慢 2.串行通信的

GPIO口详解、HAL库操作按键

本次博客知识来自于韦东山老师的7天物联网课程。 一、GPIO详解 1、STM32F103C8T6一共有48个引脚。 2、按A、B、C分组,每组16个引脚,编号为0~15,STM32F103C8T6