STM32 ESP8266WiFi模块的使用:基于机智云平台开发

概述

        本文介绍在机智云物联网云平台上实现基于STM32的WiFi通信功能,即通过WiFi发送指令,使STM32能够完成特定的操作。具体介绍如何通过WiFi控制LED灯的亮灭,更多复杂功能可自行拓展。

        这里将使用一个WiFi模块来连接单片机,在WiFi模块中烧写固件,同时在单片机中移植所需的代码,最终实现所需的功能。

硬件准备

  1. 任意一种STM32单片机
  2. 一个WiFi模块:推荐使用ESP-07S、ESP-12S或者ESP-12F,这是机智云平台开发文档中推荐的安信可科技开发的WiFi模块。由于这三种WiFi模块在网上售卖的都是无引脚的,所以需要在同一家网店额外购买引脚并自行焊接。当然了,机智云平台的开发文档中还说明了其他厂商WiFi模块的使用,这里不作详细介绍,只介绍安信可ESP8266系列。按理来说除了ESP-07S、ESP-12S或者ESP-12F,其他WiFi模块也可以,但本人没有试过,如果使用其他安信可ESP8266系列的WiFi模块,注意其Flash大小,只有8Mbit、16Mbit和32Mbit大小的才行,常见的ESP-01S应该是8Mbit的。

软件准备

  1. keil5 MDK
  2. 机智云产品调试APP,用于在手机上发送指令来控制STM32(在“开发者中心”-“下载中心”-“机智云产品调试APP”,扫码下载到手机上)

详细步骤

一、创建产品
  1. 搜索“机智云”,进入官网。

  2. 在官网点击右上角“开发者中心”,注册,登录。
  3. 点击创建智能产品。

  4. 根据需要选择方案。这里举例使用“照明”中的“自定义方案”,点击图中的“灯”。

  5. 填写产品名称,数据传输方式改为“定长”,点击“创建”。

  6. 点击“去编辑”以创建数据点。

  7. 编辑相关信息,由于只需控制LED灯的亮灭,一共两种状态,故选择数据类型为“布尔值”,届时,STM32将收到LED灯的开或者关信息。如需其他功能,可选择枚举(如需要控制灯变为红、绿、蓝等颜色)、数值(如需要给某个变量赋值)、拓展(自定义数据类型)。读写类型的“可写”意味着可以在手机APP上通过WiFi改变变量,“只读”意味着只能在手机APP上显示变量,不能更改。

二、烧录固件
  1. 说明:将机智云提供的GAgent固件烧录到WiFi模块中,目的是使WiFi模块能够连接WiFi并接收到网络指令。
  2. 下载烧录工具:在“开发者中心”-“文档中心”-左侧“机智云平台概述”-“设备接入”-“GAgent通讯模组使用教程”-“ESP8266串口烧写说明”,下载模组资料,如图:

  3. 下载完成后打开得到如下文件,其中,“规格说明书”为三种WiFi模块的说明文档;“模组固件”为要烧写进WiFi模块的固件,提供给Flash为32Mbit的WiFi模块的;“模组日志解码映射文件”另作他用,暂不需要;“烧录工具”即为烧录所需工具。

  4. 如所用WiFi模块不是SPI Flash为32Mbit的,则需另行下载模组固件,在“开发者中心”-“下载中心”,一般进入“下载中心”即为GAgent固件下载页面,下载如图所示固件包:

  5. 在之前打开的“ESP8266串口烧写说明”中即有烧写步骤,可按其中步骤烧写,这里不再另行说明,需要注意的是,如果使用的不是SPI Flash为32Mbit的WiFi模块,需要更改下图中的选项;另外,WiFi模组内部电路有的引脚已经默认上拉,不需要连接,可在“规格说明书”中查看,不确定的也可以直接按步骤说明全部连接。
三、移植代码
(1)文件获取
  1. 说明:STM32是通过串口和WiFi模块进行通信的,为了STM32能够接收到WiFi模块传递的指令,需要移植所需代码。
  2. 在“开发者中心”,进入所创建的智能产品中,选择“独立MCU方案”,点击左侧的“MCU开发”,选择硬件平台为“其他平台”,这是为了能将生成的代码包移植到任意一种硬件平台上。填入“Product Secret”,在左上角有显示。然后点击生成“代码包”。生成完毕后点击下载。

  3. 下载完成后打开得到如下图所示文件:最下面的PDF文档为移植步骤说明,由于其中的步骤并非很详细完整,在这里另外说明移植步骤。

