Stm32CubeMx实现串行通信控制LED灯

知识储备

USART和UART

USART(通用同步异步收发器2) 是 MCU 的重要外设,在程序设计的调试阶段可发挥重要作用。

STM32F1系列器有多个收发器外设(俗称“串口”),包括USART1、USART2、USART3、UART4、UART5。
UART 与 USART 相比,裁剪了同步通信的功能,只有异步通信功能。

根据STM32F103xx参考手册(中文版)8.3.8 表47
在这里插入图片描述
在默认情况下USART1对应的引脚是PA9和PA10

使用串口向电脑输出数据

默认情况下,编程stm32使,使用printf函数会通过串口将数据发送到显示屏上面
但这一章我们想要使用pringf函数通过串口将数据发送给电脑,这个时候我们就要对printf的函数进行一些修改

系统执行printf函数的时候会调用到fputc函数,我们只需要重写fputc函数就可以实现我们上面说的功能了

fuptc函数里面有调用到一个HAL_UART_Transmit函数,这个和函数就是具体的串口输出函数

具体fuptc函数的改动请看代码编写目录里

使用串口接受电脑数据

当单片机接收到数据的时候,会触发接收中断,我们只需要将逻辑函数写在这个中断函数(HAL_UART_RxCpltCallback)里就行了
前提是需要开启接收中断HAL_UART_Receive_IT

Stm32CubeMx配置

在这里插入图片描述
配置完这一步后可以观察到PA9和PA10都被自动配置好了
在这里插入图片描述
这一章例程是串口控制流水灯,上面只是配置了串口,流水灯自行配置即可
具体步骤请看我之前的文章

代码编写

重写fputc

在这里插入图片描述

HAL_UART_Transmit(&huart1,&data,1,0xffff);
//表示通过串口1(usart1)从data指针开始输出的一个字节数据。0xffff为超时时间

添加stdio.h

在这里插入图片描述
其实这个时候就可以用pringf函数通过串口向电脑输出数据了

接下来实现通过串口接受数据

定义变量

在这里插入图片描述

const char LedMode1[8] = "mode1";
const char LedMode2[8] = "mode2";
const char LedMode3[8] = "mode3";

uint16_t LED_value = 0;

#define RXBUFFERSIZE  256     //最大接收字节数
char RxBuffer[RXBUFFERSIZE];   //接收数据
uint8_t aRxBuffer;			//接收中断缓冲
uint8_t Uart1_Rx_Cnt = 0;		//接收缓冲计数
uint8_t LedMode = 3;

使能串口接收中断

在这里插入图片描述

HAL_UART_Receive_IT(&huart1, (uint8_t *)&aRxBuffer, 1);
//三个变量分别表示:串口号的别名,接收到的数据存放地址,接受的字节数

编写接受中断函数

在这里插入图片描述

UNUSED(huart);
	//if(Uart1_Rx_Cnt >= 255)  //溢出判断
	//{
		//Uart1_Rx_Cnt = 0;
		//memset(RxBuffer,0x00,sizeof(RxBuffer));
		//HAL_UART_Transmit(&huart1, (uint8_t *)"数据溢出", 10,0xFFFF); 	
		//printf("数据溢出");
	//}
	//else
	//{
		RxBuffer[Uart1_Rx_Cnt++] = aRxBuffer;   //接收数据转存
	
		if((RxBuffer[Uart1_Rx_Cnt-1] == 0x0A)&&(RxBuffer[Uart1_Rx_Cnt-2] == 0x0D)) //判断结束位
		{
			//HAL_UART_Transmit(&huart1, (uint8_t *)&RxBuffer, Uart1_Rx_Cnt,0xFFFF); //将收到的信息发送出去
			Uart1_Rx_Cnt = 0;
			if(strstr((const char *)RxBuffer,LedMode1) != NULL)
			{
				printf("start mode1\r\n");
				LedMode = 1;
				LED_value = 0x00;
			}
			if(strstr((const char *)RxBuffer,LedMode2) != NULL)
			{
				printf("start mode2\r\n");
				LedMode = 2;
				LED_value = 0x01;
			}
			if(strstr((const char *)RxBuffer,LedMode3) != NULL)
			{
				printf("start mode3\r\n");
				LedMode = 3;
				LED_value = 0x80;
			}
			memset(RxBuffer,0x00,sizeof(RxBuffer)); //清空数组
		}
	//}
	
	HAL_UART_Receive_IT(&huart1, (uint8_t *)&aRxBuffer, 1);   //再开启接收中断

