使用stm32控制esp01s


title: 使用stm32控制esp01s
date: 2025年2月9日 18:41:20
tags:

  • 单片机
  • 模块使用
    categories: stm32
    description: 使用stm32控制esp01s连接WiFi查看内容等操作

前言

使用stm32f103控制esp01s是步入物联网的第一步,接下来的文章会详细讲解如何使用stm32控制esp01s。

一、电路图设计

对于这个模块的使用我是用我制作的项目来进行使用的,本质的内容很简单,因为esp01s它要进行通讯其实本质上就是用串口来进行通讯的,所以我们只需要使用串口来进行通讯就可以了。电路图如下:

这个电路图很简单,只需要将单片机的串口和esp01s的串口进行连接就可以了,然后再连接电源线,这样就可以了,剩下的就是对于串口通讯的编写了,实现串口收发数据的功能,控制esp01s的操作就是比较简单的了。

二、程序编写

这里主要针对于串口的编写和功能的实现,测试使用的TFT显示屏的代码编写就不说明了,因为不是这一节的内容。

1.串口的编写

1.1 串口的时钟的开启

这里在教程中我没有书写,这里简单介绍一下,实现是开启串口的时钟,这里要开启两个时钟,因为串口是借助GPIO口的,所以需要开启GPIO的时钟后再开启串口的时钟。代码如下:

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);

1.2 串口的配置

这里的串口的配置其实就是配置串口的一些参数,比如波特率、数据位、停止位、校验位等,首先先创建一个配置的变量,这里创建的变量类型为USART_InitTypeDef,然后配置变量的相关参数后使用的USART_Init()函数来进行配置的,配置的时候先需要配置一下GPIO。

对于GPIO来说,首先要确定使用的是USART1还是USART2,如果是一些高性能的,可能还要其它的,这个需要参考手册,对于我们这个基础型来说,只有USART1USART2,所以这里我们使用的是USART1,然后配置的是GPIOA,然后配置的是GPIOA9GPIOA10,这里需要注意的是,GPIOA9GPIOA10一个是TX输入,一个是RX输出,所以这里需要将GPIOA9配置成复用推挽输出的模式,GPIOA10配置为浮空输入。

代码如下:

GPIO_InitTypeDef GPIO_InitStructure = {0};
USART_InitTypeDef USART_InitStruct = {0};GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &GPIO_InitStructure);USART_InitStruct.USART_BaudRate = 115200;
USART_InitStruct.USART_WordLength = USART_WordLength_8b;
USART_InitStruct.USART_StopBits = USART_StopBits_1;
USART_InitStruct.USART_Parity = USART_Parity_No;
USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStruct.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_Init(USART1, &USART_InitStruct);
USART_Cmd(USART1, ENABLE);

1.3 配置串口中断

因为我们没办法知道串口多久才接收数据,所以这里使用的是中断来进行接收数据的,这里使用的是串口的中断接收,所以需要配置一下串口的中断,这里需要先配置串口开启中断后再配置的是串口的中断优先级,然后配置中断。

首先配置串口中断的开启:

USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);

这里的USART_IT_RXNE是串口的中断接收,然后配置串口的中断优先级:

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);

这里的NVIC_PriorityGroup_2是中断优先级分组为2,然后配置中断:

NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_Init(&NVIC_InitStructure);

这样就写好了中断配置,然后在中断服务函数中进行接收数据的处理,这里的中断服务函数我使用状态机来进行实现,因为我们不知道串口什么时候会接收数据,所以这里使用状态机来进行实现,代码如下:

typedef enum
{RECEIVE_IDLE,  // 空闲状态RECEIVE_DATA,  // 接收数据状态RECEIVE_FINISH  // 接收完成状态
}USART_STATE;USART_STATE usart_state = RECEIVE_IDLE;
static uint8_t usart_recv_buf[100] = {0};
static uint8_t usart_recv_index = 0;void USART1_IRQHandler(void)
{uint8_t res = 0;if (USART_GetITStatus(USART1, USART_IT_RXNE) != RESET){// USART_ClearITPendingBit(USART1, USART_IT_RXNE);res = USART_ReceiveData(USART1);switch(usart_state){case RECEIVE_IDLE:if (res != '\r' && res != '\n'){usart_recv_buf[usart_recv_index++] = res;usart_state = RECEIVE_DATA;}else if (res == '\n'){usart_recv_buf[usart_recv_index++] = '\n';}break;case RECEIVE_DATA:if (res == '\r'){// 跳过\r}else{usart_state = RECEIVE_IDLE;usart_recv_buf[usart_recv_index++] = res;if (usart_recv_index >= 100){usart_recv_index = 0;usart_state = RECEIVE_FINISH;}}break;case RECEIVE_FINISH:usart_state = RECEIVE_IDLE;usart_recv_index = 0;break;}USART_ClearITPendingBit(USART1, USART_IT_RXNE);}
}

这里的状态机还是比较简单的,就是一开始是未接收状态,如果接收到的不是\r或者\n就开始接收数据,然后如果都不是那就开始接收数据,当接收到\r或者\n就开始接收完成状态,然后将接收的数据进行处理。

但是我感觉这个状态机有点问题,但暂时没有更好的方案,大家如果有更好的方案可以和我交流一下。

1.4 发送数据

发送数据的代码很简单,就是先判断发送标志位是否置位,然后发送数据,然后等待发送完成,代码如下:

void Usart_Send(uint8_t* str)
{while(*str != '\0'){while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);    // 等待发送寄存器为空USART_SendData(USART1, *str++);}
}

这里的USART_FLAG_TXE是发送寄存器为空的标志位,然后发送数据,然后等待发送完成。

这样对于串口的代码就写好了,然后就是对于esp01s的控制了。

2.esp01s的控制

对于esp01s的控制其实就是串口的发送数据,然后等待接收数据,然后将接收的数据进行处理,这里的处理就是判断接收的数据是否正确,然后进行相应的操作,这里的操作就是连接WiFi,然后将连接的数据显示在TFT显示屏上,因为只是简单的介绍,对于更多的操作我还没有加,因为只要把这些最基础的问题解决了后,剩下的只是在这个基础上增加东西。

这里的操作其实就是发送AT指令,当esp01s接收到AT指令后就会进行相应的操作,然后将操作的结果返回给esp01s,然后esp01s将结果返回给单片机,单片机就可以进行相应的操作了。

这里的AT指令我就不一一介绍了,因为我也不是很清楚,大家可以去百度一下,然后就可以了。

这里就简单的把我写的代码贴出来,大家可以去百度一下,然后就可以了。

#include "esp01s.h"
#include "system_config.h"
#include "stdio.h"// 这个是去除空格
void Clear_String_Lj(uint8_t* buf)
{uint8_t recv_buf[100];uint8_t i = 0;uint8_t j = 0;Usart_Get_Recv_Buf(recv_buf);do{if (recv_buf[i]=='\n' && recv_buf[i+1]=='\n'){buf[j++] = '\n';i += 2;}else {buf[j++] = recv_buf[i++];}}while(recv_buf[i] != '\0');buf[j] = '\0';
}void ESP01S_Init(uint8_t* buf)
{// 初始化串口Usart_Init();
}void ESP01S_Test(uint8_t* buf)
{Usart_Send("AT+CWSTATE?\r\n");delay_ms(1000);Clear_String_Lj(buf);
}void ESP01S_Rst(uint8_t* buf)
{Usart_Send("AT+RST\r\n");delay_ms(1000);Clear_String_Lj(buf);
}void ESP01S_Look_GMR(uint8_t* buf)
{Usart_Send("AT+GMR\r\n");delay_ms(1000);Usart_Get_Recv_Buf(buf);
}void ESP01S_Wifi_Mode_Show(uint8_t* buf)
{Usart_Send("AT+CWMODE?\r\n");delay_ms(1000);Clear_String_Lj(buf);
}void ESP01S_Wifi_Mode_Set(uint8_t* buf, ESP01S_WIFI_MODE mode)
{uint8_t str[16];sprintf((char*)str, "AT+CWMODE=%d\r\n", mode);Usart_Send(str);delay_ms(1000);Clear_String_Lj(buf);
}void ESP01S_Wifi_Join(uint8_t* buf)
{uint8_t str[32];sprintf((char*)str, "AT+CWJAP=\"%s\",\"%s\"\r\n", WIFI_NAME, WIFI_PASSWORD);Usart_Send(str);delay_ms(1000);Usart_Get_Recv_Buf(buf);
}void ESP01S_Wifi_Join_Show(uint8_t* buf)
{Usart_Send("AT+CIPSTATE?\r\n");delay_ms(1000);Usart_Get_Recv_Buf(buf);
}

然后我们可以让esp01s连接WiFi,后面就可以通过网络来进行其它的操作了,这里只是简单的介绍一下,后面的文章我会详细介绍一下。

#include "stm32f10x.h"                  // Device header
#include "TFT144.h"
#include "systick.h"
#include "image.h"
#include "button.h"
#include "buzz.h"
#include "DS3231.h"
#include "stdio.h"          // HACK 测试
#include "esp01s.h"void menu2(void)
{uint8_t buf[100];TFT_Clear(TFT_Color(255, 255, 255));ESP01S_Wifi_Join(buf);while(1){TFT_Show_String(0, 0, TFT_Color(0, 0, 0), TFT_Color(255, 255, 255), buf);if (Read_Button_B()){TFT_Clear(TFT_Color(255, 255, 255));void ESP01S_Wifi_Join_Show(uint8_t* buf);TFT_Show_String(0, 0, TFT_Color(0, 0, 0), TFT_Color(255, 255, 255), buf);break;}}
}int main(){uint8_t buf[100];TFT_Init();Button_Init();Buzz_Init();DS3231_Init();TFT_Clear(TFT_Color(255, 255, 255));delay_ms(1000);ESP01S_Init(buf);ESP01S_Wifi_Mode_Set(buf, ESP01S_WIFI_STATION);TFT_Show_String(0, 0, TFT_Color(0, 0, 0), TFT_Color(255, 255, 255), buf);while(1){if (Read_Button_B()){menu2();}}
}

效果如下:

这样就连接到WiFi了,因为是连接的电脑热点,所有可以在电脑上看到设备连接情况:

总结

其实对于esp01s的控制还是比较简单的,因为它本质上就是串口的通讯,所以我们只需要使用串口来进行通讯就可以了,然后就可以了,后面的文章我会详细介绍一下。

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

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

相关文章

PT8042 双触控双输出触摸 IC

1. 产品概述 PT8042 是一款电容式触摸控制 ASIC ,支持双通道触摸输入和双路同步开关输出,可引脚配置 同步输出的有效电平。 PT8042 实现触摸同步开关控制。适用于雾化器、车载用品、电子玩具、 消费类电子产品等领域,具有低功耗、高抗…

【AI学习】DeepSeek-R1-Distill的意义和影响

在写完上一篇文章《DeepSeek为什么这么火爆?解密梁文锋的深谋远虑》后,又想到了一个新的问题。 在DeepSeek R1的技术报告中,还有这样一个技术:蒸馏赋予小模型推理能力。这项技术的意义和影响是什么? 先看看这个技术&…

qml ToolBar详解

1、概述 在 QML 中,ToolBar 是一种常用的 UI 组件,通常位于窗口的顶部或底部,用于提供一系列的操作按钮、菜单或其他交互元素。它可以帮助用户快速访问应用程序的常用功能,提高用户操作的便捷性。ToolBar 可以包含多个 ToolButto…

视频理解新篇章:Mamba模型的探索与应用

人工智能咨询培训老师叶梓 转载标明出处 想要掌握如何将大模型的力量发挥到极致吗?叶老师带您深入了解 Llama Factory —— 一款革命性的大模型微调工具(限时免费)。 1小时实战课程,您将学习到如何轻松上手并有效利用 Llama Facto…

Flutter项目试水

1基本介绍 本文章在构建您的第一个 Flutter 应用指导下进行实践 可作为项目实践的辅助参考资料 Flutter 是 Google 的界面工具包,用于通过单一代码库针对移动设备、Web 和桌面设备构建应用。在此 Codelab 中,您将构建以下 Flutter 应用。 该应用可以…

LVS作业

1、对比 LVS 负载均衡群集的 NAT 模式和 DR 模式,比较其各自的优势 。 NAT 模式 部署与管理优势 配置简易:在 NAT 模式中,负载均衡器主要承担网络地址转换的工作,只需配置简单的 NAT 规则,就能实现将外部请求合理地转…

从零开始手写Shell:详解命令行解释器的实现原理

Shell的本质认知 命令行解释器(Shell)是操作系统的"翻译官",它的核心工作流程可以抽象为: 循环 {1. 显示提示符2. 获取命令输入3. 解析命令参数4. 执行命令程序 }本实现仅需200行C代码,却能完整展现Shell的…

mysql读写分离与proxysql的结合

上一篇文章介绍了mysql如何设置成主从复制模式,而主从复制的目的,是为了读写分离。 读写分离,拿spring boot项目来说,可以有2种方式: 1)设置2个数据源,读和写分开使用 2)使用中间件…

