STM32 通过 ESP8266 AT指令连接阿里云物联网平台

模组  :ESP-12F   ||   ESP-12S  ||   待补充 ...

平台  :阿里云物联网平台

MCU :STM32F103RCT6

固件  :ESP8266 MQTT透传AT固件

准备工作:实现《ESP8266 AT指令连接阿里云物联网平台》

1.烧录ESP8266 MQTT透传 AT固件

2.部署好阿里云物联网平台

3.计算出MQTT的连接参数

4.AT指令实现连接阿里云物联网平台

5.AT指令实现阿里云物联网平台通讯

文章目录:

一、下载 ESP8266的STM32工程示例

二、解读 ESP8266的STM32工程示例

三、测试 MQTT通讯

四、工程的存在问题


 

一、下载 ESP8266的STM32工程示例

下载地址:https://docs.ai-thinker.com/esp8266/examples/at_demo

下载说明:工程示例归ai-thinker所有,资源是在2020/05/20更新的,存在很多bug,笔者看着有点头疼,改了一段时间。

1. 我下载《使用文档》一直出错,没有下载成功,所以demo包都是自己阅读代码理解的,如果有错误,大家指正一下,谢谢。

2. 我用MDK5打开ESP8266的STM32工程,点击某个文件会闪退,然后重新下载了几次,工程才变正常,不知道具体原因。所以,为大家附上官方demo源码包(该demo更新时间为2020/05/20),以及我个人做了修改的demo源码包。

3. 官方工程bug很多,如果大家不想自己修改,建议使用我修改过的工程,当然,我的工程也有很多bug,逐步完善中... ...

链接:https://pan.baidu.com/s/1YWhsK6STZVUouneQYa152A 
提取码:j4k2 

二、解读 ESP8266的STM32工程示例

说明:解读以笔者的工程为示例,官方示例那个真的欲哭无泪,我花费了很长时间去修改,我还需要慢慢完善自己的工程 !!

1. 默认连线方式:

UASRT3 :  用来打印信息(大家可以根据自己的需要改为其他串口)

UASRT2 :  用来与ESP8266通信

 
引脚 连接 引脚说明
GPIOA2 U2_TX 连接ESP8266的 RX 引脚
GPIOA3 U2_RX 连接ESP8266的 TX 引脚
GPIOA4 ESP8266_RST 连接ESP8266的 RST 引脚
GPIOA5 ESP8266_EN 连接ESP8266的 EN 引脚
GPIOB10 U3_TX 连接USB转TTL的 RX 引脚
GPIOB11 U3_RX 连接USB转TTL的 TX 引脚

特别提醒:各个模块记得共地,不然可能模块不工作,或者打印不出信息,或者打印各种乱码,我最近才意识到“共地”的问题

2.用户需要修改:

(1)esp8266.h

STM32 通过 ESP8266 AT指令连接阿里云物联网平台_第1张图片

(2)mqtt.h :

STM32 通过 ESP8266 AT指令连接阿里云物联网平台_第2张图片

3. 串口接收协议

 ESP8266串口(即USART2)接收结构体定义

#define RX_BUF_MAX_LEN 1024       //最大字节数,最大可以设为2^14
extern struct STRUCT_USART_Fram   //数据帧结构体
{
    char Data_RX_BUF[RX_BUF_MAX_LEN];
    union 
    {
        __IO u16 InfAll;						//所有信息
        struct 
        {
            __IO u16 FramLength       :15;     	// 接收字节长度  14:0 
            __IO u16 FramFinishFlag   :1;      	// 接收完成标志  15 
        }InfBit;								//按位信息
    }; 
	
}ESP8266_Fram_Record_Struct;

 

ESP8266串口配置参数

 

void uart2_Init(u32 bound)//串口2  引脚为PA2--U2_TX  PA3--U2_RX
{
	USART_InitTypeDef USART_InitStructure;
	GPIO_InitTypeDef  GPIO_InitStructure;
	NVIC_InitTypeDef NVIC_InitStructure;
	
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);	    //使能指定端口时钟
	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;	//复用推挽输出
	GPIO_Init(GPIOA, &GPIO_InitStructure);			//初始化GPIOA3
	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING;
	GPIO_Init(GPIOA, &GPIO_InitStructure);			//初始化GPIOA2
	
	//USART2 NVIC 配置
	NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;      
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;         
	NVIC_Init(&NVIC_InitStructure); 

	
	//USART2 参数 配置
	USART_InitStructure.USART_BaudRate = bound;										//设置串口波特率
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;						//字长为8
	USART_InitStructure.USART_StopBits = USART_StopBits_1;							//1个停止位
	USART_InitStructure.USART_Parity = USART_Parity_No;								//无奇偶校验
	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;	//无流控
	USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;					//收发模式
	USART_Init(USART2, &USART_InitStructure); 										//配置USART参数
						
    USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);									//配置了接收中断
    USART_ITConfig(USART2, USART_IT_IDLE, ENABLE);									//配置总线空闲中断

	USART_Cmd(USART2, ENABLE);            			//使能USART2
}

 

ESP8266串口(即UASRT2)接收数据的过程