HAL_UART_Receive_IT(&huart1, (uint8_t *)&aRxBuffer, 1);表示一个一个字节接受数据并输送给RxBuffer数组里面,这样做的好处是可以无视单片机接受的数据长度(前提是单片机接受的数据长度小于255字节)

调用HAL_UART_Receive_IT函数后,单片机只会进入一次HAL_UART_RxCpltCallback函数,所以需要在HAL_UART_RxCpltCallback再次声明HAL_UART_Receive_IT

char类型的数组最多接受255个字节数据,所以需要先判断接收到的数据是不是超过了255,若是超过255:数组清空,报错

这里我们接受到的数据一定是小于255个字节的,所以我就把多余的代码注释掉了,有需要这一些代码的同学取消注释即可

Main函数While代码

在这里插入图片描述

		HAL_GPIO_WritePin(GPIOE,0xff,GPIO_PIN_SET);
		HAL_GPIO_WritePin(GPIOE,LED_value,GPIO_PIN_RESET);
		switch(LedMode)
		{
			case 1 : LED_value = 0;break;
			case 2 : 
				LED_value = LED_value << 1;
				if(LED_value == 0x100)
				{
					LED_value = 0x01;
				}
				break;
			case 3 : 
				LED_value = LED_value >> 1;
				if(LED_value == 0x00)
				{
					LED_value = 0x80;
				}
				break;
		}
		HAL_Delay(1000);
  • 23
    点赞
  • 104
    收藏
    觉得还不错? 一键收藏
  • 12
    评论
