void Wifi_Init(void)
{
//打开GPIOA时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOE,ENABLE);
GPIO_InitTypeDef GPIO_InitStructure = {0};//定义结构体GPIO外设结构体变量
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; //配置引脚
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //推挽模式
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //浮空输入
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6; //配置引脚
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽模式
GPIO_Init(GPIOE, &GPIO_InitStructure);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3,ENABLE);//打开USART自身时钟
USART_InitTypeDef USART_InitStructure = {0};//定义串口结构体变量
USART_InitStructure.USART_BaudRate = 115200; //波特率
USART_InitStructure.USART_WordLength = USART_WordLength_8b; //数据位:数据长度
USART_InitStructure.USART_StopBits = USART_StopBits_1; //停止位
USART_InitStructure.USART_Parity = USART_Parity_No; //不使用校验
//硬件流控制
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;//全双工:发送和接受
USART_Init(USART3, &USART_InitStructure);
USART_Cmd(USART3,ENABLE);//串口使能
//启动串口接收中断
USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);//配置中断源 第二个参数选择中断
USART_ITConfig(USART3,USART_IT_IDLE,ENABLE);
NVIC_InitTypeDef NVIC_InitStructure = {0};//定义结构体NVIC外设结构体变量
NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
//15.ESP_EN引脚输出高电平 开机
GPIO_SetBits(GPIOE, GPIO_Pin_6);
Delay_nms(2000);
}
//串口发送函数:发送1字节
void Wifi_Tx(uint8_t ch)
{
//等待上一次发送完成
while (USART_GetFlagStatus(USART3, USART_FLAG_TC) == RESET)
{}
USART_SendData(USART3, (uint8_t) ch);//串口发送数据,只可以发送一个字节
}
//发送已知长度字节:针对数组
void Wifi_Tx_Buff(uint8_t buff[],uint16_t len)
{
for(uint16_t i=0;i<len;i++)
Wifi_Tx(buff[i]);
}
//发送未知长度字节:字符串
void Wifi_Tx_str(uint8_t buff[])
{
while(*buff != '\0')
{
Wifi_Tx(*buff++);
}
}
void USART3_IRQHandler(void)
{
uint8_t data = 0;
if(USART_GetITStatus(USART3, USART_IT_RXNE) != RESET)
{
data = USART_ReceiveData(USART3);
USART_SendData(USART1, (uint8_t)data);
wifi.RxBuff[wifi.RxNum++] = data;
wifi.RxNum %= 512;
//清理中断服务函数
USART_ClearITPendingBit(USART3, USART_IT_RXNE);
}
//1.判断中断是否发生--接收中断:每接收到一字节数据就触发一次
if(USART_GetITStatus(USART3, USART_IT_IDLE) != RESET)
{
uint8_t data = 0;
//自己需要写的
wifi.RxOver = 1;
//清理中断服务函数
data = USART3->SR;
data = USART3->DR;
data = data;
}
}
uint8_t SendATAnaJudge(char *cmd,char *ack,uint16_t waittime)
{
uint8_t flag = 0;
//清空缓冲区,方便下一次发送
memset(wifi.RxBuff,0,10);
wifi.RxNum = 0;
wifi.RxOver = 0;
//发送指令
Wifi_Tx_str((uint8_t *)cmd);
//等待指令回复
while(waittime--)
{
//接收完成
if(wifi.RxOver == 1)
{
char *p =strstr((char *)wifi.RxBuff,(char *)ack);
if(p != NULL)
{
flag = 1;
break;
}
}
Delay_nms(1);
}
return flag;
}
uint8_t Wificount = 0;
void UpData(void)
{
uint8_t data = 0;
switch(Wificount)
{
case 0:data = SendATAnaJudge("AT\r\n","OK",1000);
if(data==1)
Wificount++;
break;
case 1:
data = SendATAnaJudge("AT+CWMODE=1\r\n","OK",1000);
if(data==1)
Wificount++;
break;
case 2:
Wifi_Tx_str((uint8_t *)"AT+RST\r\n");
Delay_nms(1000);
Wificount++;
break;
case 3:
{
uint8_t len = 0;
sFLASH_ReadBuffer(&len,WIFIADDR,1);
sFLASH_ReadBuffer(WifiName,WIFIADDR+0x100,len);
sFLASH_ReadBuffer(&len,WIFIADDR+0x200,1);
sFLASH_ReadBuffer(WifiPassword,WIFIADDR+0x300,len);
sprintf((char *)wifi.TxBuff,"AT+CWJAP=\"%s\",\"%s\"\r\n",WifiName,WifiPassword);
data = SendATAnaJudge((char *)wifi.TxBuff,"OK",10000);
if(data==1)
Wificount++;
}
break;
case 4:
data = SendATAnaJudge("AT+CIPSTART=\"TCP\",\"3df8ab406e.st1.iotda-device.cn-north-4.myhuaweicloud.com\",1883\r\n","OK",10000);
if(data==1)
Wificount++;
break;
case 5:
data = SendATAnaJudge("AT+CIPMODE=1\r\n","OK",1000);
if(data==1)
Wificount++;
break;
case 6:
data = SendATAnaJudge("AT+CIPSEND\r\n",">",1000);
if(data==1)
Wificount++;
break;
case 7:
MQTT_Connect();
Wificount++;
break;
case 8:
Delay_nms(1000);
MQTT_Sub(PUBTIME);
Wificount++;
break;
case 9:
Delay_nms(1000);
memset(wifi.RxBuff,0,10);
wifi.RxNum = 0;
wifi.RxOver = 0;
MQTT_PublishTime();
Wificount++;
break;
case 10:
Delay_nms(1000);
MQTTGetTime();
Wificount++;
break;
case 11:
Delay_nms(1000);
MQTT_PublishData();
break;
}
}
//配置AT指令
//+IPD,0,79:{"wifiname":"xwt","password":"123456789","mycity":"","alarm_h":"","alarm_m":""}
uint8_t APcount = 0;
void MQTT_APMode(void)
{
uint8_t data = 0;
switch(APcount)
{
case 0:data = SendATAnaJudge("AT\r\n","OK",1000);
if(data == 1)
APcount++;
break;
case 1:data = SendATAnaJudge("AT+CWMODE=2\r\n","OK",1000);
if(data == 1)
APcount++;
break;
case 2:data = SendATAnaJudge("AT+RST\r\n","OK",1000);
if(data == 1)
APcount++;
break;
case 3:data = SendATAnaJudge("AT+CWSAP=\"AP\",\"12345678\",5,4\r\n","OK",1000);
if(data == 1)
APcount++;
break;
case 4:data = SendATAnaJudge("AT+CIFSR\r\n","OK",1000);
if(data == 1)
APcount++;
break;
case 5://开启多链接
data = SendATAnaJudge("AT+CIPMUX=1\r\n","OK",10000);
if(data==1)
APcount++;
break;
case 6:
memset(wifi.RxBuff,0,512);
wifi.RxNum = 0;
wifi.RxOver = 0;
data = SendATAnaJudge("AT+CIPSERVER=1\r\n","OK",10000);
if(data == 1)
APcount++;
break;
case 7 :
if(Wifi_GetApI())
{
printf("成功\r\n");
APcount++;
}
break;
}
}
#include "MQTTPacket.h"
//mqtt链接工程
void MQTT_Connect(void)
{
//定义Mqtt连接报文结构体
MQTTPacket_connectData data = MQTTPacket_connectData_initializer;
//定义一个发送缓冲区
unsigned char buf[400];
int buflen = sizeof(buf);
data.keepAliveInterval = 60; //保活时间
data.cleansession = 1; //清理会话标志
data.clientID.cstring = CLIENTID; //客户端ID
data.username.cstring = USERNAME; //用户名字
data.password.cstring = PASSWORD; //用户密码
int len = MQTTSerialize_connect(buf, buflen, &data);
Wifi_Tx_Buff(buf,len);
}
//mqtt得发布函数--上行
void MQTT_Publish(char * Topic,char *payload)
{
MQTTString topicString = MQTTString_initializer;
topicString.cstring = Topic;
unsigned char buf[400];
int buflen = sizeof(buf);
int payloadlen = strlen((char *)payload);
int len = MQTTSerialize_publish(buf, buflen, 0, 0, 0, 0, topicString, (unsigned char*)payload, payloadlen);
Wifi_Tx_Buff(buf,len);
}
//发布主题数据
void MQTT_PublishData(void)
{
uint8_t payload[200] = {0};
sprintf((char *)payload,"{\"services\":[\
{\"service_id\":\"parameter\",\"properties\":{\
\"temp\":%s,\
\"hum\":%s\
}}]}",TemBuff,HumBuff);
MQTT_Publish(PUBTOPIC,(char *)payload);
}
//
void MQTT_PublishTime(void)
{
uint8_t payload[400] = {0};
sprintf((char *)payload,"{ \"object_device_id\":\"6892c09cd582f2001842ea3f_air-check\", \
\"services\":[{\
\"service_id\":\"$time_sync\",\
\"event_type\":\"time_sync_request\",\
\"event_time\":\"20151212T121212Z\",\
\"paras\":{\
\"device_send_time\":1582685678789\
}}]}");
MQTT_Publish(PUBTIME,(char *)payload);
}
//订阅函数---接收服务器下行数据
//只需要订阅一次就够了,不需要多次订阅
void MQTT_Sub(char * Topic)
{
//定义发送缓冲区
unsigned char buf[400];
int buflen = sizeof(buf);
//定义订阅主题
MQTTString topicString = MQTTString_initializer;
topicString.cstring = Topic;
//服务质量等级
int req_qos = 0;
int len = MQTTSerialize_subscribe(buf, buflen, 0, 1, 1, &topicString, &req_qos);
if(len < 0)
{
printf("创建失败");
}
Wifi_Tx_Buff(buf,len);
}
#include <stdlib.h>
#include <time.h>
#include "RGC.h"
//struct tm *rtc;
void MQTTGetTime(void)
{
uint8_t TimeBuff[10] = {0};
char *p = strstr((char *)&wifi.RxBuff[10],"server_send_time");
p += 18;
for(u8 i=0;i<10;i++)
{
TimeBuff[i] = *p++;
}
long tim = atol((char *)TimeBuff);
RtcUpData(tim);
}
/*
1.接收用户发送的wifi信息 并解析保存
2.当用于链接上AP模式设置的网络时,此时回返回链接设备所分配IP地址
3.当用户利用AP模式对ESP8266修改密码时,可以通过设备与ESP8266进行通信,同时通过串口
中断服务函数,把收集到的数据保存再我们自己定义的接收缓冲区,再从接收缓冲区里面读取出来
上传到FLash存储IC中,以满足代码在此从新运行时保证客户端需要修改的wifi信息不会丢失。
+IPD,0,79:{"wifiname":"xwt","password":"123456789","mycity":"","alarm_h":"","alarm_m":""}
0,CLOSED
*/
uint8_t Wifi_GetApI(void)
{
uint8_t data = 0;
if(wifi.RxOver == 1)
{
char *p = strstr((char *)wifi.RxBuff,"+IPD");
if(p != NULL)
{
char * name = strstr((char *)wifi.RxBuff,"wifiname");
if(name != NULL)
{
name += 11;
uint8_t i = 0;
while(*name != '"')
{
WifiName[i] = *name;
i++;
name++;
}
WifiName[i] = '\0';
}
char * PassWord = strstr((char *)wifi.RxBuff,"password");
if(PassWord != NULL)
{
PassWord += 11;
uint8_t i = 0;
while(*PassWord != '"')
{
WifiPassword[i] = *PassWord;
i++;
PassWord++;
}
WifiPassword[i] = '\0';
}
printf("name:%s\r\n",WifiName);
printf("word:%s\r\n",WifiPassword);
data = 1;
//保存到flash中
sFLASH_EraseSector(WIFIADDR);
uint8_t len = strlen((char *)WifiName);
sFLASH_WriteBuffer(&len,WIFIADDR,1);
sFLASH_WriteBuffer(WifiName,WIFIADDR+0x100,len);
len = strlen((char *)WifiPassword);
sFLASH_WriteBuffer(&len,WIFIADDR+0x200,1);
sFLASH_WriteBuffer(WifiPassword,WIFIADDR+0x300,len);
}
else
{
memset(wifi.RxBuff,0,512);
wifi.RxNum=0;
wifi.RxOver=0;
}
}
return data;
}