admin管理员组

文章数量:1620366

概述

利用ESP8266模块连接到远程服务器,服务器可以远程更新密码、请求密码。

ESP8266

这个模块是一个wifi模块,它可以作为AP、STA也可以两者共存,可以通过他进行wifi通讯,使用很方便。
淘宝有这种模块,十几块钱,很便宜。
引脚图

其中CH_PD是个使能脚,使用时要把他接高电平。VCC接5V,3.3V都是可以的。
他内部有一个32位的MCU,可以直接在他上面开发,我没研究过,所以没用。他可以通过穿过AT指令来快速开发。

对于他的编程,主要是通过串口对他发送相应的AT指令,然后接收他返回值,判断指令是否响应成功。
其中关键就是指令设置的程序了。

//ESP8266发送命令后,检测接收到的应答
//str:期待的应答结果
//返回值:0,没有得到期待的应答结果
//      其他,期待应答结果的位置(str的位置)
u8* esp8266_check_cmd(u8 *str)
{

    char *strx=0;
    if(USART3_RX_STA&0X8000)        //接收到一次数据了
    { 
        USART3_RX_BUF[USART3_RX_STA&0X7FFF]=0;//添加结束符
        strx=strstr((const char*)USART3_RX_BUF,(const char*)str);
    } 
    return (u8*)strx;
}
//向ESP8266发送命令
//cmd:发送的命令字符串
//ack:期待的应答结果,如果为空,则表示不需要等待应答
//waittime:等待时间(单位:10ms)
//返回值:0,发送成功(得到了期待的应答结果)
//       1,发送失败
u8 esp8266_send_cmd(u8 *cmd,u8 *ack,u16 waittime)
{
    u8 res=0; 
    USART3_RX_STA=0;
    u3_printf("%s\r\n",cmd);    //发送命令
    if(ack&&waittime)       //需要等待应答
    {
        while(--waittime)   //等待倒计时
        {
            delay_ms(10);
            if(USART3_RX_STA&0X8000)//接收到期待的应答结果
            {
                if(esp8266_check_cmd(ack))
                {
                    break;//得到有效数据 
                }
                    USART3_RX_STA=0;
            } 
        }
        if(waittime==0)res=1; 
    }
    return res;
} 

其中由于8266的指令返回值可能会发送多个,所以串口接收的时候,判断一下这是两个回复还是一个回复。这里用一个定时器,当接收间隔大于10ms就认为不是同一个回复了。

void USART3_IRQHandler(void)
{
    u8 res;     
    if(USART_GetITStatus(USART3, USART_IT_RXNE) != RESET)//接收到数据
    {    
        res =USART_ReceiveData(USART3);     
        if(USART3_RX_STA<USART3_MAX_RECV_LEN)       //还可以接收数据
        {
            TIM_SetCounter(TIM4,0);//计数器清空                       
            if(USART3_RX_STA==0)TIM4_Set(1);        //使能定时器4的中断 
            USART3_RX_BUF[USART3_RX_STA++]=res;     //记录接收到的值    
        }else 
        {
            USART3_RX_STA|=1<<15;                   //强制标记接收完成
        } 
    }                                            
}

//定时器4中断服务程序            
void TIM4_IRQHandler(void)
{   
    if (TIM_GetITStatus(TIM4, TIM_IT_Update) != RESET)//是更新中断
    {                  
        USART3_RX_STA|=1<<15;   //标记接收完成
        TIM_ClearITPendingBit(TIM4, TIM_IT_Update  );  //清除TIMx更新中断标志    
        TIM4_Set(0);            //关闭TIM4  
    }       
}
//设置TIM4的开关
//sta:0,关闭;1,开启;
void TIM4_Set(u8 sta)
{
    if(sta)
    {      
        TIM_SetCounter(TIM4,0);//计数器清空
        TIM_Cmd(TIM4, ENABLE);  //使能TIMx    
    }else TIM_Cmd(TIM4, DISABLE);//关闭定时器4      
}

然后就可以用它进行开发了,这是主函数,里面有8266基本用法,主要就是和目标服务器连接,然后和服务器通讯,并且轮询键盘。

u8 join_flag=0;
u8 change_flag=0;
extern u8 data[10];

