STM32 HAL 库驱动 ESP8266 WiFi 模块

实验原理

关于 ESP8266 WiFi 模块使用原理可以看我前面的博客

WiFi 驱动代码连接将会放到文末

这里我们将芯片换为 STM32F103ZET6,别问为什么,问就是引脚资源多

CubeMX 配置

USART2 与 USART3 配置

这里我们使用的配置与前面我们配置 USART1 的方式完全一致:




ESP32 WIFI模组 esp32wifi模块调用_ESP32 WIFI模组


ESP32 WIFI模组 esp32wifi模块调用_stm32_02


USART3 同理,这里不再进行展示

GPIO 配置




ESP32 WIFI模组 esp32wifi模块调用_嵌入式硬件_03


这里我们直接设置好名字,我们就不需要修改驱动代码

代码设计

代码生成

首先,由于给定的驱动是基于 LL 库实现的,所以这里我们使用的 USART2 和 USART3 需要生成 LL 库对应的代码:


ESP32 WIFI模组 esp32wifi模块调用_单片机_04


驱动代码移植

重写 printf 函数,这里主要用 com3 作为输出串口

int fputc(int ch,FILE *f)
{
	uint8_t temp[1]={ch};
	LL_USART_TransmitData8(USART3,temp[0]);
	while(!LL_USART_IsActiveFlag_TXE(USART3));//需要等待发送完成
	return(ch);
}

下载对应的驱动代码,然后添加到我们的项目中:


ESP32 WIFI模组 esp32wifi模块调用_ESP32 WIFI模组_05


代码中已经存在了我们需要进行配置的函数,我们直接调用即可:


ESP32 WIFI模组 esp32wifi模块调用_单片机_06


注意:这里我们需要按照个人配置来修改 WiFi 及 IP 信息


ESP32 WIFI模组 esp32wifi模块调用_嵌入式硬件_07


注意:这里还需要注意的是,我们需要应用 rt_thread.h 头文件,将驱动函数中的所有延时函数 HAL_Delay() 全部替换为 rt_thread_delay() 函数,不然会遇到进程终止或无法继续执行的问题

USART 功能设计

打开 usart.c 源文件,我们在函数 MX_USART2_UART_Init()、MX_USART3_UART_Init() 最后面添加 USART 接收中断使能

// USART2
  /* USER CODE BEGIN USART1_Init 2 */
  LL_USART_EnableIT_RXNE(USART2);
  LL_USART_EnableIT_IDLE(USART2);
  /* USER CODE END USART1_Init 2 */

// USART3
  /* USER CODE BEGIN USART1_Init 2 */
  LL_USART_EnableIT_RXNE(USART3);
  LL_USART_EnableIT_IDLE(USART3);
  /* USER CODE END USART1_Init 2 */

现在我们已经成功使能了 USART2、USART3 的中断,对应函数在 stm32f1xx_it.c 中,下面进行中断函数的实现

首先我们编写 USART2 的中断函数

/**
  * @brief This function handles USART2 global interrupt.
  */
void USART2_IRQHandler(void)
{
  /* USER CODE BEGIN USART2_IRQn 0 */
  uint8_t ucCh;
	if (LL_USART_IsActiveFlag_RXNE(USART2) != RESET) {
	ucCh = LL_USART_ReceiveData8(USART2);

	if ( strEsp8266_Fram_Record .InfBit .FramLength < ( RX_BUF_MAX_LEN - 1 ) )                       //预留1个字节写结束符
		strEsp8266_Fram_Record .Data_RX_BUF [ strEsp8266_Fram_Record .InfBit .FramLength ++ ]  = ucCh;

	}
  /* USER CODE END USART2_IRQn 0 */
  /* USER CODE BEGIN USART2_IRQn 1 */
	if (LL_USART_IsActiveFlag_IDLE(USART2) == SET) {
		strEsp8266_Fram_Record .InfBit .FramFinishFlag = 1;

		ucCh = LL_USART_ReceiveData8(USART2);                 //获取连接状态
		ucTcpClosedFlag = strstr ( strEsp8266_Fram_Record .Data_RX_BUF, "CLOSED\r\n" ) ? 1 : 0;
	}
  /* USER CODE END USART2_IRQn 1 */
}

接着我们编写 USART3 的中断函数

/**
  * @brief This function handles USART1 global interrupt.
  */
void USART3_IRQHandler(void)
{
  /* USER CODE BEGIN USART1_IRQn 0 */
  uint8_t ucCh;
	if ( LL_USART_IsActiveFlag_RXNE(USART3) != RESET )
	{
		ucCh  = LL_USART_ReceiveData8( USART3 );
		
		if ( strUSART_Fram_Record .InfBit .FramLength < ( RX_BUF_MAX_LEN - 1 ) )                       //预留1个字节写结束符
			   strUSART_Fram_Record .Data_RX_BUF [ strUSART_Fram_Record .InfBit .FramLength ++ ]  = ucCh;
	}
  /* USER CODE END USART1_IRQn 0 */
  /* USER CODE BEGIN USART1_IRQn 1 */
	if ( LL_USART_IsActiveFlag_IDLE( USART3) == SET )     //数据帧接收完毕
	{
		strUSART_Fram_Record .InfBit .FramFinishFlag = 1;
		ucCh = LL_USART_ReceiveData8( USART3 );
  }
  /* USER CODE END USART1_IRQn 1 */
}

测试 WiFi

现在代码移植工作已经完成了,下面进行验证驱动环节

在 app_rt_thread.c 中引用相关头文件

#include "bsp_esp8266_test.h"

在主进程函数中添加以下内容

//初始化ESP8266
  ESP8266_Init();
  //ESP8266进行透传模式
  ESP8266_StaTcpClient_Unvarnish_ConfigTest();

烧录测试

当我们烧录测试之后,能够正常运行并输出如下,则说明 WiFi 已经连接成功


ESP32 WIFI模组 esp32wifi模块调用_Data_08


当我们成功连接 WiFi 后,我们开始测试我们的 udp 传输,由于我们是继续前面的倒车系统进行的,所以这里我们直接输出超声波测距数据:

这里我们使用自治的测试工具进行测试:


ESP32 WIFI模组 esp32wifi模块调用_ESP32 WIFI模组_09


这里我们开始测距输出一个 start 表示开始,在测距结束时输出一个 stop 表示停止,图中已经获取到输出与发送数据的 IP 和端口号,说明我们的程序就已经成功了

下载地址

HAL库 ESP8266 WiFi 驱动