stm32与esp8266WIFI模块

硬件介绍

WIFI模块ESP-01S

使用AT指令控制1-ESP8266-AT指令初试化及部分基础知识_ch_pd-CSDN博客

项目需求

通过ESP-01SWIFI模块控制LED状态模拟插座

串口1用于与ESP8266通讯,串口2连接PC,用于打印log,查看系统状态

项目接线

WIFI模块TXRX分别接到单片机的RX1和TX1

CH340TXDRXD分别接到单片机的RX2和TX2

项目注意事项 

1. 在这个项目里,烧写完单片机之后,不光要点击复位,还要重启单片机电源,以确保WIFI模块重新启动

2. 在以后的工作中一般不直接在中断服务函数里处理数据,而是在收到数据后直接丢给队列,再处理数据

3. 在中断服务函数里尽量减少使用延时函数及打印函数

4. 2,3条在本项目中并没有实现,因为还没有学到Linux的队列概念,只是先留个印象

5. 由于之前的WIFI模块波特率改成了9600,所以现在连接CH340修改回 115200(使用AT指令修改)

 AP模式下控制的实现(透传)

CubeMX

1. 惯例配置(时钟,gpio,系统时钟)

2. 打开两个串口(uart1和uart2),并在WIFI模块对应的串口1打开中断

 3. 由于在中断处理函数中使用了Delay函数,得调整中断的优先级(非必要不使用,容易造成未知错误)

4. 惯例配置,导出工程(路径,编程软件)

Keil

要在魔术棒中将MiroLIB勾选,使得可以重写printf

代码:

