ESP8266的AP模式与STA编写,

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);//配置中断源 第二个参数选择中断

//11.开启空闲中断

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;

}

相关推荐
晶振厂家-晶发电子2 小时前
怎么判断晶振的好坏,有什么简单的办法
单片机·嵌入式硬件
jllllyuz3 小时前
SysTick定时器的工作原理是什么
stm32·单片机·嵌入式硬件
RIKI_13 小时前
【浅学】tflite-micro + ESP32S3 + VScode + ESP-IDF 基于例程快速实现自己的图像分类模型训练部署全流程
单片机·分类
滴滴滴嘟嘟嘟.4 小时前
STM32 HAL驱动MPU6050传感器
stm32·单片机·嵌入式硬件
食鹿...6 小时前
【记录贴】STM32 I2C 控制 OLED 卡死?根源在 SR1 与 SR2 的读取操作
stm32·单片机·嵌入式硬件
范纹杉想快点毕业7 小时前
《嵌入式 C 语言编码规范与工程实践个人笔记》参考华为C语言规范标准
服务器·c语言·stm32·单片机·华为·fpga开发·51单片机
Chipi Chipi7 小时前
STM32即插即用HAL库驱动系列——4位串行数码管显示
stm32·单片机·嵌入式硬件
Moonnnn.8 小时前
【51单片机学习】定时器、串口、LED点阵屏、DS1302实时时钟、蜂鸣器
笔记·单片机·学习·51单片机
不断提高10 小时前
多种适用于 MCU 固件的 OTA 升级方案
单片机·mcu·ota升级·双分区升级