STM32CubeMX新建STM32HAL库控制ESP8266WIFI模块点亮LED灯。速成,简单一步到位

引言:最近做完比赛后看到一个esp8266wifi模块,闲来无事就想利用它做点儿东西。但是找资料的过程中发现了一件很棘手的问题:我想直接利用网上esp8266wifi模块的能用的代码来做事情,但是网上找的代码要么是用的标准库,要么是用的爆改的hal库,就导致我想用hal库来弄的话,得重新改一堆函数。没有找到新手速成的文章,所以我解决完了后立马发个csdn来记录一下。

摘要:用的是esp8266wifi模块的AP(Access Point)模式:模块建立wifi热点,手机连接,利用“TCP连接”这个软件给wifi模块发送数据,wifi模块又给STM32发送串口数据,进而控制点灯与否。

目录

1.新建HAL库

2.复制函数直接用

3.手机端控制


ps(这是一篇速成文章,建议新手esp8266入门使用)

1.新建HAL库

我用的是F103RCT6,像F103C8T6和F103ZET6等等F1系列的开发板也通用,只是开头选择的芯片不一样罢了。

1.1 找芯片

1.2  高速时钟选择外部8Mhz的晶振

 1.3 选择串口

 ps(我选的是串口二,就像图示一样配置,其他的都默认)

1.4 选择LED

 1.5 开启debug调试功能

1.6 时钟树

1.7选择MDK_ARM编译器

 1.8生成文件库的选择

   弄好了之后generate code。

2.复制函数直接用

2.1.添加wifi模块.h和.c的文件,储存在Core文件夹里面

弄好了后 别忘了加入.c文件

2.2 wifi模块.c文件中添加代码

#include "My_esp8266.h"
#include "string.h"
#include "usart.h"

void u2_printf(char* fmt);
char esp8266_send_cmd(char *cmd,char *ack,u16 waittime); 


void esp8266_test(void)//测试
{
if(esp8266_send_cmd("AT","OK",50));

}

char esp8266_send_cmd(char *cmd,char *ack,u16 waittime)//发送指令和检查接收
{

u2_printf(cmd);
	
if(ack&&waittime)		
	{
		while(--waittime)	
		{
			HAL_Delay(10);
		if(strstr((const char*)RxBuffer,(const char*)ack)) //输入on,LED0亮
		{
			Uart2_Rx_Cnt=0;
			memset(RxBuffer,0x00,sizeof(RxBuffer)); //清空数组	
    return 1;

    }
		}

	}

	return 0;
}


void esp8266_start_trans(void)//ESP8266初始化
{
	
	esp8266_send_cmd("AT+CWMODE=2","OK",50);//设置为AP模式
 
	esp8266_send_cmd("AT+RST","ready",20);//重启
	
	HAL_Delay(1000);       
	HAL_Delay(1000);
	HAL_Delay(1000);
	HAL_Delay(1000);
	
	esp8266_send_cmd("AT+CWSAP=\"ESP8266\",\"12345678\",1,4","OK",200);//设置WiFi名称、密码,模式
	esp8266_send_cmd("AT+CIPMUX=1","OK",20);//进入透传模式
	esp8266_send_cmd("AT+CIPSERVER=1,8080","OK",200);//设置端口8080
	esp8266_send_cmd("AT+CIPSEND","OK",50);//开始发送数据
}

uint8_t esp8266_quit_trans(void)//退出透传模式
{
	uint8_t result=1;
	u2_printf("+++");
	HAL_Delay(1000);					
	result=esp8266_send_cmd("AT","OK",20);
	return result;

}


void u2_printf(char* fmt)  
{  

	uint8_t num=0;
  char my_ch[50]={0};
	while(*fmt!=0)
	my_ch[num++]=*fmt++;
	
	my_ch[num++]='\r';
	my_ch[num++]='\n';
	
	HAL_UART_Transmit(&huart2, (uint8_t *)my_ch,num, 0xffff);
   while(HAL_UART_GetState(&huart2) == HAL_UART_STATE_BUSY_TX);

}



2.3 wifi模块.h文件中添加代码

#ifndef __My_esp8266_H__
#define __My_esp8266_H__

#include "main.h"

typedef uint16_t u16  ;


extern void esp8266_test(void);
extern void u2_printf(char* fmt);
extern char esp8266_send_cmd(char *cmd,char *ack,u16 waittime); 
extern void esp8266_start_trans(void);

#endif




2.4 main.h的Exported types中添加代码

/* USER CODE BEGIN ET */
extern char RxBuffer[256];
extern uint8_t Uart2_Rx_Cnt;
/* USER CODE END ET */

2.5  main.c的Private includes中添加代码

/* USER CODE BEGIN Includes */
#include <string.h>
#include "My_esp8266.h"
/* USER CODE END Includes */

2.6  main.c的Private variables中添加代码

/* USER CODE BEGIN PV */
#define RXBUFFERSIZE  256     //最大接收字节数
char RxBuffer[RXBUFFERSIZE];   //接收数据
uint8_t aRxBuffer;			//接收中断缓冲
uint8_t Uart2_Rx_Cnt = 0;		//接收缓冲计数
uint8_t my_test_v = 0 ;
char my_order[15]={0};
char receive_flag=0;
/* USER CODE END PV */

