赞
踩
20240410备注:非常抱歉我不能帮助各位解决问题,我已经好多年不看嵌入式的东西了,本文只提供参考,遇见问题还得大家去搜索自己解决。
参考: ----------------------------------------------------------------------------------------- 创建一个 MQTT 协议产品: 版权声明:本文为CSDN博主「Yonas-Luo」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/qq_17351161/article/details/107716689 ------------------------------------------------------------------------------------------ ESP8266固件库烧录(AT固件库与Node固件库): 版权声明:本文为CSDN博主「风铃叶雨」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/jidudong0673/article/details/105222924 ------------------------------------------------------------------------------------------ 将c52单片机的串口设置为115200波特率: 版权声明:本文为CSDN博主「Day____Day____Up」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/weixin_37281289/article/details/80304532 ------------------------------------------------------------------------------------------- STM32单片机ESP8266发送数据到WiFi接收端代码实现: 版权声明:本文为CSDN博主「花开莫与流年错_」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/qq_17242837/article/details/72464956 -------------------------------------------------------------------------------------------- 基于8266WIFI模块实现智能手机与51单片机的通信入门: 版权声明:本文为CSDN博主「IamDaodaoLi」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/IamDaodaoLi/article/details/79715074 ----------------------------------------------------------------------------------------------- ESP8266MOD、刷可以使用AT指令的固件、作为客户端向贝壳云端发送固定数据: 版权声明:本文为CSDN博主「FightingBoom」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/fightingboom/article/details/83315486
本文使用刷入 OneNET 提供的 ESP8266 固件的方法,你甚至不需要了解MQTT协议,既可实现远程控制。使用 STC89C52+ESP8266 来接入云平台。
esp8266 模块型号为:ESP8266-01s,它的Flash 大小为 8M ,这是一个重要的参数,在刷新固件时需要使用到
esp8266有8个引脚分别做一下介绍
引脚 | 功能 |
---|---|
VCC | 3.3V电源 |
GND | 接地 |
RX | 数据接收 |
TX | 数据发送 |
EN | 高电平工作;低电平模块供电关掉 |
RST | 外部Reset信号,低电平复位,高电平工作(默认高)(有的命名为CH_PD) |
IO0 | 工作模式选择:悬空:FlashBoot,工作模式;下拉:UARTDownload,下载模式 |
IO2 | (1)开机上电时必须为高电平,禁止硬件下拉;(2)内部默认已拉高 |
串口模块 | ESP8266模块 |
---|---|
VCC3.3V | VCC(3.3V) 和CH_PD |
TX | RX |
RX | TX |
GND | GND |
注:烧入固件时IO0接GND才能烧写成功 |
MCU | ESP8266模块 |
---|---|
VCC3.3V | VCC(3.3V) 和CH_PD |
TX | RX |
RX | TX |
GND | GND |
注:这样连接MCU和ESP就可以正常通信了 |
烧入的固件使用的是:大佬分享的 https://open.iot.10086.cn/bbs/thread-25723-1-1.html
烧入固件使用的工具是:flash_download_tool
我下载后的百度云链接:链接:https://pan.baidu.com/s/1cU6NJoDb2b3bks-KPYmK1Q
提取码:8023
软件
除了COM(串口和电脑连接的端口号)
其余选择必须和图片一样
注意:esp8266-01sflash大小是8M,FLASH SIZE必须是8Mbit
比特率是115200
最后点击START等待下在完成
需要注意的是
所有AT指令均需加上\r\n作为结束。
所有AT指令回复均已\r\n作为结束.
注:只介绍部分指令的工能不做过多赘述esp8266的反馈信息(想了解更多信息就参考【ESP8266-直连OneNET-内置协议】中的文件【OneNET接入固件-MQTT-AT指令说明文档-v1.1.docx】百度云链接分享中有)
AT指令 | 作用 |
---|---|
AT+IOTSTATUS | 查询与OneNET连接状态 |
AT+CIPSTATUS | 查询WIFI连接状态 |
AT+CWJAP=ssid,password | 手动链接WiFi |
AT+IOTCFG=devid,proid,auth_info | 连接OneNET(devid 为设备DI,proid 为产品ID,auth_info为鉴权信息) |
AT+IOTSEND=a,b,c,(d) | 发送数据流 【a:(0:数据是数值类型)(1:数据是字符串类型)(2:数据是gps)】【b:数据流名】【c:数据值】【d:数据值 (只有上传GPS时才会用到)】 |
AT+IOTSTATUS | 查询OneNET连接状态 |
收到不合法的AT指令 | +Event:ERROR Cmd |
注:最好把自己使用到的指令都试一试,联网和不联网、连接onenet和不连接onenet时esp回馈信息是不一样的,建议自己尝试
**我写的程序只有上传数据,没有onenet控制MCU功能,需要注意没有onenet控制MCU功能,**
使用的STC89C52单片机一般产生的波特率是9600,但是烧入这个固件ESP8266串口通信波特率是115200,为了使MCU和ESP 通信正常使用定时器2产生115200的波特率
main.c
#include "usart.h" #include "esp8266.h" #include "timer0.h" //sbit led1=P2^0; //sbit led2=P2^1; sbit led3=P2^2; void main_delayms(uint xms) { uint i,j; for(i=0;i<xms;i++) for(j=0;j<120;j++); } void main() { uchar temp=20; uchar hum=40; count_m=0;//定时器0计数 count_s=0; time0_flag=0; Rx_len=0; Rx_data_len=0; Timer0_Init(); set52_baudrate(11.0592, 115200);//串口初始化 ESP_Init();//esp8266初始化 // led1=1; // led2=1; led3=1; main_delayms(5000); while(1) { temp ++ ;//做实验使用的所以数据是随机生成的 hum ++ ; if(temp>=30)temp=20; if(hum>=95)hum=40; // led1=1; // led2=0; ESP_Send_Data(temp,hum); } }
usart.c
#include "usart.h" uchar idata RxBuf[70]; uchar idata TxBuf[70]; uchar RIflag; uchar TIflag; uchar Rx_len; uchar Rx_data_len; /*波特率为9600*/ //void UART_init(void) //{ // SCON = 0x50; //串口方式1 // // TMOD = 0x20; // 定时器使用方式2自动重载 // TH1 = 0xFD; //9600波特率对应的预设数,定时器方式2下,TH1=TL1 // TL1 = 0xFD; // // TR1 = 1;//开启定时器,开始产生波特率 //} /**自定义波特率产生函数**/ /* frequency:晶振频率,11.0592 baudrate: 需要的波特率,115200 */ void set52_baudrate(float frequency, long int baudrate) { uint itmp; uchar tlow,thigh; TMOD =0x20; itmp=(int)(65536-(frequency*1000000)/(baudrate*32)); thigh=itmp/256; tlow=itmp%256; SCON=0x5c; T2CON=0x30; RCAP2H=thigh; RCAP2L=tlow; TH2=thigh; TL2=tlow; TR2=1; //set ok //REN=1; ET2=1; //T2中断 EA=1; //总中断 ES=1; //串口中断 PS=1; // } /*发送一个字符*/ void UART_send_byte(uchar dat) { ES=0;//关闭中断,新添加的 SBUF = dat; //把数据放到SBUF中 while (TI == 0);//未发送完毕就等待 TI = 0; //发送完毕后,要把TI重新置0 ES=1;//关闭中断,新添加的 } /*发送一个字符串*/ void UART_send_string(uchar *buf) { while (*buf != '\0') { UART_send_byte(*buf++); } } ///*串口接收一个字节数据*/ //void UART_receive_string( uchar *RxBuffer ) //{ // ES=0; // *RxBuffer = SBUF; // ES=1; //} // /*串口中断*/ void USART_interrupt() interrupt 4 { uchar ss; if(RI==1)//接收中断 { RI=0; ss=SBUF; if(ss!='\n')//esp返回的字符串是以\r\n为结尾的 { RxBuf[Rx_len]=ss; Rx_len++; } else { ES=0;//每次接收完成就将中断关闭 RIflag=1;//一个字符串几首完成才会将此标志位置为1 strcat(RxBuf,"\r\n"); Rx_len=Rx_len+2; Rx_data_len=Rx_len; Rx_len=0; } } if(TI==1)//发送中断 { TI=0; } }
usart.h
#include"reg52.h" #include"stdio.h" #include"stdlib.h" #include"intrins.h" #include <string.h> #ifndef __USART__H #define __USART__H #define uchar unsigned char #define uint unsigned int extern uchar idata RxBuf[70] ; extern uchar idata TxBuf[70] ; extern uchar RIflag; extern uchar TIflag; extern uchar Rx_len; extern uchar Rx_data_len; #define usart_buf_size strlen(RxBuf) //void UART_init();//初始化串口 void set52_baudrate(float frequency, long int baudrate); void UART_send_byte(uchar dat);//发送一个字节数据 void UART_send_string(uchar *buf);//发送一个字符串 //void UART_receive_string( uchar *RxBuffer );//接收字符串, #endif
esp8266.c
#include"reg52.h" #include"esp8266.h" #include "usart.h" #include "timer0.h" uchar idata ESP_Send_Temp[]="AT+IOTSEND=0,Temp,28\r\n"; uchar idata ESP_Send_Hum[]="AT+IOTSEND=0,Hum,54\r\n"; sbit led1=P2^0; sbit led2=P2^1; sbit led5=P2^4;//esp指示灯,会是一闪一闪的,表示esp正常工作呢 void esp_delayms(uint xms) { uint i,j; for(i=0;i<xms;i++) for(j=0;j<120;j++); } uchar Check_ESP_connect_onenet()//和onenet连接时返回1,没有连接时返回0 { ES=1; RIflag=0; memset(RxBuf,0,usart_buf_size); UART_send_string(AT_IOTSTATUS);//查询与OneNET连接状态 esp_delayms(test_time); if(RIflag==1) { RIflag=0; if(RxBuf[1]=='I' && RxBuf[2]=='O' && RxBuf[3]=='T' && RxBuf[12]=='0')//连接着onenet呢 { memset(RxBuf,0,usart_buf_size); Rx_data_len=0; ES=0; return 1; } else { memset(RxBuf,0,usart_buf_size); Rx_data_len=0; ES=0; return 0; } } ES=0; return 0; } void ESP_connect_IOTCFG()//和onenet连接 { ES=1; RIflag=0; memset(RxBuf,0,usart_buf_size); UART_send_string(AT_IOTCFG);//配置登录信息 esp_delayms(test_time); if(RIflag==1) { ES=0; RIflag=0; if(RxBuf[7]=='O' && RxBuf[8]=='n' && RxBuf[9]=='e' && RxBuf[14]=='L')//成功登陆onenet { memset(RxBuf,0,usart_buf_size); Rx_data_len=0; } else//没有连接WiFi时,连接不成功,没有连接成功 { memset(RxBuf,0,usart_buf_size); Rx_data_len=0; } } ES=0;//没有接收到反馈信息 } /*检查esp是否接入WiFi*/ uchar ESP_AP_Check() { led5=1; ES=1;//打开中断, esp_delayms(2); RIflag=0; memset(RxBuf,0,usart_buf_size); UART_send_string(AT_CIPSTATUS);//发送AT指令判断是否连接WiFi esp_delayms(test_time); if(RIflag==1)//接收到esp返回信息,串口接收到数据之后产生中断,在中断中将此标志位置为1 { RIflag=0; // UART_send_string(strcat(RxBuf,"\r\n"));//把接收到的信息返回 if(RxBuf[1]=='S' && RxBuf[2]=='T' && RxBuf[3]=='A' && RxBuf[8]=='5')//WiFi连接状态,是5说明连接WiFi成功 +STATUS:5 { memset(RxBuf,0,usart_buf_size); Rx_data_len=0; ES=0;//关闭中断 if(Check_ESP_connect_onenet()==0)//返回值是0说明没有和onenet连接 { if(time0_flag==1)//定时器时间,3分钟重新连接一次 { time0_flag=0; ESP_connect_IOTCFG();//WiFi连接的时候判断是否和服务器连接着呢 esp_delayms(1000); } return 1; } else//返回值是1说明和onenet连接呢 { return 1; } } else//检测出来和WiFi没有连接 { return 0; } } ES=0; return 0; } void ESP_Init() { uchar f; ES=0; memset(RxBuf,0,usart_buf_size); f = ESP_AP_Check(); ESP_connect_IOTCFG();//先发送一下,就算没有连接上,连接WiFi后也会自动连接onenet } /*MCU向ESP发送温湿度数据*/ void ESP_RX_Data(uchar temp, uchar hum) { ES=1; ESP_Send_Temp[18]='0'+temp/10; ESP_Send_Temp[19]='0'+temp%10; if(ESP_Send_Temp[17]!=',') ESP_Send_Temp[17]=','; UART_send_string(ESP_Send_Temp); esp_delayms(10); memset(TxBuf,0,usart_buf_size); ESP_Send_Hum[17]='0'+hum/10; ESP_Send_Hum[18]='0'+hum%10; if(ESP_Send_Hum[16]!=',') ESP_Send_Hum[16]=','; UART_send_string(ESP_Send_Hum); esp_delayms(5); ES=0; } void ESP_Send_Data(uchar temp, uchar hum) { uchar esp_ap=0; led1=1; led2=0; esp_ap=ESP_AP_Check(); if(esp_ap==1)//WiFi正确连接 { esp_ap=0; ESP_RX_Data(temp,hum); esp_delayms(100); led1=0; led2=1; } }
esp8266.h
#include"reg52.h" #define uchar unsigned char //宏定义一个无符号的char类型 #define uint unsigned int //宏定义一个无符号的int类型 #ifndef __ESP8266__H #define __ESP8266__H #define test_time 1000 /*******AT指令说明*********/ //我只是用到这几个AT命令 #define AT_CIPSTATUS "AT+CIPSTATUS\r\n" //查询WIFI连接状态 #define AT_CIPSTATUS_Event "+STATUS:5\r\n" //接入成功 #define AT_CWJAP "AT+CWJAP=YJ8023,12345678\r\n" //手动接入AP #define AT_CWJAP_Event "+Event:WIFI CONNECTED\r\n" //接入成功 #define AT_IOTCFG "AT+IOTCFG=713051942,422751,0625\r\n" //配置登录信息 #define AT_IOTCFG_Event "+Event:OneNET Link:PROID: 422751,AUIF: 0625,DEVID:713051942\r\n" //成功登陆 #define AT_IOTSTATUS "AT+IOTSTATUS\r\n" //查询与OneNET连接状态 #define AT_IOTSTATUS_Event "+IOT:status:0\r\n" //如还未接入路由就发送指令登录OneNET时 extern uchar idata ESP_Send_Temp[]; extern uchar idata ESP_Send_Hum[]; /****************/ uchar Check_ESP_connect_onenet(); uchar ESP_AP_Check(); void ESP_connect_IOTCFG(); void ESP_Init(); void ESP_RX_Data(uchar temp, uchar hum);//是子函数 void ESP_Send_Data(uchar temp, uchar hum);//在主函数调用 #endif
timer0.c
#include "timer0.h" uchar count_s; uchar count_m; uchar time0_flag; void Timer0_Init(void) { TMOD |= 0x01;//设置定时器为工作方式1 C/T位为1的时候是计数器模式,为0的时候是定时器模式,前四位是定时器1,后四位是定时器0 TL0 = (65536 - 1000)%256; //装初值,低8位 TH0 = (65536 - 1000)/256; //高8位 ET0 = 1; //开定时器的中断 TR0 = 1; //开定时器 EA = 1; //开总中断 } void Timer0(void) interrupt 1 { TL0 = (65536 - 45872)%256; //装初值,低8位//初值是1000即1ms TH0 = (65536 - 45872)/256; //高8位 //50ms中断一次 count_s++; if(count_s == 20)//一秒钟 { count_s = 0; count_m++;//60就是1分钟 if(count_m==60 * 3) { count_m=0; time0_flag=1; } } }
timer0.h
#include"reg52.h" #include"stdio.h" #include"stdlib.h" #include"intrins.h" #define uchar unsigned char //宏定义一个无符号的char类型 #define uint unsigned int //宏定义一个无符号的int类型 #ifndef __TIMER0__H #define __TIMER0__H extern uchar count_s; extern uchar count_m; extern uchar time0_flag; void Timer0_Init(void); #endif
我写的程序不好可以优化地方很多,但是达到了我的预期,我时间紧张就没有做过多修改,分享出来是为了让时间紧凑的人不至于走太多的弯路,谢谢大家观看,有意见请提出来,评论区回复不一定会及时,但是看到会及我所能帮你解决问题。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。