文章内容仅个人的理解,如有错误还请各位多多包涵
参考:b站:海创电子工作室,漫天飞羽zz
硬件
单片机:stm32f103c8t6、esp8266模块
一、首先,让esp8266作为客户端,连接上WiFi。
(这里使用手机开热点,注意热点设置AP频段选择2.4Ghz,否则连接不上)
1.1先用串口调试助手(xcom)进行调试
硬件连接
在串口调试助手输入相关AT指令,发送时记得勾选 换新行
除了第二步返回的是redy,其他成功都是返回ok的。这样就完成了
1.2通过单片机发送指令给esp8266,连接上WiFi
首先要明白,回车换行,相当于串口调试助手勾选新行
想相关代码(后续会附上所有代码)
要知道 \ 转义符的使用,print(“ ”)括号里只能有一个引号,如果要有多个引号要在引号前加转义符 \,例如print(“ \" \" ”)这样就不会出错
void WIFI_config()
{
printf ("AT\r\n");//会去执行接收中断,执行完之后才会继续下一个代码
end_wait(3);
u2_printf ("1 End wait\r\n");
printf ("AT+CWMODE=1\r\n");//配置WiFi模式
end_wait(3);
u2_printf ("2 End wait\r\n");
printf ("AT+RST\r\n");//重启
end_wait(3);
u2_printf ("3 End wait\r\n");
printf("AT+CWJAP=\"%s\",\"%s\"\r\n","aaaa","123456789");//连接WiFi
end_wait(3);
u2_printf ("5 End wait\r\n");
}
二、esp8266连接阿里云
2.1先串口调试发送AT指令连接
自己在阿里云创建产品,设备,设备点击查看就知道用户名和密码了
相关AT指令
2.2通过单片机发送指令连接阿里云
相关代码
void WIFI_connect_aliyun(void)
{
printf("AT+CIPSNTPCFG=1,8,\"%s\"\r\n", "ntpl.aliyun.com");
end_wait(3);
u2_printf ("4 End wait\r\n");
printf("AT+MQTTUSERCFG=0,1,\"%s\",\"%s\",\"%s\",0,0,\"%s\"\r\n","NULL","esp88266&k14s6MVFIVB","d8fb3900cdb6cd8415042b418ff2171626448bd45e4626465ebbd0b76fce0bc3","");
end_wait(3);
u2_printf ("6 End wait\r\n");
printf("AT+MQTTCLIENTID=0,\"%s\"\r\n", "k14s6MVFIVB.esp88266|securemode=2\\,signmethod=hmacsha256\\,timestamp=1713436406272|");
end_wait(3);
u2_printf ("7 End wait\r\n");
printf("AT+MQTTCONN=0,\"%s\",1883,1\r\n","iot-06z00bu1jeo8uwc.mqtt.iothub.aliyuncs.com");
end_wait(3);
u2_printf ("8 End wait\r\n");
printf("AT+MQTTSUB=0,\"%s\",1\r\n","/k14s6MVFIVB/esp88266/user/get");
end_wait(3);
u2_printf ("9 End wait\r\n");
}
三、单片机成功连接上阿里云后
3.1发送数据给阿里云
void send_mcu_aliyun(char *wifi_data)
{
printf("AT+MQTTPUB=0,\"/k14s6MVFIVB/esp88266/user/update\",\"%s\",1,0\r\n", wifi_data);
end_wait(3);
u2_printf ("10 End wait\r\n");
}
3.2接收云端传来的数据,通过回车换行,能够判断数据是否传输完整
/* 参考整点原子
云端返回数据的格式: asdfgdghjh...(0x0d)(ox0a)结尾
*/
u8 USART_RX_BUF[USART_REC_LEN];
u16 USART_RX_STA=0;
void judge_receive_end()
{
u8 Res;
if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) //接收中断(接收到的数据必须是0x0d 0x0a结尾)
{
Res =USART_ReceiveData(USART1); //读取接收到的数据
if((USART_RX_STA&0x8000)==0)//接收未完成
{
if(USART_RX_STA&0x4000)//接收到了0x0d
{
if(Res!=0x0a)USART_RX_STA=0;//接收错误,重新开始
else USART_RX_STA|=0x8000; //接收完成了
}
else //还没收到0X0D
{
if(Res==0x0d)USART_RX_STA|=0x4000;
else
{
USART_RX_BUF[USART_RX_STA&0X3FFF]=Res ;
USART_RX_STA++;
if(USART_RX_STA>(USART_REC_LEN-1))USART_RX_STA=0;//接收数据错误,重新开始接收
}
}
}
}
}
四、使用
1.显示接收从云端接收到的数据
for(t=0;t<len;t++)
{
USART_SendData(USART2,USART_RX_BUF[t]);
while (USART_GetFlagStatus(USART2,USART_FLAG_TXE)==RESET);//等待发送结束
}
2.判断云端数据
if(USART_RX_STA&0x8000)
{
len=USART_RX_STA&0x3fff;//得到此次接收到的数据长度
if(strstr((const char*)USART_RX_BUF,"on"))
{
u2_printf("ture");
}
3.使用接收函数记得将
USART_RX_STA=0;标志为清零
memset (USART_RX_BUF,0,USART_REC_LEN);上次所得数据清零
五、esp8266.h和esp8266.c,usart.h在另一个文章
#ifndef _WIFI_H
#define _WIFI_H
#include "stm32f10x.h"
#include "delay.h"
#include "usart.h"
#include "string.h"
#define USART_REC_LEN 200 //定义最大接收字节数 200
extern u8 USART_RX_BUF[USART_REC_LEN]; //接收缓冲,最大USART_REC_LEN个字节.末字节为换行符
extern u16 USART_RX_STA; //接收状态标记
void WIFI_config(void);//esp8266连上wifi
void WIFI_connect_aliyun(void);//连接上aliyun
void send_mcu_aliyun(char *wifi_data);//发送数据到云端
void send_dht11_to_aliyun(int t,int h);//发送温湿度数据给阿里云
void end_wait(int t);//等待串口发送后esp8266再返回数据
void judge_receive_end(void);//将云端发来的字符串存在USART_RX_BUF里
#endif
.c
#include "wifi.h" // Device header
void WIFI_config()
{
printf ("AT\r\n");//会去执行接收中断,执行完之后才会继续下一个代码
end_wait(3);
u2_printf ("1 End wait\r\n");
printf ("AT+CWMODE=1\r\n");//配置WiFi模式
end_wait(3);
u2_printf ("2 End wait\r\n");
printf ("AT+RST\r\n");//重启
end_wait(3);
u2_printf ("3 End wait\r\n");
printf("AT+CWJAP=\"%s\",\"%s\"\r\n","aaaa","123456789");//连接WiFi
end_wait(3);
u2_printf ("5 End wait\r\n");
}
void WIFI_connect_aliyun(void)
{
printf("AT+CIPSNTPCFG=1,8,\"%s\"\r\n", "ntpl.aliyun.com");
end_wait(3);
u2_printf ("4 End wait\r\n");
printf("AT+MQTTUSERCFG=0,1,\"%s\",\"%s\",\"%s\",0,0,\"%s\"\r\n","NULL","esp88266&k14s6MVFIVB","d8fb3900cdb6cd8415042b418ff2171626448bd45e4626465ebbd0b76fce0bc3","");
end_wait(3);
u2_printf ("6 End wait\r\n");
printf("AT+MQTTCLIENTID=0,\"%s\"\r\n", "k14s6MVFIVB.esp88266|securemode=2\\,signmethod=hmacsha256\\,timestamp=1713436406272|");
end_wait(3);
u2_printf ("7 End wait\r\n");
printf("AT+MQTTCONN=0,\"%s\",1883,1\r\n","iot-06z00bu1jeo8uwc.mqtt.iothub.aliyuncs.com");
end_wait(3);
u2_printf ("8 End wait\r\n");
printf("AT+MQTTSUB=0,\"%s\",1\r\n","/k14s6MVFIVB/esp88266/user/get");
end_wait(3);
u2_printf ("9 End wait\r\n");
}
void send_mcu_aliyun(char *wifi_data)
{
printf("AT+MQTTPUB=0,\"/k14s6MVFIVB/esp88266/user/update\",\"%s\",1,0\r\n", wifi_data);
end_wait(3);
u2_printf ("10 End wait\r\n");
}
void send_dht11_to_aliyun(int t,int h)
{
printf("AT+MQTTPUB=0,\"/k14s6MVFIVB/esp88266/user/update\",\"{\\\"temperature\\\": %d\\\,\\\"humidity\\\": %d}\",1,0\r\n",t,h);
end_wait(3);
u2_printf ("11 End wait\r\n");
}
void end_wait(int t)
{
int ti=0;
while(!((USART_GetITStatus(USART1, USART_IT_RXNE) == RESET)&&(ti>t)))//不接收消息3秒后再继续,
{
delay_ms(1000);
ti++;
}
}
/* 参考整点原子
云端返回数据的格式: asdfgdghjh...(0x0d)(ox0a)结尾
*/
u8 USART_RX_BUF[USART_REC_LEN];
u16 USART_RX_STA=0;
void judge_receive_end()
{
u8 Res;
if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) //接收中断(接收到的数据必须是0x0d 0x0a结尾)
{
Res =USART_ReceiveData(USART1); //读取接收到的数据
if((USART_RX_STA&0x8000)==0)//接收未完成
{
if(USART_RX_STA&0x4000)//接收到了0x0d
{
if(Res!=0x0a)USART_RX_STA=0;//接收错误,重新开始
else USART_RX_STA|=0x8000; //接收完成了
}
else //还没收到0X0D
{
if(Res==0x0d)USART_RX_STA|=0x4000;
else
{
USART_RX_BUF[USART_RX_STA&0X3FFF]=Res ;
USART_RX_STA++;
if(USART_RX_STA>(USART_REC_LEN-1))USART_RX_STA=0;//接收数据错误,重新开始接收
}
}
}
}
}