(2)文件转移
  1. 接下来,开始移植代码。首先,将上图文件中的Gizwits和Utils文件复制粘贴到STM32工程文件中,如下图所示:

  2. 打开keil5软件,将这两个文件夹添加为STM32工程文件的两个组,如下图中的组Gizwits和组Utils:

  3. 之后,将这两个组的文件路径添加到头文件路径中,如下图所示:

  4. 打开上述第3点所示的文件夹中的User文件,有一个main.c文件,打开,复制如下6行代码到STM32的main.c文件中:

  5. 复制粘贴时按照对应位置放置,如下图所示:

 (3)完善代码
     ①实现串口驱动
  1. MCU方案需要用户实现一个串口,用于设备MCU与WIFI模组之间的数据通信,同时,需要实现串口接收中断服务函数接口,该接口调用gizPutData()函数实现串口数据的接收并且写入协议层数据缓冲区。所以现在需要配置一个串口并编写其中断服务函数,这里使用串口USART1。
    #include "stm32f10x.h"                  // Device header
    #include "gizwits_product.h"
    
    void Serial1_Init(void)
    {
    	RCC_APB2PeriphClockCmd (RCC_APB2Periph_GPIOA |RCC_APB2Periph_USART1,ENABLE );
    	
    	GPIO_InitTypeDef GPIO_InitStructure;
    	GPIO_InitStructure.GPIO_Mode =GPIO_Mode_AF_PP;
    	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
    	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_9;
    	GPIO_Init(GPIOA,&GPIO_InitStructure);
    	
    	GPIO_InitStructure.GPIO_Mode =GPIO_Mode_IPU;
    	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
    	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_10;
    	GPIO_Init(GPIOA,&GPIO_InitStructure);
    	
    	USART_InitTypeDef USART_InitStructure;
    	USART_InitStructure.USART_BaudRate=9600;
    	USART_InitStructure.USART_HardwareFlowControl=USART_HardwareFlowControl_None;
    	USART_InitStructure.USART_Mode=USART_Mode_Tx|USART_Mode_Rx ;
    	USART_InitStructure.USART_Parity=USART_Parity_No;
    	USART_InitStructure.USART_StopBits=USART_StopBits_1;
    	USART_InitStructure.USART_WordLength=USART_WordLength_8b;
    	USART_Init(USART1 ,&USART_InitStructure);
    	
    	USART_ITConfig (USART1 ,USART_IT_RXNE ,ENABLE);
    	
    	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
    	
    	NVIC_InitTypeDef NVIC_InitStructure;
    	NVIC_InitStructure.NVIC_IRQChannel=USART1_IRQn;
    	NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE ;
    	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1;
    	NVIC_InitStructure.NVIC_IRQChannelSubPriority=1;
    	NVIC_Init(&NVIC_InitStructure);                         
    	
    	USART_Cmd (USART1,ENABLE );                                 
    }
    
    void USART1_IRQHandler(void)                //USART1中断服务函数
    {
    	 uint8_t value = 0;
    	 if(USART_GetITStatus (USART1,USART_IT_RXNE )==SET)  
    	 {
    		 value=USART_ReceiveData (USART1);
                    
    		 gizPutData(&value, 1);             //用于实现串口数据的接收并且写入协议层数据缓冲区
    		 
    		 USART_ClearITPendingBit (USART1,USART_IT_RXNE );
    	 }
    }
    
    

    在上述代码中,要包含头文件#include "gizwits_product.h",因为下面的串口中断服务函数用到的函数gizPutData()在该文件中声明。

  2. 下面是这个C文件对应的头文件:

    #ifndef _SERIAL1_H
    #define _SERIAL1_H
    
    void Serial1_Init(void);
    
    #endif
    

  3. 完善串口写函数uartWrite(),用于发送数据报文到WiFi模组,该函数位于gizwits_product.c文件中,在该文件中找到该函数,添加图中框出的四行代码进去。

  4. 同时,在该文件中包含外设头文件#include "stm32f10x.h",因为所添加的几行代码涉及STM32外设USART。

     ②实现定时器
  1. 协议层使用到了一个系统时间,该事件单位为毫秒,所以要求用户实现一个毫秒定时器,并且实现中断服务函数,该函数调用gizTimerMs()实现协议层系统时间的维护。所以现在要配置一个定时器及其中断服务函数,这里用到定时器TIM4。
    #include "stm32f10x.h"                  // Device header
    #include "gizwits_product.h"
    
    void TIM4_Init(void)
    {
    	RCC_APB1PeriphClockCmd (RCC_APB1Periph_TIM4 ,ENABLE );
    	
    	TIM_InternalClockConfig (TIM4);
    	
    	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
    	TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up ;
    	TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1 ;
    	TIM_TimeBaseInitStructure.TIM_RepetitionCounter=0;
    	TIM_TimeBaseInitStructure.TIM_Period=72-1;
    	TIM_TimeBaseInitStructure.TIM_Prescaler=1000-1;
    	TIM_TimeBaseInit (TIM4,&TIM_TimeBaseInitStructure);       //每1ms进入一次中断
    	
    	TIM_ClearFlag (TIM4,TIM_FLAG_Update );
    	
    	TIM_Cmd (TIM4,ENABLE );
    	
    	TIM_ITConfig (TIM4,TIM_IT_Update ,ENABLE );
    	
    	NVIC_PriorityGroupConfig (NVIC_PriorityGroup_2 );
    	
    	NVIC_InitTypeDef NVIC_InitStructure;
    	NVIC_InitStructure.NVIC_IRQChannel=TIM4_IRQn ;
    	NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE ;
    	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0;
    	NVIC_InitStructure.NVIC_IRQChannelSubPriority=0;
    	NVIC_Init(&NVIC_InitStructure);
    }
    
    void TIM4_IRQHandler(void)                  //定时器TIM4中断服务函数
    {
    	if(TIM_GetITStatus(TIM4, TIM_IT_Update)==1)
    	{
    		gizTimerMs();                       //实现协议层系统时间的维护
    
    		TIM_ClearITPendingBit(TIM4, TIM_IT_Update);
    	}
    }
    

    其中,头文件包含#include "gizwits_product.h",因为中断函数中使用到的gizTimerMs()是在文件gizwits_product.c中定义的。但是这个函数没有在gizwits_product.h文件中声明,所以需要在该文件中声明一下该函数:

  2. 该C文件的头文件为:
    #ifndef _TIM4_H
    #define _TIM4_H
    
    void TIM4_Init(void);
    
    #endif
    

 ③实现芯片复位函数
  1. 根据串口协议文档规定,模组可以发送命令复位设备MCU,所以用户需要实现mcuRestart()接口完成设备的复位。
  2. 在gizwits_product.c文件中找到void mucRestart(void)函数,将下面两行代码移植到其函数体内:
     __set_FAULTMASK(1);
     NVIC_SystemReset();

    具体如图:

 ④实现串口打印驱动
  1. 如果用户需要打印日志调试信息,要求用户实现printf函数。协议层将用GIZWITS_LOG宏替代printf,进行相关信息的打印。如果用户不使用日志调试,那么需要将协议层相关日志打印部分的代码屏蔽掉方可运行。所以现在需要配置一个串口并实现printf重定向,这里使用串口USART3。
    #include "stm32f10x.h"                  // Device header
    #include <stdio.h>
    
    void Serial3_Init(void)
    {
    	RCC_APB2PeriphClockCmd (RCC_APB2Periph_GPIOB ,ENABLE );
    	RCC_APB1PeriphClockCmd (RCC_APB1Periph_USART3,ENABLE );
    	
    	GPIO_InitTypeDef GPIO_InitStructure;
    	GPIO_InitStructure.GPIO_Mode =GPIO_Mode_AF_PP;
    	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
    	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_10;
    	GPIO_Init(GPIOB,&GPIO_InitStructure);                             //配置发送引脚PB10
    	
    	GPIO_InitStructure.GPIO_Mode =GPIO_Mode_IPU;
    	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
    	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_11;
    	GPIO_Init(GPIOB,&GPIO_InitStructure);                             //配置接收引脚PB11
    	
    	USART_InitTypeDef USART_InitStructure;
    	USART_InitStructure.USART_Mode=USART_Mode_Rx | USART_Mode_Tx ;
    	USART_InitStructure.USART_BaudRate=9600;
    	USART_InitStructure.USART_WordLength=USART_WordLength_8b ;
    	USART_InitStructure.USART_Parity=USART_Parity_No ;
    	USART_InitStructure.USART_StopBits=USART_StopBits_1 ;
    	USART_InitStructure.USART_HardwareFlowControl=USART_HardwareFlowControl_None ;
    	USART_Init (USART3,&USART_InitStructure);
    	
    	USART_Cmd (USART3,ENABLE );
    }
    
    
    
    void Serial_SendByte3(uint8_t Byte)         //通过USART3发送一个字节
    {
    	USART_SendData (USART3 ,Byte);
    	while (USART_GetFlagStatus (USART3 ,USART_FLAG_TXE )==RESET );
    }
    
    int fputc(int ch,FILE *f)       //printf重定向,需要#include <stdio.h>,作用是打印到串口
    {
    	Serial_SendByte3(ch);
    	return ch;
    }
    
    

    这里的printf重定向的方法需要使用精简c库,点击“魔术棒”按钮(Options for Target),勾选Use McroLIB选项。

  2. 该C文件的头文件为:
    #ifndef _SERIAL3_H
    #define _SERIAL3_H
    #include <stdio.h>
    
    void Serial3_Init(void);
    
    #endif
    