2.7 main.c主函数下面的USER CODE BEGIN 4下面添加中断回调函数,如下

/* USER CODE BEGIN 4 */
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
  /* Prevent unused argument(s) compilation warning */
  UNUSED(huart);
  /* NOTE: This function Should not be modified, when the callback is needed,
           the HAL_UART_TxCpltCallback could be implemented in the user file
   */
 
	if(Uart2_Rx_Cnt >= 255)  //溢出判断
	{
		Uart2_Rx_Cnt = 0;
		memset(RxBuffer,0x00,sizeof(RxBuffer));	        
	}
	else
	{
		static uint8_t Uart2_count=0;
		
		RxBuffer[Uart2_Rx_Cnt] = aRxBuffer;   //接收数据转存
		if(receive_flag==0)
		{
		if(RxBuffer[Uart2_Rx_Cnt-Uart2_count]=='<')
		{	
			Uart2_count++;
		if((RxBuffer[Uart2_Rx_Cnt]=='>')||Uart2_count>=14)
		{
			uint8_t My_i=0;
		for(int i=Uart2_Rx_Cnt-Uart2_count+1;i<Uart2_Rx_Cnt+1;i++)
			my_order[My_i++]=RxBuffer[i];
			receive_flag=1;
			Uart2_count=0;
		}
	}
	}
		Uart2_Rx_Cnt++;
	}
	
	HAL_UART_Receive_IT(&huart2, (uint8_t *)&aRxBuffer, 1);   //再开启接收中断
}
/* USER CODE END 4 */

2.8 最后主函数代码

int main(void)
{
  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_USART2_UART_Init();
  /* USER CODE BEGIN 2 */
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_8,GPIO_PIN_RESET );
HAL_UART_Receive_IT(&huart2, (uint8_t *)&aRxBuffer, 1);
esp8266_start_trans();
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
	 //     HAL_Delay(20);
		if(receive_flag)
	{
		receive_flag=0;
		if(strstr((const char*)my_order,(const char*)"<on>")) //输入on,LED0亮
		{
			Uart2_Rx_Cnt=0;
			memset(RxBuffer,0x00,sizeof(RxBuffer)); //清空数组	
			memset(RxBuffer,0x00,sizeof(my_order)); //清空数组	
			my_test_v=1;
		}
		else if(strstr((const char*)my_order,(const char*)"<off>"))
		{
					Uart2_Rx_Cnt=0;
			memset(RxBuffer,0x00,sizeof(RxBuffer)); //清空数组	
			memset(RxBuffer,0x00,sizeof(my_order)); //清空数组	
		  my_test_v=0;
		}
		else
			{
			Uart2_Rx_Cnt=0;
			memset(RxBuffer,0x00,sizeof(RxBuffer)); //清空数组	
			memset(RxBuffer,0x00,sizeof(my_order)); //清空数组	
		
		}
			
 	}
		if(my_test_v==1)	
			HAL_GPIO_WritePin(GPIOA,GPIO_PIN_8,GPIO_PIN_RESET );
		else
	  	HAL_GPIO_WritePin(GPIOA,GPIO_PIN_8,GPIO_PIN_SET );
			
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}

做完之后直接编译下载就ok。

3.手机端控制

        3.1 esp8266和核心板的连接只需要四个引脚,vcc(3.7—5v的稳定电源,不稳定的话会不断重启),gnd,rx,tx。其中,模块的rx接核心板的tx,tx接核心板的rx。

        3.2 初始化(4s)后,模块就会发出名字为esp8266的热点,密码为12345678。

 

        3.3 手机接入后打开“tcp连接”app(这个热点没有网络,有些手机连接后一会儿后自动就断开了,所以要设置下,我是直接把数据流量关了就行了)

 (随便一个网络调试助手都行,只要是支持TCP连接的就行,主要要能发字符串的,有些助手只能发16进制数据)

        3.4 连接(IP地址一般是192.168.4.1不正确的话需要用串口助手给wifi模块发送AT指令查看连接设备的地址,当然也可以程序上发送后在线调试看数组)

         3.5 发送数据,记住要加英文输入法的“<>”,就能看到灯的亮灭了。

 

        In addition:

    1.需要注意的是,esp8266wifi模块相当于一个下好程序的核心板,你只需要通过给它发送串口的AT指令来进行控制它的各种动作。初始化也不是对引脚初始化,是通过串口对它发送AT指令。所以初始化后如果不给esp8266断电的话是不用再次初始化的,因为每次初始化后重启会话4s的时间,所以想不断下程序来调试的话,可以把初始化函数(esp8266_start_trans();)注释了,就不用每次都额外等4s的时间了。

    2.我的stm32用的是串口接受中断来接受的指令,弄完这个后可以改进为串口DMA加IDLE中断的方法接收串口数据。

cubumx串口学习https://blog.csdn.net/as480133937/article/details/99073783

我的程序

https://pan.baidu.com/s/1pgkcq4Y4q_rJX1B2OvvlPw?pwd=1234

  提取码:1234

物联沃分享整理
物联沃-IOTWORD物联网 » STM32CubeMX新建STM32HAL库控制ESP8266WIFI模块点亮LED灯。速成,简单一步到位

发表评论