void USART2_IRQHandler( void )
{
	u8 ucCh;
    if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET)		//检测到接收区非空
    {
		USART_ClearITPendingBit(USART2, USART_IT_RXNE); 
		ucCh = USART_ReceiveData(USART2);
		/*未超出1024个字节的字符串*/
        if(ESP8266_Fram_Record_Struct .InfBit .FramLength < ( RX_BUF_MAX_LEN - 1 ) ) 		// -1的目的:至少保留最后一位做结束位,补'\0'
        {
            ESP8266_Fram_Record_Struct .Data_RX_BUF[ ESP8266_Fram_Record_Struct .InfBit .FramLength ++ ]  = ucCh;   
        }
		/*对超出1024个字节的字符串做容错处理*/
		
    }
    else if(USART_GetFlagStatus(USART2, USART_FLAG_IDLE) != RESET)		//检测到总线空闲
    {
        USART2->SR;
        USART2->DR;
        ESP8266_Fram_Record_Struct .InfBit .FramFinishFlag = 1;	
		ESP8266_Fram_Record_Struct.Data_RX_BUF[ESP8266_Fram_Record_Struct.InfBit.FramLength] = '\0';
		
//      TcpClosedFlag = strstr ( ESP8266_Fram_Record_Struct .Data_RX_BUF, "CLOSED" ) ? 1 : 0;
//		TcpReceiveFlag = strstr ( ESP8266_Fram_Record_Struct .Data_RX_BUF, "+IPD" ) ? 1 : 0;
		
		MQTTReceiveFlag = strstr ( ESP8266_Fram_Record_Struct .Data_RX_BUF, "+MQTTSUBRECV" ) ? 1 : 0;
 //       MQTTClosedFlag = strstr ( ESP8266_Fram_Record_Struct .Data_RX_BUF, "CLOSED" ) ? 1 : 0;
		
    }
}

 

三、测试 MQTT通讯

 

void ESP8266_STA_MQTTClient_Test(void)
{
	char mqtt_message[1024];
	char str[128] = {0};
	u8 cnt = 0;
	
	printf("正在配置 ESP8266 MQTT ...\r\n");
	
    ESP8266_AT_Test();						//恢复出厂默认
    ESP8266_Net_Mode_Choose(STA);			//配置热点信息
    while(!ESP8266_JoinAP(User_ESP8266_SSID, User_ESP8266_PWD));
	ESP8266_MQTTUSERCFG(User_ESP8266_client_id,User_ESP8266_username,User_ESP8266_password);
	ESP8266_MQTTCONN( User_ESP8266_MQTTServer_IP, User_ESP8266_MQTTServer_PORT);
	
	ESP8266_MQTTSUB( User_ESP8266_MQTTServer_Topic);
	
	ESP8266_MQTTSUB( User_ESP8266_MQTTServer_Topic_Property_Post_Reply);
	
	ESP8266_MQTTSUB(User_ESP8266_MQTTServer_Topic_Property_Set);
	
	printf("ESP8266 MQTT 配置完成 ...\r\n");
	
	ESP8266_Fram_Record_Struct.InfAll = 0;	
	
	
	
	while(1)
	{
		//每32s发送一次
		if(cnt % 32 == 0)
		{

			memset(str, sizeof(str),0);
			memset(mqtt_message,sizeof(mqtt_message),0);
			
			sprintf(str,"I AM ESP8266");//格式化发送字符串到MQTT服务器
			MQTT_SendString (User_ESP8266_MQTTServer_Topic,str);//发送数据到MQTT服务器
			
			sprintf(mqtt_message,"{\\\"method\\\":\\\"thing.service.property.post\\\"\\,\\\"id\\\":\\\"2012934115\\\"\\,\\\"params\\\":{\\\"PowerSwitch\\\":1}\\,\\\"version\\\":\\\"1.0.0\\\"}");			
			MQTT_SendString (User_ESP8266_MQTTServer_Topic_Property_Post,mqtt_message);//发送数据到MQTT服务器			
			
			
		}

		if(MQTTReceiveFlag == 1)		//判断是否接收到TCP网络数据
		{
			printf("Message From ESP8266 : %s\r\n",ESP8266_Fram_Record_Struct .Data_RX_BUF);
			printf("Length Of Message    : %d\r\n",ESP8266_Fram_Record_Struct.InfBit.FramLength);			
			ESP8266_Fram_Record_Struct.InfAll = 0;		//清空ESP8266_Fram_Record_Struct接收标志,准备接收下一条消息
			MQTTReceiveFlag = 0;
		}
		
		delay_ms(1000);
		cnt++;
		
	}
}

STM32 通过 ESP8266 AT指令连接阿里云物联网平台_第3张图片

STM32 通过 ESP8266 AT指令连接阿里云物联网平台_第4张图片

 

STM32 通过 ESP8266 AT指令连接阿里云物联网平台_第5张图片

 

- - 云端下发设置指令

 STM32 通过 ESP8266 AT指令连接阿里云物联网平台_第6张图片

++ ESP 接收到设置指令

 

四、工程的存在问题

 

1. 粘包问题 :

2. 混合度中:

你可能感兴趣的:(项目开发归档)