因为之前学习stm32+esp8266请求心知天气时看的不是很懂,然后在成功调试出来之后发一篇面向刚入门的学者,当然我也属于是刚入门级别的。
我这里使用的是ESP8266-01S,首先得烧录固件库,这些买的时候商家也会提供,所以不多做解释。
首先配置好ESP8266所用的指令
AT+CWMODE=1
AT+RST
AT+CWJAP=“232”,"123456789\” 这里的232是你的热点名称 后面数字代表密码
AT+CIPMUX=0 单连接模式
AT+CIPSTART=“TCP”,“116.62.81.138”,80 TCP为连接协议,后面为服务器IP,80表示端口
AT+CIPMODE=1 设置为透传模式
AT+CIPSEND 这个是用来发送数据前的AT指令,当使用完这个指令返回">"这个符号之后 esp8266就会禁止以后的AT指令发送
最后就是直接GET请求 以心知天气API为例:GET https://api.seniverse.com/v3/weather/now.json?key=你的私钥&location=zhaoqing&language=zh-Hans&unit=c
还有一点就是当发送了GET请求之后平台返回的数据是直接进入与esp8266相连的单片机的中断,不需要另外写接收代码
最后可以使用调试助手查阅是否获取到了数据,我这里用的是安信可:https://docs.ai-thinker.com/_media/tools/aithinker_serial_tool_v1.2.3.7z 直接点击链接既可下载
我使用的是STM32F103C8T6,这个库可以直接复制粘贴使用
我这是从OneNet平台上下载的一个8266库然后修改了一点东西,需要的可以直接去下载一份
#include "stm32f10x.h"
#include <esp8266.h>
#include "delay.h"
#include "usart.h"
#include <string.h>
#include <stdio.h>
#define ESP8266_WIFI_INFO "AT+CWJAP=\"232\",\"123456789\"\r\n"
#define ESP8266_ONENET_INFO "AT+CIPSTART=\"TCP\",\"116.62.81.138\",80\r\n"
unsigned char espbuf_Goal[300];//全局变量
unsigned char esp8266_buf[300];
unsigned short esp8266_cnt = 0, esp8266_cntPre = 0;
void ESP8266_Clear(void)//清除8266接收数据的包缓存
{
memset(esp8266_buf, 0, sizeof(esp8266_buf));
esp8266_cnt = 0;
}
_Bool ESP8266_WaitRecive(void)//这个不需要用到,可以不用管,复制就完了
{
if(esp8266_cnt == 0)
return REV_WAIT;
if(esp8266_cnt == esp8266_cntPre)
{
esp8266_cnt = 0;
return REV_OK;
}
esp8266_cntPre = esp8266_cnt;
return REV_WAIT;
}
_Bool ESP8266_SendCmd(char *cmd, char *res)//发送AT指令用的函数,复制就完了
{
unsigned char timeOut = 200;
Usart_SendString(USART1, (unsigned char *)cmd, strlen((const char *)cmd));
while(timeOut--)
{
if(ESP8266_WaitRecive() == REV_OK) //如果收到数据
{
if(strstr((const char *)esp8266_buf, res) != NULL) //如果检索到关键词
{
ESP8266_Clear(); //清空缓存
return 0;
}
}
delay_ms(10);
}
return 1;
}
//放延时可以给中断接收预留时间 该函数是返回GET请求获取的包数据
unsigned char *ESP8266_GetIPD(unsigned short timeOut)//这里我用了一个全局变量将esp8266buf储存到这个全局变量里面
{
do
{
delay_ms(5);
} while(timeOut--);
strcpy((char*)espbuf_Goal,(char*)esp8266_buf);
return espbuf_Goal;
}
//这个没什么好说的,就是初始化ESP8266的,要注意的是ESP8266的复位引脚要与PC14连接,否则复位指令失效
//直接复制就完了
void ESP8266_Init(void)
{
GPIO_InitTypeDef GPIO_Initure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
//ESP8266复位引脚
GPIO_Initure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Initure.GPIO_Pin = GPIO_Pin_14; //GPIOC14-复位
GPIO_Initure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOC, &GPIO_Initure);
GPIO_WriteBit(GPIOC, GPIO_Pin_14, Bit_RESET);
delay_ms(250);
GPIO_WriteBit(GPIOC, GPIO_Pin_14, Bit_SET);
delay_ms(500);
ESP8266_Clear();
while(ESP8266_SendCmd("AT\r\n", "OK"))
delay_ms(500);
while(ESP8266_SendCmd("AT+CWMODE=1\r\n", "OK"))
delay_ms(500);
while(ESP8266_SendCmd("AT+RST\r\n", "OK"))
delay_ms(500);
while(ESP8266_SendCmd(ESP8266_WIFI_INFO, "GOT IP"))
delay_ms(500);
while(ESP8266_SendCmd("AT+CIPMUX=0\r\n", "OK"))
delay_ms(500);
while(ESP8266_SendCmd(ESP8266_ONENET_INFO, "CONNECT"))
delay_ms(500);
while(ESP8266_SendCmd("AT+CIPMODE=1\r\n", "OK"))
delay_ms(500);
while(ESP8266_SendCmd("AT+CIPSEND\r\n", ">"))
delay_ms(500);
UsartPrintf(USART2, "6. ESP8266 Init OK\r\n");//用来打印是否已经完成了配置
}
//我把USART1的中断往这个头文件写了,需要改的可以改一下
//里面的代码直接复制就完了
void USART1_IRQHandler(void)
{
if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) //接收中断
{
if(esp8266_cnt >= sizeof(esp8266_buf)) esp8266_cnt = 0; //防止串口被刷爆
esp8266_buf[esp8266_cnt++] = USART1->DR;//读取接收到的数据
USART_ClearFlag(USART1, USART_FLAG_RXNE);
}
}
头文件
#ifndef _ESP8266_H_
#define _ESP8266_H_
#define REV_OK 0 //接收完成标志
#define REV_WAIT 1 //接收未完成标志
unsigned char espbuf_Goal[300];
void ESP8266_Init(void);
void ESP8266_Clear(void);
void ESP8266_SendData(unsigned char *data, unsigned short len);
unsigned char *ESP8266_GetIPD(unsigned short timeOut);
#endif
main.c的代码
#include "stm32f10x.h"
#include "usart.h"
#include "string.h"
#include "delay.h"
#include "time.h"
#include "esp8266.h"
#include <stdio.h>
int main(void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC|RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOD| RCC_APB2Periph_AFIO,ENABLE);//串口时钟
delay_init();
Usart1_Init(115200);//物联网通信
Usart2_Init(115200);//打印串口信息
ESP8266_Init();//初始化物联网指令
ESP8266_Clear();//清除esp8266buf的缓存数据
char sss[256];
sprintf(sss,"GET https://api.seniverse.com/v3/weather/now.json?key=SOIDqYnBIHFXVAywS&location=zhaoqing&language=zh-Hans&unit=c\r\n");//发送get请求
Usart_SendString(USART1, (unsigned char *)sss, strlen((const char *)sss));
extern unsigned char espbuf_Goal[300];//调用esp8266.c的变量
ESP8266_GetIPD(200);//获取GET请求的返回包
ESP8266_Clear();//清除缓存数据
UsartPrintf(USART2, "%s\r\n",espbuf_Goal);
while(1)
{
}
}
可以看到我们这里已经成功收到来自心知天气返回的一个json的数据表包,而这个包已经储存在espbuf_Goal这个变量里面,剩下的就是如何对espbuf_Goal这个变量进行解析了,这个相信网上有很多资源跟教程,应该不难,或者等过几天再发一篇如何进行json解析这个数据包获取对应的数据
由于是第一次发博客,所以有很多不好的地方需要改进,如果说还有看不懂不会用的可以多看几次多琢磨几次,先把以上的几个AT指令测试几次,就明白了,最后main.c那边的get请求!!! 千万记住最后要加\r\n 否则你是请求不出去的,至于上面还有一个usart的头文件,那个里面其实就是最基本的usar配置和中断优先级配置,这些你们可以自己去配置,也不难,可以多去看看一些其他博主的文章。
最后就是这个esp8266的代码我也不是原创,不过也不难,就是对usart_sendstring这个函数进行不断的封装还有串口中断接收数据而已,我只是提供一些适合初学者GET获取的简单方法,有其他什么不懂的可以留言,当然是对这篇文章的问题,其他太高深的问题我也不懂。以上代码有不好的地方可以指出,我也是初学者,写的可能不是很好。
登陆的实现逻辑很简单,只需要根据传入的用户名和密码做出相应的判断并和数据库中数据匹配即可基本实现1. controller层,先对传入的用户名和密码进行非空判断再调用Service层进行数据库匹配,如果匹配成功则把用户信息存到session域中,并且重定向到admin/index请求,返回index页主要,因为这里涉及到了表单的提交所以再跳转页的时候一定要使用重定向请求转发和直接返回inde...
互联网各职位的简称 :PM&nbsp;(&nbsp;Product Manager&nbsp;)&nbsp;产品经理:&nbsp; &nbsp;&nbsp; &nbsp; 产品的构想、框架的设计、用户的调研等。UE(User&nbsp;Experience,简称UX或&nbsp;UE)用户体验:&nbsp; &nbsp;&nbsp; &nbsp; 还有个组合叫法:UED(产品交互设计师,用
04 | 语法分析语法分析程序(语法分析器)概述自上而下分析法前述递归下降分析法预测分析法( LL(1)分析法 )自下而上分析法前述算符优先分析法LR分析法LR(0)语法分析程序(语法分析器)概述输入:词法分析器生成的单词符号序列输出:语法树详述:语法分析器的功能是以词法分析器生成的单词符号序列作为输入,根据语言的语法规则(描述程序语言语法结构的上下文无关文法),识别出各种语法成分(如表达式、语句、程序段以及整个程序等),并在分析过程中进行语法检查,检查所给单词符号序列是否是该语言的文法的一个句子
杂写感想感想本人网络系统专业学渣一个,毕业已经7、8年了。刚毕业时年轻好玩,社会上随波逐流,天南地北只求快乐、义气。跟着朋友吃吃喝喝,饭馆、电网销之类都做过。慢慢发现人和人是不一样的,有的人直接就生在终点,有些人自带气运,有些人天赋出众;自己呐?既非豪富之家、又无天降横财,只是个普普通通的农村娃,吃穿住行自有一套,但是想要提高,还是要靠自己的努力。后来做运维,桌面运维、软件运维、Linux运维,一步步走到现在。计算机行业的专业性还是蛮大的,工作以后发现学的东西早就忘得一干二净,这几年来网上各种博客论
《教育经济学》作业一、单选题1.我国多数学者认为,应该把教育经济学隶属于经济科学体系,属于( )。A.宏观经济学 B.微观经济学 C.部门经济学 D.产业经济学2.教育经济学是现代经济和现代教育的产物,它在西方萌芽于20世纪20年代,形成于( )年代。A.40 B.60 D.703.人力资本这一概念是由美国的( )于1935年首先使用的A.舒尔茨 B.丹尼森 C.贝克
我们有时候遇到要打开一个文件,我们可以选择用其他应用打开,这时弹出来的应用列表,那么我们如何让自己开发的应用也能出现在里面呢?第一步:设置启动Activity的intent-filter,给data 指定可以打开的mimeType.(注意允许文件操作的权限) <activity android:name=".StartActivity">...
1、引用dll2、将生成的控件拖入到窗体中3、加载Excel模板,含有主要代码,实现cellvaluechange功能,类似datagridviewpath = Util.Pub.DownloadFile("重庆模组成本模型.xlsx"); reoGridControl1.Load(path, unvell.ReoGrid.IO.FileFormat.Excel2007);reoGridControl1.Worksheets[0].Ce
我们知道在java程序中,需要将我们写的java文件编译为class文件才能被使用,一个java程序也是由许许多多的class文件组成。在程序运行的时候是需要将这些class文件加载到内存中才能被我们使用的,而且这些class文件也不是一次性的被加载进内存的,它是什么时候需要就什么时候加载,加载这些class文件到内存中就需要使用ClassLoader类加载器来完成。一般情况下我们不需要关系Cla...
摘 要:随着数字化转型的深入,海量数据对存储提出了新的要求。传统存储虽然有技术成熟、性能良好、可用性高等优点,但面对海量数据,其缺点也越来越明显:如扩展性差、成本高等。为了克服上述缺点,满足海量数据的存储需求,市场上出现了分布式存储技术。分布式存储系统,通常包括主控服务器、存储服务器,以及多个客户端组成。其本质是将大量的文件,均匀分布到多个存储服务器上。当前,分布式存储有多种实现技术,如HDFS、Ceph、GFS、Switf等。在实际工作中,为了更好地引入分布式存储技术,我们需了解各种分布式存储
Tensorflow一些常用基本概念与函数1、tensorflow的基本运作为了快速的熟悉TensorFlow编程,下面从一段简单的代码开始:import tensorflow as tf #定义‘符号’变量,也称为占位符 a = tf.placeholder("float") b = tf.placeholder("float") y = tf.mul(a, b) #构造一个op节点...
文章目录前言一、事件转发1.Forward events to syslog server2.Event Type3.新建日志服务器设备二、事件操作1.告警提示框设置2.告警音设置3.添加事件类型和动作4.查看效果总结前言当网络有告警事件时,该如何向系统日志服务器发送告警日志?事件告警如何以设置警示框、声音告警、邮件发送告警信息?以下步骤将详细介绍赫斯曼网管软件的告警事件设置。一、事件转发1.Forward events to syslog server通过 “Forward event
分布式数据库系统原理分布式数据库系统,简称为DDBS。它源自于两种数据处理方法的结合,一个是数据库系统DBS,另一个则是计算机网络。很有意思的是数据库系统是将企业运营的数据集中起来,提供对数据可控制的存取。但是计算机网络技术提倡的是一种反对集中的工作模式。这两种对比如此鲜明的技术合在一起变成了分布式数据库技术,这种技术追求的是在可能取得集成的情况下放弃集中。分布式分布式处理(或者是分布式计算)没有准确的定义。我们使用的分布式计算系统的定义要求它具备一定数量的自主式处理单元,这些单元通过计算机网络互