⑤实现配置入网
  1.  模组支持SoftAp和AirLink两种方式配置入网,相应接口为gizwitsSetMode(),官方指导书建议使用按键方式选择配网方式,这里不详细介绍按键选择方式,只用最简单的单一配网选择方式。

    /*配置入网*/
    	gizwitsSetMode(WIFI_SOFTAP_MODE);  //使用SoftAP方式配置入网
    //	gizwitsSetMode(WIFI_AIRLINK_MODE); //使用AirLink方式配置入网
    //	gizwitsSetMode(WIFI_RESET_MODE);   //复位

    上述代码移植到main.c文件的主函数内、while循环外,如图:

  2. 用户可以自行选用一种配网方式,如果感兴趣,可以根据官方指导书使用按键选择方式,或者自行设计代码。

⑥实现下行动作执行
  1. 这一步需要完善gizwits_product.c 文件中的gizwitsEventProcess()函数,目的是根据指令完成相应的操作。在前面的步骤中,我们创建了一个数据点Light_On_Off,它是布尔类型的,它只有两个值1或0,现在要做的就是编写代码,完成功能:当Light_On_Off为1时做什么,当Light_On_Off为0时做什么。其他类型的数据点类似。

  2. 现在,配置一个控制LED开关的模块,其c文件如下:

    #include "stm32f10x.h"                  // Device header
    
    void LED_Init(void)
    {
        RCC_APB2PeriphClockCmd (RCC_APB2Periph_GPIOA ,ENABLE );
    	
    	GPIO_InitTypeDef GPIO_InitStructure;
    	GPIO_InitStructure.GPIO_Mode =GPIO_Mode_Out_PP;
    	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
    	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_1;
    	GPIO_Init(GPIOA,&GPIO_InitStructure);
    	
    	GPIO_SetBits (GPIOA ,GPIO_Pin_1);
    }
    void LED_ON(void )
    {
    	GPIO_ResetBits(GPIOA ,GPIO_Pin_1);
    }
    
    void LED_OFF(void )
    {
    	GPIO_SetBits (GPIOA,GPIO_Pin_1);
    }
    

    其头文件如下:

    #ifndef _LED_H
    #define _LED_H
    
    void LED_Init(void);
    void LED_ON(void );
    void LED_OFF(void );
    
    #endif
    

  3. 然后,在gizwits_product.c文件中找到gizwitsEventProcess()函数,在相应位置编写所需代码,如图:

  4. 同时,需要在main.c文件的主函数中声明全局变量LED_Switch,用于控制LED的亮灭。

  5. 然后,在gizwits_product.c文件中也声明这个变量。

  6. 在主函数的while循环中编写根据变量LED_Switch控制LED亮灭的程序。一些头文件的包含什么的就不多说了,包括前面的串口和定时器的头文件,也要包含到main.c文件中,还要将对应的初始化函数在主函数中写出来。

