以下实验已经成功本人亲自试过(在下列代码中没有粘贴出连接路由器那部分代码,只是粘贴了连接TLINK部分,因为该部分有一定学习意义)
实现 TCP 和 UDP 通信主要围绕连接热点,连接服务器,向服务器发送数据和接收服务器
传回来的信息这四个大的方面来展开。
实现设备连接远程服务器的流程为:
STM32程序: 常见操作
⚫ ESP8266 握手函数——STM32连接上ESP8266
(使用 AT\r\n 来检查此时 ESP8266 的状态,如果回复 OK)
⚫ **ESP8266 初始化函数⚫ **
退出透传模式并重启,
检查 ESP8266 是否正常(是否连接成功),
关闭回显
⚫ 恢复出厂设置
该函数后 ESP8266 会删除所有用户设置并重启
⚫ 连接 AP(无线路由器 )⚫
⚫ 使用指定协议连接到指定服务器⚫
⚫ 断开与服务器的连接
⚫ 发送数据到服务器⚫(STM32发数据给平台)
设备和服务器的通信都是通过该函数来完成的
⚫ 接收数据⚫
⚫ 处理接收数据⚫
如控制 LED 和继电器
⚫⚫⚫最重要的一个操作是检测发送指令后ESP8266返回值是否和程序设置值一样
⚫⚫⚫注意以下几点:
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
}
}
}
下面是串口发送字符串函数因为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
}
}
}
}