### 回答1: STM32CubeMX是STMicroelectronics提供的一种STM32控制器配置工具,它可以帮助用户轻松配置STM32控制器的外设和参数。如果要使用STM32CubeMX控制LED,可以按照以下步骤进行: 1. 打开STM32CubeMX并选择要使用的STM32控制器型号。 2. 在"Pinout"标签页中,选择一个可用的GPIO引脚并将其配置为控制LED。 3. 在"Clock Configuration"标签页中,配置系统时钟,确保它为LED提供足够的时钟频率。 4. 在"Configuration"标签页中,选择"GPIO"并配置GPIO参数。 5. 在"Code Generation"标签页中,生成代码。 6. 在生成的代码中,找到控制LED的函数并调用它来控制LED。 7. 编译并烧录代码到微控制器中。 8. 打开串口调试工具,连接STM32控制器,发送对应的指令来控制LED。 ### 回答2: STM32CubeMX是一个用于快速搭建STM32控制器系列的软件开发环境。通过它,可以轻松地配置微控制器外围设备和中间件,并生成基于HAL库的完整示例项目。其中,串口通信是常见的应用场景之一。 下面是实现使用串口控制LED亮灭的步骤: 1. 配置串口通信:打开STM32CubeMX软件,选择对应的微控制器型号并创建新项目。然后,在“Pinout & Configuration”选项卡中,选择“USART”功能后,分别配置串口的波特率、数据位、停止位和奇偶校验等参数。最后,生成代码。 2. 编写代码:在生成的代码框架中,找到“main.c”文件,并添加以下的宏定义、变量和函数: - 宏定义:定义串口输入命令,并与相应的LED管脚关联(例如# define LED_ON ’1’和# define LED_OFF ’0’)。 - 变量:定义串口数据接收缓冲区、LED控制标志等变量。 - 函数:编写串口数据接收和LED控制函数,实现串口接收到指定的命令时,LED的亮灭控制。 3. 测试程序:将STM32控制器与计算机连接,打开串口调试助手,通过串口输入“1”或“0”命令,即可控制LED亮灭。 总之,使用STM32CubeMX通过串口通信控制LED的过程需要先进行串口通信的配置并生成代码,然后编写控制命令的代码实现LED亮灭的控制。这样可以大大简化控制代码的编写和调试过程,提高开发效率。 ### 回答3: STM32CubeMX是一个代码生成工具,可用于快速生成STM32控制器项目的初始化代码。在STM32CubeMX中,我们可以轻松地添加串口LED库函数来控制LED的状态。在以下步骤中,我们将学习如何使用STM32CubeMXSTM32控制器上控制LED: 1. 配置串口STM32CubeMX中,我们需要先配置板载串口。为此,我们可以打开STM32CubeMX,选择正确的芯片系列和型号,然后单击“时钟配置”选项卡,以配置系统时钟。 2. 启用串口和GPIO 接下来,我们需要启用所需的串口(USART)和GPIO(General Purpose Input/Output)端口。选择“Pinout & Configuration”选项卡,然后单击“USART1”并将其设置为“Enable”状态。此外,我们需要启用控制LED的GPIO端口。选择与所选开发板中的LED对应的端口,并将其设置为输出模式。 3. 建立中断服务例程 在“Configuration”选项卡中,我们可以配置中断服务例程。选择“NVIC”选项卡,然后启用或禁用所需的中断。对于串口,我们需要启用“USART1 global interrupt”。 4. 处理中断和发送数据 在我们的代码中,我们可以实现一个自定义的USART1中断服务例程来处理接收的数据,并相应地改变LED状态。我们也可以使用库函数来发送数据到串口。例如,我们可以使用库函数“HAL_USART_Transmit”将“LED ON/OFF”这样的字符发送到串口上。 5. 编写代码 在以上步骤完成后,我们需要在IDE中编写代码来控制LED。使用库函数的示例代码如下: ``` #include "main.h" #include "stm32f1xx_hal_usart.h" void GPIO_Init(void); void USART1_Init(void); void USART1_IRQHandler(void); int main(void) { HAL_Init(); // 初始化 HAL 库 GPIO_Init(); // 初始化 GPIO USART1_Init();// 初始化 USART1 while (1) { // 循环等待中断触发 } } void GPIO_Init(void) { __HAL_RCC_GPIOC_CLK_ENABLE(); // 使能 GPIOC 时钟 GPIO_InitTypeDef GPIO_InitStruct = {0}; GPIO_InitStruct.Pin = GPIO_PIN_13; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); } void USART1_Init(void) { __HAL_RCC_USART1_CLK_ENABLE(); // 使能 USART1 时钟 USART_HandleTypeDef USART_InitStruct = {0}; USART_InitStruct.Instance = USART1; USART_InitStruct.Init.BaudRate = 9600; USART_InitStruct.Init.WordLength = USART_WORDLENGTH_8B; USART_InitStruct.Init.StopBits = USART_STOPBITS_1; USART_InitStruct.Init.Parity = USART_PARITY_NONE; USART_InitStruct.Init.Mode = USART_MODE_TX_RX; USART_InitStruct.Init.HwFlowCtl = USART_HWCONTROL_NONE; USART_InitStruct.Init.OverSampling = USART_OVERSAMPLING_16; HAL_USART_Init(&USART_InitStruct); HAL_NVIC_SetPriority(USART1_IRQn, 0, 1); // 设置中断优先级 HAL_NVIC_EnableIRQ(USART1_IRQn); // 使能中断 } void USART1_IRQHandler(void) { uint32_t isrflags = READ_REG(USART1->ISR); // 读取中断状态寄存器 if (isrflags & USART_ISR_RXNE) // 如果是 USART 接收中断 { uint8_t ch; HAL_USART_Receive(&huart1, &ch, 1, HAL_MAX_DELAY); // 读取数据 if (ch == '0') // 接收到 '0',关闭 LED { HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_RESET); } else if (ch == '1') // 接收到 '1',开启 LED { HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_SET); } else { // 发送错误消息到串口 const char* errmsg = "Invalid command received!"; HAL_USART_Transmit(&huart1, (uint8_t*)errmsg, strlen(errmsg), HAL_MAX_DELAY); } } } ``` 在以上代码中,我们使用了库函数来初始化GPIO和USART1,然后等待中断触发。当接收到'0'或'1'字符时,我们将相应地关闭或开启LED。如果接收到其他字符,我们将发送一个错误消息。 如上所述,我们现在可以在STM32控制器上使用串口LED库函数控制LED了。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值