STM32通过ESP8266与平台通信——远程控制STM32——TLINK

以下实验已经成功本人亲自试过(在下列代码中没有粘贴出连接路由器那部分代码,只是粘贴了连接TLINK部分,因为该部分有一定学习意义)

实现 TCP 和 UDP 通信主要围绕连接热点,连接服务器,向服务器发送数据和接收服务器
传回来的信息这四个大的方面来展开。

实现设备连接远程服务器的流程为:

  1. 设置 ESP8266 连接 AP 热点使其正常上网 (连接路由器)
  2. 设置 ESP8266 连接远程/局域网 TCP 或 UDP 服务器(连接平台)如TCP Lab在线调试,或TLINK云服务(本文介绍)
  3. 将采集到的传感器数据发送到服务器
  4. 根据服务器传输过来的控制指令做出相应动作,如控制 LED 和继电器

STM32程序: 常见操作
ESP8266 握手函数——STM32连接上ESP8266
(使用 AT\r\n 来检查此时 ESP8266 的状态,如果回复 OK)
⚫ **ESP8266 初始化函数⚫ **
退出透传模式并重启,
检查 ESP8266 是否正常(是否连接成功),
关闭回显
⚫ 恢复出厂设置
该函数后 ESP8266 会删除所有用户设置并重启
⚫ 连接 AP(无线路由器 )⚫
⚫ 使用指定协议连接到指定服务器⚫
⚫ 断开与服务器的连接
⚫ 发送数据到服务器⚫(STM32发数据给平台)
设备和服务器的通信都是通过该函数来完成的
⚫ 接收数据⚫
⚫ 处理接收数据⚫
如控制 LED 和继电器

⚫⚫⚫最重要的一个操作是检测发送指令后ESP8266返回值是否和程序设置值一样

⚫⚫⚫注意以下几点:
STM32通过ESP8266与平台通信——远程控制STM32——TLINK_第1张图片
1.连接上路由器后紧接着是连接云服务器TLINK
连接TLINK顺序如下:注意顺序不可调换
顺序:
先发云服务器TCP,IP,PORT连接上TLINK

sendString(USART2,"AT+CIPSTART=\"TCP\",\"112.74.142.132\",8647\r\n");//连接平台

发进入透传模式指令

sendString(USART2,"AT+CIPMODE=1\r\n"); 
 delay_ms(200);
	sendString(USART2,"AT+CIPSEND\r\n");  
	 delay_ms(200);

发TLINK服务器序号

sendString(USART2,"0WQ60ET6QJKW09JU\r\n");//连接平台
	delay_ms(800);

发数据:注意这里没有换行没有换行

sendString(USART2,"FM:40,21,0,#"); //这里不加回车

	delay_ms(800); 

至此便可连接上TLINK

2.下面是接收TLINK发回数据处理操作:
即连接上TLINK要干什么

//串口2中断处理函数
void USART2_IRQHandler(void) 
{
	
static u8 i = 0;
if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET)//判断USART2是否接收到TLINK发来数据
{
	  RXBuffer[i++]= USART_ReceiveData(USART2);//保存数据
}
 
if(USART_GetITStatus(USART2, USART_IT_IDLE))//判断USART2是否接收完一帧TLINK发来数据
    {
        USART_ReceiveData(USART2);              //读一次UART可以清除空闲标志位
        i = 0;
		printf("%s",RXBuffer);//通过串口1发送给串口助手目的,方便我们查看TLINK发来的数据
		
		if(strstr(RXBuffer,"open")) //字符串对比函数,看RXBuffer中是否还有open这样的子串
		{
			LED1=0;
			sendString(USART2,"FM:40,21,1,#");//返回状态给TLINK
		
		}		
		if(strstr(RXBuffer,"off")) //字符串对比函数,看RXBuffer中是否还有off这样的子串
		{ 
			LED1=1;
			sendString(USART2,"FM:40,21,0,#");	//返回状态给TLINK
		}
	}
}

STM32通过ESP8266与平台通信——远程控制STM32——TLINK_第2张图片
下面是串口发送字符串函数因为ESP8266发送指令是通过发送字符串

/**
 * 功能:指定某个UART发送一个字节
 * 参数:USARTx:使用的目标串口x为1-3
 *       byte:待发送字节
 * 返回值:None
 */
void sendByte(USART_TypeDef *USARTx, u16 byte)
{
	USART_ClearFlag(USARTx, USART_FLAG_TC);             //软件清除发送完成标志位
    USART_SendData(USARTx, byte);                       //发送一个字节
    while (!USART_GetFlagStatus(USARTx, USART_FLAG_TC));//等待发送完成
    USART_ClearFlag(USARTx, USART_FLAG_TC);             //软件清除发送完成标志位
}