机器学习10-卷积和卷积核3

机器学习10-卷积和卷积核3 纹理表示卷积神经网络全链接神经网络的瓶颈卷积网络中的卷积操作特征响应图组尺寸计算 池化操作示例 图像增强翻转随机缩放抠图色彩抖动其他方案1. 平移2. 旋转3. 拉伸4. 径向畸变5. 裁剪 纹理表示 如何去表示纹理? 基于卷积核组的纹理表…

办公用品管理系统需求说明

办公用品管理系统需求说明 1. 系统概述 目标:实现办公用品的全生命周期管理(采购→入库→领用→盘点→报废),提升物资使用效率,降低运营成本 用户角色: 普通员工部门管理员采购专员财务人员系统管理员 …

Shell-基本命令与运算符

1.为什么要进行shell编程? 在Linux系统中,虽然有各种各样的图形化接口工具,但是shell仍然是一个非常灵活的 工具。 Shell不仅仅是命令的收集,而且是一门非常棒的编程语言。 您可以通过使用shell使大量的任务自动化, 因此&#…

Spring基于文心一言API使用的大模型

有时做项目我们可能会遇到要在项目中对接AI大模型 本篇文章是对使用文心一言大模型的使用总结 前置任务 在百度智能云开放平台中注册成为开发者 百度智能云开放平台 进入百度智能云官网进行登录,点击立即体验 点击千帆大模型平台 向下滑动,进入到模型…

