1、使用硬件
我这里使用的是正点原子家的STM32开发板(精英版)和ESP8266模块。刚开始准备做一个LORA网关的,但是后面因为比赛的原因就没有搞了,就搞了LORA的通信和WIFI上云(巴法云物联网)的代码:
- 正点原子家的STM32开发板(精英版)

- ESP8266模块
程序思路(基于正点原子的测试程序)
第一步:stm32单片机配置两个串口,(USART1和USART3), USART1主要用来单片机向电脑的串口发送数据,方便我们调试。USART3主要用来连接WIFi模块,和它通信。
第二步:通过USART3串口配置ESP8266模块。
第三步:接收云平台的信息和发送心跳包
单片机订阅云平台的主题:
cmd=1&uid=005dd80adf61d7df35bb4e2cbbf1bf9f&topic=chishi
单片机把消息推送到云平台:
cmd=2&uid=005dd80adf61d7df35bb4e2cbbf1bf9f&topic=chishi&msg=RELAY1_OPEN
单片机的心跳包(60s之内必须发一次,否则单片机会掉线):
cmd=0&msg=ping
在巴法云物联网创建的主题

ESP8266初始化代码(比较简陋)
#include "esp8266.h"
#include "common.h"
#include "stdlib.h"
#include "led.h"
u8 atk_8266_apsta_test(void)
{
atk_8266_send_cmd("AT","OK",50);
atk_8266_send_cmd("AT+CWMODE=3","OK",50);
atk_8266_send_cmd("AT+CWJAP="zhouyong","23456789"","WIFI GOT IP",1000);
delay_ms(1000);//这里的延时是等待模块重启,具体延时多久是看模块的重启时间
delay_ms(1000);
delay_ms(1000);
delay_ms(1000);
delay_ms(1000);
delay_ms(1000);
atk_8266_send_cmd("AT+CIPMODE=1","OK",200);
atk_8266_send_cmd("AT+CIPSTART="TCP","bemfa.com",8340","OK",200);
atk_8266_send_cmd("AT+CIPSEND","OK",200);
atk_8266_send_cmd("cmd=1&uid=005dd80adf61d7df35bb4e2cbbf1bf9f&topic=chishi","cmd=1&res=1",200);
atk_8266_send_cmd("cmd=0&msg=ping","cmd=0&res=1",200);
//atk_8266_send_cmd函数的第一个参数是要发送的消息
//第二个参数是返回的消息
//第三个参数是等待的时间
}
atk_8266_send_cmd函数的代码
//向ATK-ESP8266发送命令
//cmd:发送的命令字符串
//ack:期待的应答结果,如果为空,则表示不需要等待应答
//waittime:等待时间(单位:10ms)
//返回值:0,发送成功(得到了期待的应答结果)
// 1,发送失败
u8 atk_8266_send_cmd(u8 *cmd,u8 *ack,u16 time)
{
u8 res=0;
USART3_RX_STA=0;
u3_printf("%srn",cmd); //发送命令
if(ack&&time) //需要等待应答
{
while(--time) //等待倒计时
{
delay_ms(10);
if(USART3_RX_STA&0X8000)//接收到期待的应答结果
{
if(atk_8266_check_cmd(ack))
{
printf("ack:%srn",(u8*)ack);
break;//得到有效数据
}
USART3_RX_STA=0;
}
}
if(waittime==0)res=1;
}
return res;
}
主函数代码
#include "stm32f10x.h"
#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "esp8266.h"
#include "key.h"
#include "string.h"
#include "usart3.h"
#include "common.h"
int main(void)
{
u16 rlen=0;//保存接收到的数据长度
char data_tiqu[100];//将接收到的数据保存到该数组
char data[10];//最终提取的数据
int k=0,s=0;//保存cmd2开头的数据的下标
int i=0,j=0;
char cmd[]="msg";
int flag=1;//收到正确数据标志位,默认为1,
u8 timex=0;//每200发送1次心跳包的标志位
delay_init(); //延时函数初始化
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置中断优先级分组为组2:2位抢占优先级,2位响应优先级
uart_init(115200); //串口初始化为115200
usart3_init(115200);
LED_Init();
relay_Init();//继电器端口初始化
KEY_Init();
atk_8266_apsta_test();//esp8266初始化
atk_8266_send_cmd("cmd=0&msg=ping","cmd=0&res=1",200);
while(1)
{
timex++;
//atk_8266_send_cmd("cmd=0&msg=ping",NULL,200);//心跳包
//u3_printf("%srn","cmd=2&uid=005dd80adf61d7df35bb4e2cbbf1bf9f&topic=chishi&msg=RELAY1_OPEN");//推送消息到云平台
//atk_8266_at_response(1);
if(USART3_RX_STA&0X8000) //接收到一次数据了
{
//USART3_RX_BUF[USART3_RX_STA&0X7FFF]=0;
rlen=USART3_RX_STA&0X7FFF; //得到本次接收到的数据长度
USART3_RX_BUF[rlen]=0; //添加结束符
printf("%s",USART3_RX_BUF); //发送到串口
数据提取
if(strncmp(USART3_RX_BUF,"cmd=2",5)==0)
{
for(i=0;i
{
data_tiqu
=USART3_RX_BUF;
s++;
}
printf("%s",data_tiqu);
for(i=0;i
{
if(data_tiqu==cmd[0])
{
k=i;
k++;
for(j=1;j
{
if(data_tiqu[k]==cmd[j])
{
k++;
flag=1;
}
else
{
flag=0;
}
}
}
}
s=0;
数据提取结束
if(flag==1)
{
for(i=k+1;i
{
data=data_tiqu;
s++;
}
printf("%s",data);
if(data[0]=='R'&&data[1]=='1')
{
GPIO_ResetBits(GPIOE,GPIO_Pin_1);//开继电器1
}
if(data[0]=='R'&&data[1]=='0')
{
GPIO_SetBits(GPIOE,GPIO_Pin_1);//关继电器1
}
if(data[2]=='R'&&data[3]=='1')
{
GPIO_ResetBits(GPIOE,GPIO_Pin_2);//开继电器2
}
if(data[2]=='R'&&data[3]=='0')
{
GPIO_SetBits(GPIOE,GPIO_Pin_2);//关继电器2
}
if(data[4]=='R'&&data[5]=='1')
{
GPIO_ResetBits(GPIOE,GPIO_Pin_3);//开继电器3
}
if(data[4]=='R'&&data[5]=='0')
{
GPIO_SetBits(GPIOE,GPIO_Pin_3);//关继电器1
}
if(data[6]=='R'&&data[7]=='1')
{
GPIO_ResetBits(GPIOE,GPIO_Pin_4);//开继电器4
}
if(data[6]=='R'&&data[7]=='0')
{
GPIO_SetBits(GPIOE,GPIO_Pin_4);//关继电器4
}
}
}
if(strncmp(USART3_RX_BUF,"cmd=0&res=1",11)==0)
{
printf("%s",USART3_RX_BUF);
}
USART3_RX_STA=0;
}
if((timex%200)==0)
{
u3_printf("cmd=0&msg=ping");//心跳包
timex=0;
}
}
}
如果想用串口助手调试,接线方法如下:
[tr]串口助手esp8266[/tr]
1、使用硬件
我这里使用的是正点原子家的STM32开发板(精英版)和ESP8266模块。刚开始准备做一个LORA网关的,但是后面因为比赛的原因就没有搞了,就搞了LORA的通信和WIFI上云(巴法云物联网)的代码:
- 正点原子家的STM32开发板(精英版)

- ESP8266模块
程序思路(基于正点原子的测试程序)
第一步:stm32单片机配置两个串口,(USART1和USART3), USART1主要用来单片机向电脑的串口发送数据,方便我们调试。USART3主要用来连接WIFi模块,和它通信。
第二步:通过USART3串口配置ESP8266模块。
第三步:接收云平台的信息和发送心跳包
单片机订阅云平台的主题:
cmd=1&uid=005dd80adf61d7df35bb4e2cbbf1bf9f&topic=chishi
单片机把消息推送到云平台:
cmd=2&uid=005dd80adf61d7df35bb4e2cbbf1bf9f&topic=chishi&msg=RELAY1_OPEN
单片机的心跳包(60s之内必须发一次,否则单片机会掉线):
cmd=0&msg=ping
在巴法云物联网创建的主题

ESP8266初始化代码(比较简陋)
#include "esp8266.h"
#include "common.h"
#include "stdlib.h"
#include "led.h"
u8 atk_8266_apsta_test(void)
{
atk_8266_send_cmd("AT","OK",50);
atk_8266_send_cmd("AT+CWMODE=3","OK",50);
atk_8266_send_cmd("AT+CWJAP="zhouyong","23456789"","WIFI GOT IP",1000);
delay_ms(1000);//这里的延时是等待模块重启,具体延时多久是看模块的重启时间
delay_ms(1000);
delay_ms(1000);
delay_ms(1000);
delay_ms(1000);
delay_ms(1000);
atk_8266_send_cmd("AT+CIPMODE=1","OK",200);
atk_8266_send_cmd("AT+CIPSTART="TCP","bemfa.com",8340","OK",200);
atk_8266_send_cmd("AT+CIPSEND","OK",200);
atk_8266_send_cmd("cmd=1&uid=005dd80adf61d7df35bb4e2cbbf1bf9f&topic=chishi","cmd=1&res=1",200);
atk_8266_send_cmd("cmd=0&msg=ping","cmd=0&res=1",200);
//atk_8266_send_cmd函数的第一个参数是要发送的消息
//第二个参数是返回的消息
//第三个参数是等待的时间
}
atk_8266_send_cmd函数的代码
//向ATK-ESP8266发送命令
//cmd:发送的命令字符串
//ack:期待的应答结果,如果为空,则表示不需要等待应答
//waittime:等待时间(单位:10ms)
//返回值:0,发送成功(得到了期待的应答结果)
// 1,发送失败
u8 atk_8266_send_cmd(u8 *cmd,u8 *ack,u16 time)
{
u8 res=0;
USART3_RX_STA=0;
u3_printf("%srn",cmd); //发送命令
if(ack&&time) //需要等待应答
{
while(--time) //等待倒计时
{
delay_ms(10);
if(USART3_RX_STA&0X8000)//接收到期待的应答结果
{
if(atk_8266_check_cmd(ack))
{
printf("ack:%srn",(u8*)ack);
break;//得到有效数据
}
USART3_RX_STA=0;
}
}
if(waittime==0)res=1;
}
return res;
}
主函数代码
#include "stm32f10x.h"
#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "esp8266.h"
#include "key.h"
#include "string.h"
#include "usart3.h"
#include "common.h"
int main(void)
{
u16 rlen=0;//保存接收到的数据长度
char data_tiqu[100];//将接收到的数据保存到该数组
char data[10];//最终提取的数据
int k=0,s=0;//保存cmd2开头的数据的下标
int i=0,j=0;
char cmd[]="msg";
int flag=1;//收到正确数据标志位,默认为1,
u8 timex=0;//每200发送1次心跳包的标志位
delay_init(); //延时函数初始化
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置中断优先级分组为组2:2位抢占优先级,2位响应优先级
uart_init(115200); //串口初始化为115200
usart3_init(115200);
LED_Init();
relay_Init();//继电器端口初始化
KEY_Init();
atk_8266_apsta_test();//esp8266初始化
atk_8266_send_cmd("cmd=0&msg=ping","cmd=0&res=1",200);
while(1)
{
timex++;
//atk_8266_send_cmd("cmd=0&msg=ping",NULL,200);//心跳包
//u3_printf("%srn","cmd=2&uid=005dd80adf61d7df35bb4e2cbbf1bf9f&topic=chishi&msg=RELAY1_OPEN");//推送消息到云平台
//atk_8266_at_response(1);
if(USART3_RX_STA&0X8000) //接收到一次数据了
{
//USART3_RX_BUF[USART3_RX_STA&0X7FFF]=0;
rlen=USART3_RX_STA&0X7FFF; //得到本次接收到的数据长度
USART3_RX_BUF[rlen]=0; //添加结束符
printf("%s",USART3_RX_BUF); //发送到串口
数据提取
if(strncmp(USART3_RX_BUF,"cmd=2",5)==0)
{
for(i=0;i
{
data_tiqu
=USART3_RX_BUF;
s++;
}
printf("%s",data_tiqu);
for(i=0;i
{
if(data_tiqu==cmd[0])
{
k=i;
k++;
for(j=1;j
{
if(data_tiqu[k]==cmd[j])
{
k++;
flag=1;
}
else
{
flag=0;
}
}
}
}
s=0;
数据提取结束
if(flag==1)
{
for(i=k+1;i
{
data=data_tiqu;
s++;
}
printf("%s",data);
if(data[0]=='R'&&data[1]=='1')
{
GPIO_ResetBits(GPIOE,GPIO_Pin_1);//开继电器1
}
if(data[0]=='R'&&data[1]=='0')
{
GPIO_SetBits(GPIOE,GPIO_Pin_1);//关继电器1
}
if(data[2]=='R'&&data[3]=='1')
{
GPIO_ResetBits(GPIOE,GPIO_Pin_2);//开继电器2
}
if(data[2]=='R'&&data[3]=='0')
{
GPIO_SetBits(GPIOE,GPIO_Pin_2);//关继电器2
}
if(data[4]=='R'&&data[5]=='1')
{
GPIO_ResetBits(GPIOE,GPIO_Pin_3);//开继电器3
}
if(data[4]=='R'&&data[5]=='0')
{
GPIO_SetBits(GPIOE,GPIO_Pin_3);//关继电器1
}
if(data[6]=='R'&&data[7]=='1')
{
GPIO_ResetBits(GPIOE,GPIO_Pin_4);//开继电器4
}
if(data[6]=='R'&&data[7]=='0')
{
GPIO_SetBits(GPIOE,GPIO_Pin_4);//关继电器4
}
}
}
if(strncmp(USART3_RX_BUF,"cmd=0&res=1",11)==0)
{
printf("%s",USART3_RX_BUF);
}
USART3_RX_STA=0;
}
if((timex%200)==0)
{
u3_printf("cmd=0&msg=ping");//心跳包
timex=0;
}
}
}
如果想用串口助手调试,接线方法如下:
[tr]串口助手esp8266[/tr]
举报