#include <stdio.h>
#include <string.h>//串口接收缓存(1字节)
uint8_t buf=0;//定义最大接收字节数 200,可根据需求调整
#define UART1_REC_LEN 200// 接收缓冲, 串口接收到的数据放在这个数组里,最大UART1_REC_LEN个字节
uint8_t UART1_RX_Buffer[UART1_REC_LEN];//  接收状态
//  bit15,      接收完成标志
//  bit14,      接收到0x0d
//  bit13~0,    接收到的有效字节数目
uint16_t UART1_RX_STA=0;char buffer[12];char connect_net[]       = "AT+CWJAP=\"bbb\",\"56893233\"\r\n";              //入网指令   \r\n新行
char connect_servere[]   = "AT+CIPSTART=\"TCP\",\"192.168.93.248\",8880\r\n";//连接服务器指令char Transparent_mode[]  = "AT+CIPMODE=1\r\n";     //透传模式指令
char data_transmission[] = "AT+CIPSEND\r\n";       //数据传输开始指令                //数据传输
char reset[]             = "AT+RST\r\n";           //重启模块指令
char AT_OK_flag = 0;			    //OK返回值的标志位
char AT_Connect_Net_Flag = 0;		//WIFI GOT IP返回值的标志位void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{// 判断中断是由哪个串口触发的if(huart->Instance == USART1){// 判断接收是否完成(UART1_RX_STA bit15 位是否为1)if((UART1_RX_STA & 0x8000) == 0){// 如果已经收到了 0x0d (回车),if(UART1_RX_STA & 0x4000){// 则接着判断是否收到 0x0a (换行)if(buf == 0x0a){// 如果 0x0a 和 0x0d 都收到,则将 bit15 位置为1UART1_RX_STA |= 0x8000;//程序运行到此处,代表数据已经完整接收,可以开始判断////查看是否收到WIFI GOT IPif(strcmp(UART1_RX_Buffer,"WIFI GOT IP") == 0){HAL_UART_Transmit(&huart2, "111\r\n",strlen("111\r\n"), 100);AT_Connect_Net_Flag = 1;}//查看是否收到OKif(strcmp(UART1_RX_Buffer,"OK") == 0){HAL_UART_Transmit(&huart2, "222\r\n",strlen("222\r\n"), 100);AT_OK_flag = 1;}//灯控指令if(strcmp(UART1_RX_Buffer,"open") == 0){HAL_GPIO_WritePin(GPIOB,GPIO_PIN_8,GPIO_PIN_RESET);}if(strcmp(UART1_RX_Buffer,"close") == 0){HAL_GPIO_WritePin(GPIOB,GPIO_PIN_8,GPIO_PIN_SET);}//如果联网失败,收到FAILif(!strcmp(UART1_RX_Buffer,"FAIL")){HAL_UART_Transmit(&huart2, "error\r\n",strlen("error\r\n"), 100);int i;for(i = 0;i <5;i++){HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_8);HAL_Delay(1000);}printf(reset);}memset(UART1_RX_Buffer,0,UART1_REC_LEN);UART1_RX_STA = 0;}else// 否则认为接收错误,重新开始UART1_RX_STA = 0;}else	// 如果没有收到了 0x0d (回车){//则先判断收到的这个字符是否是 0x0d (回车)if(buf == 0x0d){// 是的话则将 bit14 位置为1UART1_RX_STA |= 0x4000;}else{// 否则将接收到的数据保存在缓存数组里UART1_RX_Buffer[UART1_RX_STA & 0X3FFF] = buf;UART1_RX_STA++;// 如果接收数据大于UART1_REC_LEN(200字节),则重新开始接收if(UART1_RX_STA > UART1_REC_LEN - 1)UART1_RX_STA = 0;}}}// 重新开启中断HAL_UART_Receive_IT(&huart1, &buf, 1);}
}int fputc(int ch, FILE *f)
{//注意,printf的重写是针对串口1的,也就是wifi的,对于串口2的数据发送不能用printf unsigned char temp[1]={ch};HAL_UART_Transmit(&huart1,temp,1,0xffff);  return ch;
}int main(void)
{HAL_NVIC_SetPriority(SysTick_IRQn,0,0);// 开启接收中断HAL_UART_Receive_IT(&huart1, &buf, 1);HAL_UART_Transmit(&huart2, "START\r\n",strlen("START\r\n"), 100);printf(connect_net); //发送联网AT指令并等待成功while(!AT_Connect_Net_Flag)  HAL_Delay(50);//此处这个delay必须得加,不然程序会卡死while(!AT_OK_flag)  HAL_Delay(50);//此处这个delay必须得加,不然程序会卡死HAL_UART_Transmit(&huart2, "5555\r\n",strlen("5555\r\n"), 100);AT_OK_flag = 0;//发送连服务器指令并等待成功printf(connect_servere);while(!AT_OK_flag)  HAL_Delay(50);HAL_UART_Transmit(&huart2, "6665\r\n",strlen("6665\r\n"), 100);AT_OK_flag = 0;//发送透传模式指令并等待成功printf(Transparent_mode);while(!AT_OK_flag)	HAL_Delay(50);HAL_UART_Transmit(&huart2, "7775\r\n",strlen("7775\r\n"), 100);AT_OK_flag = 0;//发送数据传输指令并等待成功printf(data_transmission);while(!AT_OK_flag)	HAL_Delay(50);while (1){printf("hhhhhhhhhhhhaaaaaaaaaa");HAL_UART_Transmit(&huart2, "hello shion\r\n",strlen("hello shion\r\n"), 100);HAL_Delay(3000);}}

实验效果: 

注意!要记得将服务器打开,不然一直连接不上(以至于折磨了我好长时间调试)


在电脑串口和网络调试助手可以看到不断发来的心跳包。

同时,串口1作为单片机和WIFI的通信,而串口2作为日志发回电脑的串口助手,串口1每发送并成功接收了回应,串口2就会返回电脑成功的信息,这样用户就可以可视化的看到连接进行到了哪一步,这算是用两路串口实现了以前白盒测试和黑盒测试的效果。

 当在网络助手发送“open”加上回车时,继电器会打开;反之输入“close”加上回车,继电器会闭合

STA模式下控制的实现

在这种模式下,ESP作为路由器,由电脑连接ESP的WIFI,作为Client来接收和发送。

以下是之前学习WIFI模块时总结的,关于ESP作为STA模式下的相关命令

 

CubeMX

同上

Keil

通过白盒测试可知:在ESP作为STA的模式下,WIFI助手发送的数据在串口中显示的是有特定格式的:

如果发送“open”加回车,那么显示的是:+IPD,0,6:open

如果发送“close”加回车,那么显示的是:+IPD,0,7:close

因此,在KEIL中的代码中,字符串的比较不能直接和open close比较,而是和以上两个字符串进行比较!!!

代码

#include <stdio.h>
#include <string.h>//串口接收缓存(1字节)
uint8_t buf=0;//定义最大接收字节数 200,可根据需求调整
#define UART1_REC_LEN 200// 接收缓冲, 串口接收到的数据放在这个数组里,最大UART1_REC_LEN个字节
uint8_t UART1_RX_Buffer[UART1_REC_LEN];//  接收状态
//  bit15,      接收完成标志
//  bit14,      接收到0x0d
//  bit13~0,    接收到的有效字节数目
uint16_t UART1_RX_STA=0;char buffer[12];char connect_net[]       = "AT+CWJAP=\"bbb\",\"56893233\"\r\n";              //入网指令   \r\n新行char mode[]    = "AT+CWMODE=2\r\n";    //路由器模式指令
char mul_con[] = "AT+CIPMUX=1\r\n";    //使能多链接
char server[]  = "AT+CIPSERVER=1\r\n"; //建立TCPServer   default port = 333
char send[]    = "AT+CIPSEND=0,5\r\n"; //发送数据
char end[]     = "AT+CIPCLOSE=0\r\n";  //断开连接char AT_Connect_Net_Flag = 0;		//WIFI GOT IP返回值的标志位char AT_OK_flag = 0;              //OK返回值的标志位
char Client_Connent_Flag = 0;     //客户端接入返回值标志位// 接收完成回调函数,收到一个数据后,在这里处理
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{// 判断中断是由哪个串口触发的if(huart->Instance == USART1){// 判断接收是否完成(UART1_RX_STA bit15 位是否为1)if((UART1_RX_STA & 0x8000) == 0){// 如果已经收到了 0x0d (回车),if(UART1_RX_STA & 0x4000){// 则接着判断是否收到 0x0a (换行)if(buf == 0x0a){// 如果 0x0a 和 0x0d 都收到,则将 bit15 位置为1UART1_RX_STA |= 0x8000;//程序运行到此处,代表数据已经完整接收,可以开始判断////查看是否收到WIFI GOT IPif(strcmp(UART1_RX_Buffer,"WIFI GOT IP") == 0){HAL_UART_Transmit(&huart2, "111\r\n",strlen("111\r\n"), 100);AT_Connect_Net_Flag = 1;}//查看是否收到OKif(strcmp(UART1_RX_Buffer,"OK") == 0){HAL_UART_Transmit(&huart2, "222\r\n",strlen("222\r\n"), 100);AT_OK_flag = 1;}//灯控指令if(strcmp(UART1_RX_Buffer,"+IPD,0,6:open") == 0){HAL_GPIO_WritePin(GPIOB,GPIO_PIN_8,GPIO_PIN_RESET);}if(strcmp(UART1_RX_Buffer,"+IPD,0,7:close") == 0){HAL_GPIO_WritePin(GPIOB,GPIO_PIN_8,GPIO_PIN_SET);}//如果联网失败,收到FAILif(!strcmp(UART1_RX_Buffer,"0,CONNECT")){Client_Connent_Flag = 1;}memset(UART1_RX_Buffer,0,UART1_REC_LEN);UART1_RX_STA = 0;}else// 否则认为接收错误,重新开始UART1_RX_STA = 0;}else	// 如果没有收到了 0x0d (回车){//则先判断收到的这个字符是否是 0x0d (回车)if(buf == 0x0d){// 是的话则将 bit14 位置为1UART1_RX_STA |= 0x4000;}else{// 否则将接收到的数据保存在缓存数组里UART1_RX_Buffer[UART1_RX_STA & 0X3FFF] = buf;UART1_RX_STA++;// 如果接收数据大于UART1_REC_LEN(200字节),则重新开始接收if(UART1_RX_STA > UART1_REC_LEN - 1)UART1_RX_STA = 0;}}}// 重新开启中断HAL_UART_Receive_IT(&huart1, &buf, 1);}
}int fputc(int ch, FILE *f)
{//注意,printf的重写是针对串口1的,也就是wifi的,对于串口2的数据发送不能用printf unsigned char temp[1]={ch};HAL_UART_Transmit(&huart1,temp,1,0xffff);  return ch;
}int main(void)
{HAL_NVIC_SetPriority(SysTick_IRQn,0,0);// 开启接收中断HAL_UART_Receive_IT(&huart1, &buf, 1);HAL_UART_Transmit(&huart2, "START\r\n",strlen("START\r\n"), 100);printf(mode);//发送客户端模式指令并等待成功while(!AT_OK_flag)	HAL_Delay(50);AT_OK_flag = 0;HAL_UART_Transmit(&huart1, "mode set success\r\n", strlen("mode set success\r\n"), 100);printf(mul_con);while(!AT_OK_flag)	HAL_Delay(50);AT_OK_flag = 0;printf(server);while(!Client_Connent_Flag)	HAL_Delay(50);AT_OK_flag = 0;if(Client_Connent_Flag){HAL_GPIO_WritePin(GPIOB,GPIO_PIN_8,GPIO_PIN_RESET);HAL_GPIO_WritePin(GPIOB,GPIO_PIN_9,GPIO_PIN_RESET);}while (1){printf(send);//发送数据HAL_Delay(2000);printf("wdnmd");//发给串口1的,共2个字节HAL_Delay(2000);}}

 

实现效果

打开单片机点击复位,使得电脑连上”esp8266“的WIFI,然后在网络助手中输入相关信息之后点击连接:(要提前连好wifi的情况)1-ESP8266-AT指令初试化及部分基础知识_ch_pd-CSDN博客STA模式具体连接再次参考这个

当在网络助手发送“open”加上回车时,LED1会打开;反之输入“close”加上回车,LED1会关闭

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/801656.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

关于在Ubuntu上配置mysql踩的一些坑

最近准备换工作了&#xff0c;回顾了下学校时期做的那个webserver&#xff0c;又在linux下mysql踩了一些坑&#xff0c;特此记录下来 程序编译错误mysql.h: No such file or directory 云服务器缺少mysql必要的运行组件&#xff0c;安装&#xff1a; sudo apt-get install l…

智慧农场物联网系统:重塑农业的未来

随着科技的进步&#xff0c;物联网技术正在逐渐改变我们的生活。在农业领域&#xff0c;物联网系统也正在发挥着越来越重要的作用&#xff0c;为智慧农场的发展提供了新的可能。本文将深入探讨智慧农场物联网系统的优势、应用场景、技术实现以及未来发展趋势。 一、智慧农场物…

ATAM方法架构评估实践

用ATAM方法评估软件体系结构&#xff0c;其工作分为4个基本阶段&#xff0c;即演示、调查和分析、测试和报告ATAM&#xff08;如图1所示&#xff09;。接下来分别就每个阶段的实践进行详细介绍。 图1 ATAM方法的评估实践阶段划分 1.阶段1——演示&#xff08;Presentation&…

Android14音频进阶之<进阶调试>:Perfetto定位系统音频问题(六十六)

简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长! 优质专栏:Audio工程师进阶系列【原创干货持续更新中……】🚀 优质专栏:多媒体系统工程师系列【原创干货持续更新中……】🚀 优质视频课程:AAOS车载系统+AOSP…

【算法 | 背包专题】分组背包(解题思路+题单)

分组背包 上一节&#xff0c;我们提到了什么是01背包&#xff0c;以及如何求解01背包&#xff1a; 【算法 | 背包专题】01背包&#xff08;状态定义状态转移解题流程题单&#xff09; 现在&#xff0c;我们来看分组背包。 分组背包问题是背包问题的一种变形。在这个问题中&…

转化延迟预估

转化数据延迟久&#xff0c;但实时反馈至关重要涉及到模型预估准度&#xff0c;进而影响客户成本。 现状&#xff1a;超过12h的转化被视为负例&#xff0c;12h以内的为正例&#xff0c;这样会导致模型低估。公示如下&#xff1a; P ( 转化 ∣ 点击 ) 延迟 ≤ 12 h 的转化 未转…

eclipse怎么配置git

在Eclipse中配置Git的步骤如下&#xff1a; 安装Git插件。打开Eclipse&#xff0c;选择“Help”菜单&#xff0c;然后点击“Eclipse Marketplace”。在搜索框中输入“EGit”&#xff0c;选择Eclipse Git Team Provider&#xff0c;点击“Go”按钮&#xff0c;然后点击“Inst…

【LeetCode】热题100:LRU缓存

题目&#xff1a; 请你设计并实现一个满足 LRU (最近最少使用) 缓存 约束的数据结构。 实现 LRUCache 类&#xff1a; LRUCache(int capacity) 以 正整数 作为容量 capacity 初始化 LRU 缓存 int get(int key) 如果关键字 key 存在于缓存中&#xff0c;则返回关键字的值&…

什么是人工智能?人工智能、机器学习、深度学习三者之间有什么关系吗?

深度学习是机器学习的一个分支。深度学习是机器学习的一部分&#xff0c;与机器学习的其他分支学科&#xff0c;以及统计学、人工智能等学科都有着紧密的联系。深度学习、机器学习、人工智能、统计学之间的关系如图1-4所示。 图1-4 深度学习、机器学习、人工智能、统计学之间的…

【C语言】指针篇(指针数组,数组指针,函数指针,一级、二级指针)

文章目录 一、指针基础1.什么是指针2.指针的定义和初始化3.指针的解引用4.野指针和空指针5.指针的类型6.指针的大小7.指针的运算8.指针和数组9.指针和字符串10.二级指针 二、指针数组和数组指针1.指针数组2.数组指针3.练习 三、数组传参和指针传参1.一维数组传参2.二维数组传参…

Maven POM元素解析

这是对Maven中使用的Maven项目描述符的引用。 <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/…

GEE:基于CHIRPS数据集的累积降水量影像下载

作者:CSDN @ _养乐多_ 本文将介绍在 Google Earth Engine(GEE)平台上使用“UCSB-CHG/CHIRPS/DAILY”数据集计算某一段时期(某年/某个季节/某月)的累积降雨量图像,并下载。 结果如下图所示, 文章目录 一、核心函数二、代码链接三、完整代码一、核心函数 .sum() // 对影…

02 Php学习:变量

Php 变量声明 Php 变量赋值 在PHP中&#xff0c;变量赋值是指将一个值赋给一个变量。变量赋值是 PHP 中最基本和常见的操作之一&#xff0c;以下是关于变量赋值的详细说明和示例&#xff1a; 变量赋值语法&#xff1a; $variable value;$variable&#xff1a;要赋值的变量名…

速盾:游戏cdn什么意思

CDN&#xff08;Content Delivery Network&#xff09;是指内容分发网络&#xff0c;它是由一组位于世界各地的服务器组成的网络&#xff0c;用于将内容有效地传输给用户。游戏CDN&#xff0c;顾名思义&#xff0c;就是用于游戏内容分发的网络。 在传统的网络传输模式中&#…

【MATLAB源码-第38期】基于OFDM的块状导频和梳状导频误码率性能对比,以及LS/LMMSE两种信道估计方法以及不同调制方式对比。

操作环境&#xff1a; MATLAB 2022a 1、算法描述 块状导频和梳状导频都是用于无线通信系统中信道估计的方法。 块状导频&#xff1a; 定义&#xff1a; 在频域上&#xff0c;块状导频是连续放置的一组导频符号。这意味着所有的导频符号都集中在一个短的时间段内发送。 优点…

【Java编程进阶之路 11】Java内存管理深度剖析:垃圾回收机制与性能优化

文章目录 Java内存管理深度剖析&#xff1a;垃圾回收机制与性能优化引言01 Java内存管理基础1.1 堆&#xff08;Heap&#xff09;1.2 栈&#xff08;Stack&#xff09;1.3 方法区&#xff08;Method Area&#xff09;1.4 为什么需要垃圾回收&#xff1f; 02 垃圾回收的重要性2.…

php站长在线工具箱源码优化版

环境要求 PHP > 7.4MySQL > 5.6fileinfo扩展使用Redis缓存需安装Redis扩展 源码下载地址&#xff1a;php站长在线工具箱源码优化版.zip

计算机组成原理核心知识——计算机系统工作

目录 一、计算机运算&#xff08;一&#xff09;符号数和无符号数&#xff08;二&#xff09;定点数和浮点数&#xff08;三&#xff09;原码、反码、补码和移码 二、总线&#xff08;一&#xff09;系统总线&#xff08;二&#xff09;通信总线&#xff08;三&#xff09;单/多…

RISC-V特权架构 - 模式切换与委托

RISC-V特权架构 - 模式切换与委托 1 导致模式切换的常见动作2 异常处理规则3 异常处理时模式切换3.1 在U模式下&#xff0c;发生异常3.2 在S模式下&#xff0c;发生异常3.3 在M模式下&#xff0c;发生异常 4 系统调用时模式切换5 中断处理时模式切换 本文属于《 RISC-V指令集基…

PaddleVideo:onnx模型导出

本文节介绍 PP-TSM 模型如何转化为 ONNX 模型&#xff0c;并基于 ONNX 引擎预测。 1&#xff1a;环境准备 安装 Paddle2ONNX python -m pip install paddle2onnx 安装 ONNXRuntime # 建议安装 1.9.0 版本&#xff0c;可根据环境更换版本号 python -m pip install onnxrunti…