【工业安全】-CVE-2022-35555- Tenda W6路由器 命令注入漏洞

文章目录 1.漏洞描述 2.环境搭建 3.漏洞复现 4.漏洞分析 4.1:代码分析  4.2:流量分析 5.poc代码: 1.漏洞描述 漏洞编号:CVE-2022-35555 漏洞名称:Tenda W6 命令注入 威胁等级:高危 漏洞详情&#xff1…

xtuner微调internlm2-chat-1_8b--xtuner中文文档快速上手案例

xtuner微调internlm2-chat-1_8b–xtuner中文文档快速上手案例 设备:百度飞桨免费算力平台16GB显存 1. 安装库 conda conda create --name xtuner-env python3.10 -y conda activate xtuner-env将model的conda保存到本地防止丢失 conda env list #参考env在那个…

智慧出行与车路云一体化政策研究报告

智慧出行政策的发展趋势可以大致划分为三个阶段,与行业发展历程紧密相连。当前,智慧出行政策正逐步进入第三阶段,即技术融合与广泛应用阶段。这一阶段的政策发展趋势将更加注重智慧出行的全面融合和创新应用。比如智能网联技术在智慧出行层面…

民兵装备管理系统DW-S300|支持国产化、自主研发

民兵装备器材管理系统(智装备DW-S301)是一套成熟系统,依托互3D技术、云计算、大数据、RFID技术、数据库技术、AI、视频分析技术对RFID智能仓库进行统一管理、分析的信息化、智能化、规范化的系统。 装备接收与登记 民兵装备抵达仓库时&#…

【STM32系列】利用MATLAB配合ARM-DSP库设计FIR数字滤波器(保姆级教程)

ps.源码放在最后面 设计IIR数字滤波器可以看这里:利用MATLAB配合ARM-DSP库设计IIR数字滤波器(保姆级教程) 前言 本篇文章将介绍如何利用MATLAB与STM32的ARM-DSP库相结合,简明易懂地实现FIR低通滤波器的设计与应用。文章重点不在…

服务器,交换机和路由器的一些笔记

服务器、交换机和路由器是网络中常用的设备,它们的本质区别和联系如下: 本质区别 功能不同 服务器:就像一个大型的资料仓库和工作处理中心,主要用来存储和管理各种数据,比如网站的网页数据、公司的办公文档等&#x…

SpringCloud - Gateway 网关

前言 该博客为Sentinel学习笔记,主要目的是为了帮助后期快速复习使用 学习视频:7小快速通关SpringCloud 辅助文档:SpringCloud快速通关 源码地址:cloud-demo 一、简介 官网:https://spring.io/projects/spring-clou…

【vs2022配置cursor】

Cursor搭配cmake实现C程序的编译、运行和调试的参考地址 cursor下载地址 第一步: 电脑上按爪cmake 第二步:cursor 配置 安装中文 第三步环境变量: D:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.35.322…