基于stm32的esp8266的WIFI控制风扇实验

实验案例WIFI控制风扇

项目需求

电脑通过esp8266模块远程遥控风扇。

项目框图

风扇模块封装 

#include "sys.h"
#include "fan.h"void fan_init(void)
{GPIO_InitTypeDef gpio_initstruct;//打开时钟__HAL_RCC_GPIOB_CLK_ENABLE();//调用GPIO初始化函数gpio_initstruct.Pin  = GPIO_PIN_6;gpio_initstruct.Mode = GPIO_MODE_OUTPUT_PP;gpio_initstruct.Pull = GPIO_PULLUP;//上拉需要给一个下降沿gpio_initstruct.Speed= GPIO_SPEED_FREQ_HIGH;HAL_GPIO_Init(GPIOB,&gpio_initstruct);//关闭LEDfan1_off();
}
void fan1_on(void)
{//由电路图可知,将GPIO拉低HAL_GPIO_WritePin(GPIOB,GPIO_PIN_6,GPIO_PIN_RESET);}
//熄灭LED1的函数void fan1_off(void)
{//由电路图可知,将GPIO拉低HAL_GPIO_WritePin(GPIOB,GPIO_PIN_6,GPIO_PIN_SET);}//获取继电器的状态uint8_t fan_status_get(void)
{return (uint8_t)HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_6);//要么返回0,要么返回1}


esp8266功能代码封装 

头文件

#include "sys.h"
#include "esp8266.h"
#include "string.h"
#include "delay.h"
#include "stdarg.h"uint8_t esp8266_tx_buf[ESP8266_TX_BUF_SIZE];
uint8_t esp8266_rx_buf[ESP8266_RX_BUF_SIZE]; uint16_t esp8266_cnt = 0 ,esp8266_cntPre = 0; /* esp8266接收缓冲区 */UART_HandleTypeDef esp8266_handle;             /* esp8266句柄 */

esp8266串口初始化配置

void esp8266_uart_init(uint32_t baudrate)//正常会有启动的流程只是作为一个串口的初始化
{/*esp8266 初始化设置*/esp8266_handle.Instance = USART2;                               /* USART1 */esp8266_handle.Init.BaudRate = baudrate;                        /* 波特率 */esp8266_handle.Init.WordLength = UART_WORDLENGTH_8B;            /* 字长为8位数据格式*/esp8266_handle.Init.StopBits = UART_STOPBITS_1;                 /* 一个停止位 */esp8266_handle.Init.Parity = UART_PARITY_NONE;                  /* 无奇偶校验位 */esp8266_handle.Init.HwFlowCtl = UART_HWCONTROL_NONE;            /* 无硬件流控 */esp8266_handle.Init.Mode = UART_MODE_TX_RX;                     /* 收发模式 */HAL_UART_Init(&esp8266_handle);                                 /*会使能esp8266 */                 
}

接收缓冲区配置

void esp8266_rx_clear(void)
{memset(esp8266_rx_buf, 0, sizeof(esp8266_rx_buf)); /* 清空接收缓冲区 */esp8266_cnt = 0;                                   /* 接收计数器清零 */
}

中断服务函数

void USART2_IRQHandler(void)
{uint8_t receive_data = 0;   if(__HAL_UART_GET_FLAG(&esp8266_handle, UART_FLAG_RXNE) != RESET){/* 获取接收RXNE标志位是否被置位 */if(esp8266_cnt >= sizeof(esp8266_rx_buf))                     /* 如果接收的字符数大于接收缓冲区大小, */esp8266_cnt = 0;                                          /* 则将接收计数器清零 */HAL_UART_Receive(&esp8266_handle, &receive_data, 1, 1000);    /* 接收一个字符 */esp8266_rx_buf[esp8266_cnt++] = receive_data;    /* 将接收到的字符保存在接收缓冲区 */}if (__HAL_UART_GET_FLAG(&esp8266_handle, UART_FLAG_IDLE) != RESET) /* 获取接收空闲中断标志位是否被置位 */{printf("recv: %s\r\n", esp8266_rx_buf);                  /* 将接收到的数据打印出来 */esp8266_rx_clear();__HAL_UART_CLEAR_IDLEFLAG(&esp8266_handle);              /* 清除UART总线空闲中断 */}
}

等待接收函数

uint8_t esp8266_wait_receive(void)
{if(esp8266_cnt == 0)return ESP8266_ERROR;if(esp8266_cnt == esp8266_cntPre){esp8266_cnt = 0;return ESP8266_EOK;}esp8266_cntPre = esp8266_cnt;return ESP8266_ERROR;
}

发送指令并期待返回值

uint8_t esp8266_send_command(char *cmd,char *res)//发送一个指令去   在指定时间内返回回来 否则没有接收到一个返回值
{uint8_t timeout_out = 250;esp8266_rx_clear(); //防止忍心内的数据影响HAL_UART_Transmit(&esp8266_handle,(uint8_t *)cmd,strlen(cmd),100);//发送命令 cmd在这里是一个uint8_t的数据 长度 阻塞的值//等待while(timeout_out--)//不停的等待{if(esp8266_wait_receive() == ESP8266_EOK){if(strstr((const char*)esp8266_rx_buf, res) != NULL)//判断是否又有期待的字符串return ESP8266_EOK;}delay_ms(10);}return ESP8266_ERROR;//否则接收错误}

接收数据

//接收的函数
void esp8266_receiv_data(void)
{if(esp8266_wait_receive() == ESP8266_EOK){printf("esp8266 recv: %s\r\n", esp8266_rx_buf);esp8266_rx_clear();}
}

发送不定长数据

//发送的函数  不定长数据 参数不固定
void esp8266_send_data(char *fmt, ...)
{va_list ap;uint16_t len;va_start(ap,fmt);vsprintf((char *)esp8266_tx_buf,fmt, ap);va_end(ap);len = strlen((const char*)esp8266_tx_buf);HAL_UART_Transmit(&esp8266_handle, esp8266_tx_buf, len,100);//发送
}

设置a模块是否存在测试

uint8_t esp8266_at_test(void)
{return esp8266_send_command("AT\r\n", "OK");//记得加回车换行才能作为指令发送期待返回值为OK  直接作为返回值发送}

设置模式

uint8_t esp8266_set_mode(uint8_t mode)//s四个函数
{switch(mode){case ESP8266_STA_MODE:return esp8266_send_command("AT+CWMODE=1\r\n","OK");case ESP8266_AP_MODE:return esp8266_send_command("AT+CWMODE=2\r\n","OK");case ESP8266_STA_AP_MODE:return esp8266_send_command("AT+CWMODE=3\r\n","OK");default:return ESP8266_EINVAL;//如果指令不存在}
}

加入AP


uint8_t esp8266_join_ap(char *ssid,char *pwd)//账号密码
{char cmd[64];sprintf(cmd, "AT+CWJAP=\"%s\",\"%s\"\r\n",ssid,pwd);//\"HUAWEIAP-1\",=\"%s\  就指令带引号直接写不行,我们需要如此就不会将“”认为是配对的return esp8266_send_command(cmd,"WIFI GOT IP");;//调用指令函数
}

连接模式

	
uint8_t esp8266_connect_mode(uint8_t mode)//设置单路连接的模式(透传只能用此模式)
{char cmd[64];sprintf(cmd, "AT+CIPMUX=%d\r\n",mode);//作为模式传输进入return esp8266_send_command(cmd,"OK");;//调用指令函数
}
//连接TCP服务器

esp8266_连接模式

uint8_t esp8266_connect_mode(uint8_t mode)//设置单路连接的模式(透传只能用此模式)
{char cmd[64];sprintf(cmd, "AT+CIPMUX=%d\r\n",mode);//作为模式传输进入return esp8266_send_command(cmd,"OK");;//调用指令函数
}

 esp8266连接tpc服务器ip和端口

uint8_t esp8266_connect_tcp_server(char *server_ip,char*server_port)
{char cmd[64];sprintf(cmd, "AT+CIPSTART=\"TCP\",\"%s\",%s\r\n",server_ip,server_port);//作为模式传输进入return esp8266_send_command(cmd,"CONNECT");;//调用指令函数
}

进入透传模式

uint8_t esp8266_enter_unvarnished(void)//发送的模式
{uint8_t ret;//取巧的方式定义一个返回值//两次返回值都等于0,如果有一个不为0就为不为零的情况ret  = esp8266_send_command("AT+CIPMODE=1\r\n","OK");;//调用指令函数ret += esp8266_send_command("AT+CIPSEND\r\n",">");;//调用指令函数if(ret == ESP8266_EOK)return ESP8266_EOK;elsereturn ESP8266_ERROR;		
}

建立tcp服务器

uint8_t esp8266_build_tcp_server(void)
{return esp8266_send_command("AT+CIPSERVER=1\r\n","OK");//发送AT+CIPSEVER=1,期待回复OK
}

初始化esp8266


void esp8266_init(uint32_t baudrate)//所以增加新添加一个
{printf("esp8266初始化开始...\r\n");esp8266_uart_init(baudrate);printf("1. 测试esp8266是否存在\r\n");while(esp8266_at_test())//esp8266_at_test();也是可以的不过一直不成功那就一直等待更为保险delay_ms(500);printf("2. 设置工作模式为AP...\r\n");while(esp8266_set_mode(ESP8266_AP_MODE))delay_ms(500);printf("3. 设置多路链接模式\r\n");while(esp8266_connect_mode(ESP8266_MULTI_CONNECTION))delay_ms(500);printf("4. 建立TCP服务器...\r\n");while(esp8266_build_tcp_server())delay_ms(500);		printf("esp8266初始化完成...\r\n");//esp8266的其他初始化
}

esp8266初始化测试

//测试函数
void esp8266_test(void)
{esp8266_send_data("this is from esp8266\r\n");esp8266_receiv_data();
}

main函数

#include "sys.h"
#include "delay.h"
#include "led.h"
#include "uart1.h"
#include "esp8266.h"
#include "fan.h"
#include "string.h"
int main(void)
{HAL_Init();                         /* 初始化HAL库 */stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟, 72Mhz */led_init();	/* LED初始化 */uart1_init(115200);esp8266_init(115200);fan_init();printf("helloworld!\r\n");char recv_data[ESP8266_RX_BUF_SIZE];//接收传入参数while(1){ esp8266_receive_data(recv_data);//接收到数据tcp服务器传输过来的字符串if(strstr(recv_data, "ON") != NULL)//判断字符串有ON,打开风扇fan1_on();else if(strstr(recv_data, "OFF") != NULL)fan1_off();delay_ms(10);}
}

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

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

相关文章

数据库知识点整理

DDL DDL-数据库操作 show databases ------------ 查看所有数据库 select database(); ----------查看当前数据库 create database 数据库名;---- 创建数据库 use 数据库名; --------------使用数据库 drop database 数据库名;--…

day02_计算机常识丶第一个程序丶注释丶关键字丶标识符

计算机常识 计算机如何存储数据 计算机世界中只有二进制。那么在计算机中存储和运算的所有数据都要转为二进制。包括数字、字符、图片、声音、视频等。 进制 进制也就是进位计数制,是人为定义的带进位的计数方法 实例: // 在java 中 可以使用不同…

[PHP]Undefined index错误只针对数组

1、示例一 <?php $a null; var_dump($a[name]); 结果&#xff1a;无报错 2、示例二 <?php $a []; var_dump($a[name]);结果&#xff1a;报错

【JavaEE初阶】深入理解网络编程—使用UDP协议API实现回显服务器

前言 &#x1f31f;&#x1f31f;本期讲解关于TCP/UDP协议的原理理解~~~ &#x1f308;感兴趣的小伙伴看一看小编主页&#xff1a;GGBondlctrl-CSDN博客 &#x1f525; 你的点赞就是小编不断更新的最大动力 &#x1f386;那么废话不…

JMeter 中两大高级线程组的区别与应用

一、JMeter 中的高级线程组概述 最近群里的测试小伙伴在问在 JMeter 中&#xff0c;“jpgc - Ultimate Thread Group”和“jpgc - Stepping Thread Group 阶梯加压”有哪些区别和实际应用场景有哪些&#xff1f;所以这里也跟大家分享一下 JMeter 作为一款强大的性能测试工具&a…

Java项目-基于Springboot的应急救援物资管理系统项目(源码+说明).zip

作者&#xff1a;计算机学长阿伟 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、ElementUI等&#xff0c;“文末源码”。 开发运行环境 开发语言&#xff1a;Java数据库&#xff1a;MySQL技术&#xff1a;SpringBoot、Vue、Mybaits Plus、ELementUI工具&#xff1a;IDEA/…

基于SpringBoot网上超市的设计与实现(论文+源码)_kaic

摘 要 网络技术和计算机技术发展至今&#xff0c;已经拥有了深厚的理论基础&#xff0c;并在现实中进行了充分运用&#xff0c;尤其是基于计算机运行的软件更是受到各界的关注。加上现在人们已经步入信息时代&#xff0c;所以对于信息的宣传和管理就很关键。因此超市商品销售信…

100 种下划线 / 覆盖层动画 | 终极 CSS(层叠样式表)集合

还在为你的菜单项和链接寻找动画效果而感到疲惫吗&#xff1f; 不用再找了&#xff01;这里列出了 100 多种不同的动画。从简单的到更复杂的&#xff0c;你肯定能找到自己想要的。 无需 SVG&#xff08;可缩放矢量图形&#xff09;&#xff0c;无需 JavaScript&#xff08;脚…

小白也能剪出优秀视频:四大视频剪辑工具推荐!

无论是社交媒体上的短视频分享&#xff0c;还是专业制作的长视频内容&#xff0c;视频剪辑工具都扮演着至关重要的角色。今天&#xff0c;就让我们来探讨几款市面上流行的视频剪辑工具。 福昕视频剪辑 直达链接&#xff1a;www.pdf365.cn/foxit-clip/ 操作教程&#xff1a;立…

使用Diffutoon把视频转换成动漫风格,无需部署,开箱即用

无论是图片动漫转换以及视频动漫转换&#xff0c;我们前期也介绍过相关的模型&#xff0c;但是其模型输出的动漫视频不是有瑕疵&#xff0c;就是动漫效果不唯美&#xff0c;今天介绍一个modelscope社区开源的动漫风格转换模型Diffutoon。 Diffutoon模型接受视频作为输入&#x…

【C语言】循环中断break

在循环使用过程中&#xff0c;可能遇到某些情况需要终止循环。比如按座位查找一位学生&#xff0c;循环查找&#xff0c;找到时可以直接停止。后续的循环将不再执行。 break;只跳出一层循环 例子中的素数判断&#xff0c;查找到根号n停止&#xff1a;一个合数等于两个数的乘积…

新手必须掌握的Linux命令

1.1 常用系统工作命令 echo [linuxprobelocalhost /]$ echo $SHELL /bin/bash 使用$变量的方式提取SHELL的值&#xff0c;并输出到到屏幕上 date [linuxprobelocalhost /]$ date -s "20170901 8:30:00" 将系统时间设置为 reboot ----系统重启命令poweroff --…

JavaWeb Servlet--09深入:注册系统05---动态搜索栏

动态搜索栏 分析&#xff1a;在显示用户信息的表单里有一个下拉框选择用户的信息&#xff0c;一个文本框进行输入&#xff0c;一个按钮就行搜索&#xff0c;在下拉框选择了性别或许姓名的某一个包含字就会返回所有满足的用户。在controller层进行接收选择的搜索条件&#xff0…

Starrocks部署前期准备

前提条件 硬件要求 CPU StarRocks 依靠 AVX2 指令集充分发挥其矢量化能力。因此&#xff0c;在生产环境中&#xff0c;强烈建议您将 StarRocks 部署于 x86 架构 CPU 的服务器上。 您可以在终端中运行以下命令来检查 CPU 是否支持 AVX2 指令集&#xff1a; cat /proc/cpuin…

【深度学习】RNN的简单实现

目录 1.RNNCell 2.RNN 3.RNN_Embedding 1.RNNCell import torchinput_size 4 hidden_size 4 batch_size 1idx2char [e, h, l, o] x_data [1, 0, 2, 2, 3] # 输入&#xff1a;hello y_data [3, 1, 2, 3, 2] # 期待&#xff1a;ohlol# 独热向量 one_hot_lookup [[1, …

如何使用Python合并Excel文件中的多个Sheet

在日常工作中&#xff0c;我们经常会遇到需要处理多个Excel工作表&#xff08;Sheet&#xff09;的情况。比如&#xff0c;一个Excel文件中包含了一个月内每天的数据&#xff0c;每个工作表代表一天。有时候&#xff0c;为了方便分析&#xff0c;我们需要将这些分散的数据合并到…

数据结构单向链表的插入和删除(一)

链表 一、链表结构&#xff1a; &#xff08;物理存储结构上不连续&#xff0c;逻辑上连续&#xff1b;大小不固定&#xff09;二、单链表&#xff1a;三、单项链表的代码实现&#xff1a;四、开发可用的链表&#xff1a;四、单链表的效率分析&#xff1a; 一、链表结构&#x…

Javaweb基础-vue

Vue.js Vue是一套用于构建用户界面的渐进式框架。 起步 引入vue <head><script src"static/js/vue2.6.12.min.js"></script> </head> 创建vue应用 <body> <div id"index"><p>{{message}}</p> </div>…

Vulnhub:Me-and-My-Girlfriend-1

一.环境启动/信息收集 &#xff08;1&#xff09;根据物理地址用nmap的主机发现功能得出IP地址 nmap -P 192.168.138.0/24 //同网段下主机发现得到IP为192.168.138.180&#xff08;2&#xff09;做nmap的目录扫描和端口扫描来发现其他站带以及信息 nmap -p- 192.168.138.180 …

CTF(五)

导言&#xff1a; 本文主要讲述在CTF竞赛中&#xff0c;web类题目easyphp。 靶场链接&#xff1a;攻防世界 (xctf.org.cn) 参考文章原文链接&#xff1a;Web安全攻防世界05 easyphp&#xff08;江苏工匠杯&#xff09;_攻防世界 easyphp-CSDN博客 一&#xff0c;观察页面。…