使用STM32F1控制ESP8266获取网络时间

ESP8266:web

  本次STM32控制ESP8266使用的ESP芯片版本是ESP8266-01S,主机MCU使用的是STM32F1C8T6。json

  ESP8266是乐鑫公司的一款WIFI芯片(Soc),而且能够被看成MCU使用。实际上,ESP系列芯片是一款发行量巨大,性价比极高的芯片。api

  本次我想要实现的功能是获取网络时间供MCU使用,因此选择结构简单的一款封装——ESP01S,ESP01S的具体参数以下(图源:安信可ESP8266开发手册)数组

  

  与STM32 C8T6的链接方式以下:(图源:安信可ESP8266开发手册)网络

  

  ESP8266的通讯方式是串口通讯,因为我的开发需求,我选择的是USART2接口,实际串口可自主选择。app

程序初始化(usart2.c):函数

  须要初始化的片上外设有USART2,具体以下:spa

void USART2_Init(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    USART_InitTypeDef USART_InitStructure;
    NVIC_InitTypeDef NVIC_InitStructure;
    
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);  //GPIO时钟    
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2,ENABLE);  //串口外设时钟
    
    GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;  //推挽复用输出        
    GPIO_InitStructure.GPIO_Pin=GPIO_Pin_2;                   
    GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
    GPIO_Init(GPIOA,&GPIO_InitStructure);

    GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING;  //浮空输入       
    GPIO_InitStructure.GPIO_Pin=GPIO_Pin_3;                 
    GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;           
    GPIO_Init(GPIOA,&GPIO_InitStructure); 

    USART_InitStructure.USART_BaudRate = 115200  ;  //波特率,这里改成115200与ESP8266通讯 
    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_Tx|USART_Mode_Rx;  //收发一体                          
    USART_Init(USART2,&USART_InitStructure);  //完成初始化      
    
    USART_Cmd(USART2,ENABLE);  //使能串口
    

    USART_ITConfig(USART2,USART_IT_RXNE,ENABLE);  //使能串口中断  
    
    //优先级配置
    NVIC_InitStructure.NVIC_IRQChannel=USART2_IRQn;  
    NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;   
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority=0; 
    NVIC_Init(&NVIC_InitStructure);       
    
}

  由于咱们须要发送,接收ESP芯片的信息,因此这里需重定向printf函数到串口,并定义接收中断函数(接收中断函数部分参考网上大佬思路)3d

//输出重定向
int fputc(int ch, FILE *f)
{      
    while((USART2->SR&0X40)==0);//循环发送,直到发送完毕   
    USART2->DR = (u8) ch;      
    return ch;
}

 

//接收中断
void USART2_IRQHandler(void)
{
    u8 Res;

    if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET)
        {
        Res =USART_ReceiveData(USART2);    //读取接收到的数据
        
        if((USART_RX_STA2&0x8000)==0)//接收未完成
            {
            if(USART_RX_STA2&0x4000)//接收到了0x7D}
                {
                if(Res!=0x7D)USART_RX_STA2=0;//接收错误,从新开始
                else USART_RX_STA2|=0x8000;    //接收完成了 
                }
            else //还没收到0X7D }
                {    
                if(Res==0x7D)USART_RX_STA2|=0x4000;
                else
                    {
                    USART_RX_BUF2[USART_RX_STA2&0X3FFF]=Res ;
                    USART_RX_STA2++;
                    if(USART_RX_STA2>(1024-1))USART_RX_STA2=0;//接收数据错误,从新开始接收      
                    }         
                }
            }            
    } 

} 

  在接收中断中,有两个变量在函数头进行全局声明,并在头文件中进行extern声明,方便其余函数使用。code

  其中USART_RX_BUF2[512]用于接收数据,长度自定。

//usart2.c函数头
#include "stm32f10x.h" #include "stm32f10x_usart.h" #include "usart2.h" #include <stdio.h> u8 USART_RX_BUF2[512]; u16 USART_RX_STA2;

 

 

向ESP8266发送信息

  接下来,进行ESP01.c文件的构建,首先想要得到时间,必须先链接互联网。

void ESP01_Getweb(void)
{
    delay_ms(50);
    
    printf("AT+CWMODE=1");
    delay_ms(50);
    RST_ON;
    delay_ms(100);
    RST_OFF;
    delay_ms(50);
    
    USART_RX_STA2=0x0000;
    printf("AT+CWJAP=\"WIFI name\",\"password\"");
    delay_ms(1000);  //注意delay时间限制
    delay_ms(1000);
    delay_ms(1000);
    delay_ms(1000);
    delay_ms(1000);
}

  这里延时状况由具体状况而定,可适当缩短。ESP的链接仅需一次便可,下次在一样的环境下可自主登入。

  而后是获取网络时间,这里须要调用一个网络API接口,这个接口会返回标准网络时间。

void ESP01_Gettime(void)
{
    printf("AT+CIPMUX=0\r\n");
    delay_ms(500);
    
    printf("AT+CIPSTART=\"TCP\",\"api.k780.com\",80\r\n");
    delay_ms(1600);
    
    printf("AT+CIPMODE=1\r\n");
    delay_ms(500);
    
    printf("AT+CIPSEND\r\n");
    delay_ms(500);
    USART_RX_STA2=0x0000;  //使数据从数组头开始记录
    printf("GET http://api.k780.com:88/?app=life.time&appkey=10003&sign=b59bc3ef6191eb9f747dd4e83c99f2a4&format=json&HTTP/1.1\r\n");
    delay_ms(1600);
}

  这里延时能够根据自身状况而定,实际上在每次发送指令后,ESP都会返回数据,能够由此判断是否接收成功数据。

 

  接收完成后,数据会储存在USART_RX_BUF2这个数组中,经过提取有效信息,便可获取时间,自此,经过ESP获取时间就完成了(实测成功)。

  

  (因为我的水平有限,在程序中,可能会出现冗余或低效的地方,请注意)  =)

相关文章
相关标签/搜索