Stm32CubeMx实现串行通信控制LED灯

Stm32CubeMx实现串行通信控制LED灯

  • 知识储备
    • USART和UART
    • 使用串口向电脑输出数据
    • 使用串口接受电脑数据
  • Stm32CubeMx配置
  • 代码编写
    • 重写fputc
      • 添加stdio.h
    • 定义变量
    • 使能串口接收中断
    • 编写接受中断函数
    • Main函数While代码

知识储备

USART和UART

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

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

根据STM32F103xx参考手册(中文版)8.3.8 表47
Stm32CubeMx实现串行通信控制LED灯_第1张图片
在默认情况下USART1对应的引脚是PA9和PA10

使用串口向电脑输出数据

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

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

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

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

使用串口接受电脑数据

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

Stm32CubeMx配置

Stm32CubeMx实现串行通信控制LED灯_第2张图片
配置完这一步后可以观察到PA9和PA10都被自动配置好了
Stm32CubeMx实现串行通信控制LED灯_第3张图片
这一章例程是串口控制流水灯,上面只是配置了串口,流水灯自行配置即可
具体步骤请看我之前的文章

代码编写

重写fputc

Stm32CubeMx实现串行通信控制LED灯_第4张图片

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

添加stdio.h

Stm32CubeMx实现串行通信控制LED灯_第5张图片
其实这个时候就可以用pringf函数通过串口向电脑输出数据了

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

定义变量

Stm32CubeMx实现串行通信控制LED灯_第6张图片

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);
//三个变量分别表示:串口号的别名,接收到的数据存放地址,接受的字节数

编写接受中断函数

Stm32CubeMx实现串行通信控制LED灯_第7张图片

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代码

Stm32CubeMx实现串行通信控制LED灯_第8张图片

		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);

你可能感兴趣的:(stm32)