⑦实现上行数据采集
  1. 这里需要将数据采集起来,即根据LED的亮灭更改数据点的值。现在要做的就是完善userHandle()函数,即更改currentDataPoint(数据点)结构体中的变量的值。
  2. 在gizwits_product.c文件中找到userHandle()函数的定义位置,编写如下代码: 

⑧初始化
  1. 这里需要给数据点中的变量赋一个初始值。
  2. 在gizwits_product.c文件中找到userInit()函数的定义位置,编写如下代码:

 ⑨主函数

最后的主函数如下:

#include "stm32f10x.h"                  // Device header
#include "Delay.h"

#include "gizwits_product.h"
#include "common.h"

#include "Serial1.h"
#include "Serial3.h"
#include "TIM4.h"
#include "LED.h"

uint8_t LED_Switch=0;

int main(void)
{
	userInit();     //数据点初始化,需用户编写
	gizwitsInit();  //完成Gizwits协议相关初始化
	Serial1_Init();
	Serial3_Init();
	TIM4_Init();
	LED_Init();
	
	/*配置入网*/
	gizwitsSetMode(WIFI_SOFTAP_MODE);  //使用SoftAP方式配置入网
//	gizwitsSetMode(WIFI_AIRLINK_MODE); //使用AirLink方式配置入网
//	gizwitsSetMode(WIFI_RESET_MODE);   //复位
	
	while(1)
	{
		if(LED_Switch==1)
		{
			LED_ON();
		}
		else
		{
			LED_OFF();
		}
		
		userHandle();                                   //用于数据采集,需用户编写
		gizwitsHandle((dataPoint_t *)&currentDataPoint);//用于数据处理和上传到机智云平台
	}


}