u8 password[]={"1"};

void LOCK_Init(void)           //C12作为驱动门锁信号端口
{ 
 GPIO_InitTypeDef  GPIO_InitStructure; 

 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);

 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;              
 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;        
 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;      
 GPIO_Init(GPIOC, &GPIO_InitStructure);                  
 GPIO_SetBits(GPIOC,GPIO_Pin_10);
}

 int main(void)
 { 
    char *p_password;
    u16 rlen=0;
    u8 i=0;  
    u8 *p;
    u8 send_buf[20];
    delay_init();            //延时函数初始化
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级     
    uart_init(115200);      //串口初始化为9600    
    USART3_Init(115200);  //初始化串口2波特率为115200
    mem_init();             //初始化内存池    
    LOCK_Init();
    EXTIX_Init();
    LED_Init();
    CP2532_Init();
    while(CP2532_Check());
    printf("\r\nsetting esp8266....\r\n");
    while(esp8266_send_cmd("AT","OK",20));//检查WIFI模块是否在线
    printf("\r\nwifi存在\r\n");
    delay_ms(800);
    change: 
    while(esp8266_send_cmd("ATE0","OK",20));//关闭回显
    esp8266_send_cmd("AT+CWMODE=1","OK",50);
    esp8266_send_cmd("AT+RST","OK",20);
    delay_ms(1000);         //延时3S等待重启成功
    delay_ms(1000);
    delay_ms(1000);
    delay_ms(1000);
    printf("\r\nreset success\r\n");
    join:
    p=mymalloc(32);
    sprintf((char*)p,"AT+CWJAP=\"%s\",\"%s\"",wifista_ssid,wifista_password);//设置无线参数:ssid,密码
    while(esp8266_send_cmd(p,"WIFI GOT IP",300)) ; //连接目标路由器,并且获得IP         
    printf("\r\nwifi connect\r\n");
    esp8266_send_cmd("AT+CIPMUX=0","OK",20);   //0:单连接,1:多连接
    sprintf((char*)p,"AT+CIPSTART=\"TCP\",\"SERVER_IP\",SERVER_PORT");    //配置目标TCP服务器 server_ip  服务器IP,server_port 服务器端口
    while(esp8266_send_cmd(p,"CONNECT",200));                                       
    printf("\r\nserver connect\r\n");
    myfree(p);
    LED1=0;
    join_flag=1;
    while(1)
        { 
            if(change_flag)
            {
                change_flag=0;
                goto change;
            }
            if(USART3_RX_STA&0X8000)        //接收到一次数据了
                { 
                    rlen=USART3_RX_STA&0X7FFF;  //得到本次接收到的数据长度
                    USART3_RX_BUF[rlen]=0;      //添加结束符 
                    printf("%s",USART3_RX_BUF); //发送到串口 

                    if((u32)(strstr ( (const char*)USART3_RX_BUF, "####3100000001" ))!=0 )
                    {
                        p_password=strstr ( (const char*)USART3_RX_BUF, "####3100000001" );
                        for(i=0;i<6;i++)
                    {
                        (password[i]) = *(p_password+14+i);
                    }
                        STMFLASH_Write(FLASH_SAVE_ADDR,(u16 *)password,6);
                        printf("\r\n%s\r\n",password);
                    }
                    if((u32)(strstr ( (const char*)USART3_RX_BUF, "####1100000001" ))!=0 )
                    {
                        STMFLASH_Read(FLASH_SAVE_ADDR,(u16 *)data,6);
                        sprintf((char *)send_buf,"####2100000001%s/r/n",(char *)data);
                        esp8266_send_cmd((u8 *)"AT+CIPSEND=20",(u8 *)"OK",200);  //发送指定长度的数据
                        delay_ms(200);
                        esp8266_send_data((u8 *)send_buf,(u8 *)"OK",100);
                    }
                    if((u32)(strstr ( (const char*)USART3_RX_BUF, "CLOSED" ))!=0 )
                    { 
                        join_flag=0;
                        LED1=1;
                        USART3_RX_STA=0;
                        goto join;
                    }
                    USART3_RX_STA=0;
                }
}
        }

工程文件已上传
https://download.csdn/download/qingelife/10130811

本文标签: 密码锁简单wifi