一、概述:
近期写了一篇ESP-01s通过AT指令接入新大陆云平台的小文,这篇续接上次,本篇文章重点介绍运用c51内核的STC8H高性能单片机,使用串口发送AT指令的方式,接入新大陆云平台,模拟两个传感器温度与湿度将模拟的数据上传至云平台,通过云平台下发控制指令实现单片机控制LED1的目的。
二、编程简述:
STC8H系列单片机芯片自带有多串口,感兴趣的读者可以考参串口篇,本次教程是在原多串口的基础上进行,开启串口1用来发送数据至ESP-01s模块,开启串口2用来达到单片机与PC通信,将串口1收到的数据转发到串口2,这样做的好处是PC端能实时监测ESP01s的通信返回状态数据。编程过程中LinkWifi()函数其功能用来初始化,目的是连接上云平台,发送AT指令,通过字符串比对来实现返回信息的确认。EspUpdata(u8 i)用来上报传感器的数据,开启透传后发送的是JSON数据,但注意”符号的转义符/”的使用。EspGetdata()用来接收云平台下发后的数据,当串口缓存接收到数据后,通过比对后确定LED1的状态。
三、实验平台搭建:
1、MCU:STC-打狗棒系列核心实验板 V2.3
2、实验板平台:德飞莱LY-51s
3、ESP-01s模块
4、硬件连接表:
ESP-01s接线表
3V3---------->3.3V
GND---------->GND
TX---------->P36
RX---------->P37
指示灯接线表
LED1---------->P01(执行器LED灯模拟)
LED2---------->P02(通信指示)
四、测试源代码:
#include <STC8H.h>
#include "intrins.h"
#include <stdio.h>
typedef unsigned char u8;
typedef unsigned int u16;
typedef unsigned long u32;
sbit Led1=P0^0;//模拟执行器LED灯
sbit Led2=P0^1;//连接状态指示灯
sbit RST=P2^0; //硬复位引脚
u8 TX1_Cnt; //U1发送计数
u8 RX1_Cnt; //U1接收计数
bit B_TX1_Busy; //U1发送忙标志
u8 xdata RX1_Buffer[256]; //u1接收缓冲
u8 TX2_Cnt; //U2发送计数
u8 RX2_Cnt; //U2接收计数
bit B_TX2_Busy; //U2发送忙标志
u8 xdata RX2_Buffer[128]; //u2接收缓冲
/******************AT指令***********************/
u8 code s1[]="$#AT#\r\n";
u8 code s2[]="AT+RST\r\n";
u8 code s3[]="AT+CIFSR\r\n";
u8 code s4[]="AT+CIPMUX=0\r\n";
u8 code s5[]="AT+CIPSTART=\"TCP\",\"121.37.241.174\",8600\r\n";
u8 code s6[]="AT+CIPMODE=1\r\n";
u8 code s7[]="AT+CIPSEND\r\n";
u8 code s8[]="{\"t\": 1,\"device\": \"x884811\",\"key\":\"08cc97f940fd48d59ddcaa004c41444a\",\"ver\":\"v1.1\"}\r\n";
u8 code s9[]="{\"t\": 3,\"datatype\":1, \"datas\": { \"Temp\": 21.5},\"msgid\": 123}\r\n";
u8 code k1[]="0.0.0.0";
u8 code k2[]="CONNECT";
u8 code k3[]=">";
u8 code k4[]="apitag";
u8 code k5[]="ta\":0,";
u8 code k6[]="ta\":1,";
u8 code k7[]="WIFI GOT IP";
//模拟采集的温度数据
float code temp[]={20.5,21.5,18.5,19.2,16.3,22.6,24.8,25.6,28.3,31.2,25.6,33.2,34.1,36.5,26.6,27.8,29.2,29.8,29.7};
//模拟采集的湿度数据
float code humi[]={80.1,72.6,45.3,36.9,45.8,60.0,68.3,66.2,72.8,80.2,76.6,71.2,78.1,77.5,65.6,68.8,58.2,64.8,66.7};
void Delay1ms(unsigned char x);//当主时钟频率为12M,1ms延时为基准
void init_IO();//初始化IO
void init_Uart1();//串口1初始化
void init_Uart2();//串口2初始化
void Uart1Send(char dat);
void Uart2Send(char dat);
void SendToPCStr(char *puts);//发送数据
void SendToEspStr(char *puts);//发送数据
bit Findkey(u8 key[],u8 len);
void LinkWifi();
void EspUpdata(u8 i);
void EspGetdata();
void main()
{
u8 i=0,num=0;
P_SW2 |= 0x80; //扩展寄存器XFR访问使能
init_IO();
RST=0;//上电时硬件复位模块
Delay1ms(200);
RST=1;//硬件复位模块
init_Uart1();
init_Uart2();
EA=1;
SendToPCStr("STC8H TEST!");
LinkWifi();
while(1)
{
EspGetdata();//接收下发数据
if(num>60)
{
EspUpdata(i++);//传感器数据上载
if(i>=19)i=0;
num=0;
}
else
{
SendToEspStr(s1);//上传心跳包
}
num++;
Delay1ms(200);Delay1ms(200);Delay1ms(200);Delay1ms(200);Delay1ms(200);
Delay1ms(200);Delay1ms(200);Delay1ms(200);Delay1ms(200);Delay1ms(200);
Delay1ms(200);Delay1ms(200);Delay1ms(200);Delay1ms(200);Delay1ms(200);
}
}
//接收到的字符串,从中查找关键字
bit Findkey(u8 key[],u8 len)
{
u8 i=0,j=0;
bit result=0;
for(i=0;i<RX1_Cnt;i++)
{
if(RX1_Buffer[i]==key[0])
{
for(j=1;j<len;j++)
{
if(RX1_Buffer[i+j]!=key[j])
break;
if(j==len-1) result=1;
}
}
}
return result;
}
void LinkWifi() //wifi连接上线
{
RX1_Buffer[RX1_Cnt]='\0';
while(Findkey(k7,10)==0);
SendToEspStr(s3);
Delay1ms(200);Delay1ms(200);Delay1ms(200);Delay1ms(200);
RX1_Buffer[RX1_Cnt]='\0';
while(Findkey(k1,6))
{
SendToEspStr(s3);
Delay1ms(200);Delay1ms(200);Delay1ms(200);Delay1ms(200);
RX1_Buffer[RX1_Cnt]='\0';
}
SendToEspStr(s4);
Delay1ms(200);Delay1ms(200);Delay1ms(200);Delay1ms(200);
SendToEspStr(s5);
RX1_Buffer[RX1_Cnt]='\0';
while(Findkey(k2,6))
{
SendToEspStr(s5);
Delay1ms(200);Delay1ms(200);Delay1ms(200);Delay1ms(200);
RX1_Buffer[RX1_Cnt]='\0';
}
Delay1ms(200);Delay1ms(200);Delay1ms(200);Delay1ms(200);
Delay1ms(200);Delay1ms(200);Delay1ms(200);Delay1ms(200);
SendToEspStr(s6);
Delay1ms(200);Delay1ms(200);Delay1ms(200);Delay1ms(200);
SendToEspStr(s7);
RX1_Buffer[RX1_Cnt]='\0';
while(Findkey(k3,1))
{
SendToEspStr(s7);
Delay1ms(200);Delay1ms(200);Delay1ms(200);Delay1ms(200);
RX1_Buffer[RX1_Cnt]='\0';
}
Delay1ms(200);Delay1ms(200);Delay1ms(200);Delay1ms(200);
Delay1ms(200);Delay1ms(200);Delay1ms(200);Delay1ms(200);
SendToEspStr(s8);
Delay1ms(200);Delay1ms(200);Delay1ms(200);Delay1ms(200);
Delay1ms(200);Delay1ms(200);Delay1ms(200);Delay1ms(200);
Led2=0;
}
void EspUpdata(u8 i) //传感器数据上传
{
u8 xdata TempBuf[80];
sprintf((char *)TempBuf ,"{\"t\": 3,\"datatype\":1, \"datas\": { \"Temp\": %2.1f,\"Humi\": %2.1f},\"msgid\": 123}\r\n",temp[i],humi[i]);//格式化输出
SendToEspStr(TempBuf);
Delay1ms(200);Delay1ms(200);Delay1ms(200);Delay1ms(200);
Delay1ms(200);Delay1ms(200);Delay1ms(200);Delay1ms(200);
}
void EspGetdata()//云平台下发数据接收与执行
{
if(RX1_Cnt>60)
{
RX1_Buffer[RX1_Cnt]='\0';
if(Findkey(k4,5))
{
if(Findkey(k5,6))
Led1=1;
if(Findkey(k6,6))
Led1=0;
}
}
}
/*****以下部分省略为串口通信函数参考STC8H串口通信篇*****/