文件有:

 四、手机APP测试
  1. 手机APP可以使用前面要求下载的机智云产品调试APP,也可以另外为这个产品生成一个APP。这里两种都介绍一下。
  2. 首先,可以打开机智云产品调试APP,点击右上角的“+”号,选择前面的代码中自己指定的配网方式,然后一步步进行。
  3. 或者,还可以为这个产品创建一个APP,在“开发者中心”,点击“创建应用”(当然,也可以使用微信小程序,这里不再介绍),填写信息,然后点击确认。

  4. 下面,点开该应用,点击上方的“构建应用”。

  5. 然后,点击左侧的“构建应用”。

  6. 之后,点击“构建测试版”。

  7. 之后就是等待构建完成,然后下载到手机上。

  8. 最后,回到开发者中心,点开左侧我们创建的产品,然后点击上方的“控制页面”,点击“关联产品”,然后,就可以在已经下载的手机APP上完成配网等操作了,之后就可以在手机上完成通过WiFi控制STM32的功能了。

  9. 需要注意的是,无论使用哪个APP、哪种配网方式来配网,都需要连接2.4GHz的WiFi,如果连接的是5G的WiFi,那么配网将不成功,注意查看自己所连WiFi是不是5G的。如果没有2.4GHz的WiFi,可以用另一个手机打开热点,在热点设置中将热点设为2.4GHz,然后就可以使用该热点来操作了。
  • 11
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
STM32ESP8266WiFi模块是一种将ESP8266 Wi-Fi SoC整合到STM32微控制器上的硬件设备。它允许STM32系列单片机通过Wi-Fi网络进行通信,支持多种协议,包括TCP/IP、HTTP、HTTPS、FTP、SMTP、CoAP等,适合构建物联网应用、智能家居系统或是无线数据传输设备。 ### STM32ESP8266WiFi模块教程概览 #### 1. 安装和设置硬件连接 首先,你需要准备一块带有STM32ESP8266模块的开发板,并且确保该模块已经安装在你的开发板上。通常情况下,ESP8266需要通过串口进行配置,在烧录固件前,你可以参考官方文档或社区教程了解如何安全地烧录ESP8266的固件。 #### 2. 硬件配置 - **电源**:给ESP8266提供稳定的5V电源,通常由STM32供电。 - **GPIO配置**:选择合适的GPIO用于发送和接收串行通信数据。 - **串行通信**:确保正确的波特率配置。常用的是115200bps。 - **其他配置**:可能还需要设置ESP8266的工作模式(如AP模式、STA模式)、SSID、密码等。 #### 3. 软件开发环境搭建 - **IDE**:推荐使用Keil uVision或其他支持STM32的集成开发环境(IDE)。 - **库管理**:利用第三方库管理工具,比如STM32CubeMX,可以自动帮助生成兼容STM32的代码和库文件。 - **ESP8266库**:可能需要额外下载并添加ESP8266相关库到项目中,比如Arduino ESP8266库。 #### 4. 编程示例 - **初始化ESP8266**:编写代码来初始化ESP8266并配置其工作模式。 - **连接Wi-Fi**:实现代码以连接特定的Wi-Fi网络。 - **发送HTTP请求**:发送GET或POST请求至Web服务器获取或上传数据。 - **响应处理**:解析返回的数据并显示结果。 - **断开连接**:当任务完成后,确保释放资源并安全地关闭ESP8266的连接。 #### 5. 测试与调试 运行程序,测试是否能正常连接Wi-Fi、访问互联网、发送请求并接收数据。同时,利用调试工具检查程序状态,确保无误。 #### 6. 进阶功能探索 随着对STM32ESP8266WiFi理解的加深,可以进一步研究更复杂的网络操作,如SSL加密通信、UDP协议使用、以及更多高级功能的应用。 #### 相关问题: 1. 在实际开发中遇到ESP8266无法正常连接Wi-Fi怎么办? 2. 如何优化ESP8266的功耗以延长电池寿命? 3. 在STM32使用ESP8266进行数据实时监控和控制的具体步骤是什么? 以上内容仅为入门级指导,实际开发过程中还需查阅详细的技术手册和教程,不断实践和学习才能更好地掌握STM32ESP8266WiFi模块使用技巧。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值