打印
[应用相关]

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

[复制链接]
734|21
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主

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

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



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


设置 ESP8266 连接 AP 热点使其正常上网 (连接路由器)

设置 ESP8266 连接远程/局域网 TCP 或 UDP 服务器(连接平台)如TCP Lab在线调试,或TLINK云服务(本文介绍)

将采集到的传感器数据发送到服务器

根据服务器传输过来的控制指令做出相应动作,如控制 LED 和继电器

———————————————


使用特权

评论回复
评论
发给她更好fh 2022-7-27 23:25 回复TA
— 版权声明:本文为CSDN博主「修心养性的bug」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/qq_24093081/article/details/114091763 
沙发
发给她更好fh|  楼主 | 2022-7-27 23:25 | 只看该作者
STM32程序: 常见操作
⚫ ESP8266 握手函数——STM32连接上ESP8266
(使用 AT\r\n 来检查此时 ESP8266 的状态,如果回复 OK)
⚫ **ESP8266 初始化函数⚫ **
退出透传模式并重启,
检查 ESP8266 是否正常(是否连接成功),
关闭回显
⚫ 恢复出厂设置
该函数后 ESP8266 会删除所有用户设置并重启
⚫ 连接 AP(无线路由器 )⚫
⚫ 使用指定协议连接到指定服务器⚫
⚫ 断开与服务器的连接
⚫ 发送数据到服务器⚫(STM32发数据给平台)
设备和服务器的通信都是通过该函数来完成的
⚫ 接收数据⚫
⚫ 处理接收数据⚫
如控制 LED 和继电器

使用特权

评论回复
板凳
发给她更好fh|  楼主 | 2022-7-27 23:26 | 只看该作者
最重要的一个操作是检测发送指令后ESP8266返回值是否和程序设置值一样

使用特权

评论回复
地板
发给她更好fh|  楼主 | 2022-7-27 23:27 | 只看该作者
注意以下几点:

使用特权

评论回复
5
发给她更好fh|  楼主 | 2022-7-27 23:28 | 只看该作者
连接上路由器后紧接着是连接云服务器TLINK
连接TLINK顺序如下:注意顺序不可调换

使用特权

评论回复
6
发给她更好fh|  楼主 | 2022-7-27 23:28 | 只看该作者
顺序:
先发云服务器TCP,IP,PORT连接上TLINK
sendString(USART2,"AT+CIPSTART=\"TCP\",\"112.74.142.132\",8647\r\n");//连接平台

使用特权

评论回复
7
发给她更好fh|  楼主 | 2022-7-27 23:29 | 只看该作者
发进入透传模式指令
sendString(USART2,"AT+CIPMODE=1\r\n"); 
delay_ms(200);
        sendString(USART2,"AT+CIPSEND\r\n");  
         delay_ms(200);

使用特权

评论回复
8
发给她更好fh|  楼主 | 2022-7-27 23:33 | 只看该作者
发TLINK服务器序号
sendString(USART2,"0WQ60ET6QJKW09JU\r\n");//连接平台
        delay_ms(800);

使用特权

评论回复
9
发给她更好fh|  楼主 | 2022-7-27 23:35 | 只看该作者
发数据:注意这里没有换行没有换行
sendString(USART2,"FM:40,21,0,#"); //这里不加回车

        delay_ms(800);

使用特权

评论回复
10
发给她更好fh|  楼主 | 2022-7-27 23:38 | 只看该作者
发数据:注意这里没有换行没有换行

使用特权

评论回复
11
发给她更好fh|  楼主 | 2022-7-27 23:42 | 只看该作者
sendString(USART2,"FM:40,21,0,#"); //这里不加回车

        delay_ms(800);

使用特权

评论回复
12
发给她更好fh|  楼主 | 2022-7-27 23:59 | 只看该作者
至此便可连接上TLINK

使用特权

评论回复
13
发给她更好fh|  楼主 | 2022-7-29 23:29 | 只看该作者
2.下面是接收TLINK发回数据处理操作:
即连接上TLINK要干什么

使用特权

评论回复
14
发给她更好fh|  楼主 | 2022-7-29 23:31 | 只看该作者
//串口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
                }
        }
}

使用特权

评论回复
15
发给她更好fh|  楼主 | 2022-7-29 23:32 | 只看该作者

使用特权

评论回复
16
发给她更好fh|  楼主 | 2022-7-29 23:32 | 只看该作者
下面是串口发送字符串函数因为ESP8266发送指令是通过发送字符串

使用特权

评论回复
17
发给她更好fh|  楼主 | 2022-7-29 23:33 | 只看该作者
/**
* 功能:指定某个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++);
    }
}

使用特权

评论回复
18
发给她更好fh|  楼主 | 2022-7-29 23:34 | 只看该作者
串口2初始化函数
该串口主要是为了与ESP8266通信

使用特权

评论回复
19
发给她更好fh|  楼主 | 2022-7-29 23:37 | 只看该作者
//串口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接收一帧中断
}

使用特权

评论回复
20
发给她更好fh|  楼主 | 2022-7-29 23:38 | 只看该作者
串口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

}

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

37

主题

546

帖子

1

粉丝