/**
 * 功能:指定某个串口发送字符串
 * 参数:USARTx:使用的目标串口x为1-3
 *       str:字符串指针
 * 返回值:None
 */
void sendString(USART_TypeDef *USARTx, char *str)
{
    while (*str)//直到\0退出
    {
        sendByte(USARTx,*str++);
    }
}

串口2初始化函数
该串口主要是为了与ESP8266通信

//串口2初始化函数
void initUART2(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	USART_InitTypeDef USART_InitStructure;
	NVIC_InitTypeDef NVIC_InitStructure;
	/*配置USART2和GPIO时钟*/
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);

	/*GPIO配置TX*/
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	 /*GPIO配置RX*/   
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	  
	/* UART2配置 */
	USART_InitStructure.USART_BaudRate = 115200;
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;
	USART_InitStructure.USART_StopBits = USART_StopBits_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;


	//Usart1 NVIC 配置
	NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2 ;//抢占优先级3
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;		//子优先级3
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;			//IRQ通道使能
	NVIC_Init(&NVIC_InitStructure);	//根据指定的参数初始化VIC寄存器



	USART_Init(USART2, &USART_InitStructure); 		//初始化化结构体
	USART_Cmd(USART2, ENABLE);						//使能串口2
    USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);	//使能串口2接收中断
    USART_ITConfig(USART2, USART_IT_IDLE, ENABLE);	//使能串口2接收一帧中断
}

串口1初始化
该串口主要是为了打印出来

//串口1初始化
void uart_init(u32 bound)
{
  //GPIO端口设置
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
 
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA, ENABLE);	//使能USART1,GPIOA时钟

//USART1_TX   GPIOA.9
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PA.9
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;	//复用推挽输出
GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.9
   
//USART1_RX	  GPIOA.10初始化
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;//PA10
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入
GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.10  

//Usart1 NVIC 配置
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ;//抢占优先级3
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;		//子优先级3
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;			//IRQ通道使能
NVIC_Init(&NVIC_InitStructure);	//根据指定的参数初始化VIC寄存器

//USART 初始化设置

USART_InitStructure.USART_BaudRate = bound;//串口波特率
USART_InitStructure.USART_WordLength = USART_WordLength_8b;						//字长为8位数据格式
USART_InitStructure.USART_StopBits = USART_StopBits_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(USART1, &USART_InitStructure); 		//初始化串口1
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);	//开启串口接受中断
USART_Cmd(USART1, ENABLE);                    	//使能串口1 

}

主函数

int main(void)
 {	 
	u8 key;
	u8 t=0;	
 	u8 *str=0;
	
 
	delay_init();	    	 //延时函数初始化	  
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置中断优先级分组为组2:2位抢占优先级,2位响应优先级
	uart_init(115200);	 	//串口初始化为115200
	initUART2();
 	LED_Init();			     //LED端口初始化

/***********该部分主要是消除ESP8266由于已经连接过返回错误****************/
sendString(USART2,"+++"); //退出透传
delay_ms(1000);
sendString(USART2,"AT+CIPSTATUS\r\n");//查状态
delay_ms(1000);

//是否连接过,是则重启再连接
if((u8)strstr(RXBuffer,"STATUS:3"))//表明之前连接了TLNK
{
sendString(USART2,"AT+RST\r\n");//重启ESP8266
delay_ms(1000);
connet_TLINK();//连接TLINK
}

//若没连接过则直接连TLINK
else connet_TLINK();

/**************该部分主要是循环发送数据给TLINK*****************/
while(1)
{
		if(strstr(RXBuffer,"no ip"))connet_TLINK();	
		 LED0=0;
		 delay_ms(1000); 
		if(t++>30)//此处t不宜过小否则会让TLINK禁用
		 {
			 t=0;
				
			if(strstr(RXBuffer,"open")) //字符串对比函数,看RXBuffer中是否还有open这样的子串
			{
				LED1=0;
				sendString(USART2,"FM:40,21,1,#");//返回状态给TLINK
		
			}		
			if(strstr(RXBuffer,"off")) //字符串对比函数,看RXBuffer中是否还有off这样的子串
			{ 
				LED1=1;
				sendString(USART2,"FM:40,21,0,#");	//返回状态给TLINK
			}	
		 }		
}

}

你可能感兴趣的:(笔记)