STM32开发——串口通讯(第2篇)——WIFI(Esp8266)

news2024/11/25 11:49:43

目录

1.ESP8266 作为设备

2.ESP8266作为服务器


 

注意:1.在中断中一般不直接在中断服务函数里处理数据,而是在收到数据后直接丢给队列,再处理数据;
2.在中断服务函数里尽量减少使用延时函数及打印函数。

1.ESP8266 作为设备

1.1项目需求

ESP8266接入同一WIFI局域网下的服务器,向服务器发送数据

ESP-01s出厂波特率正常是115200, 注意:AT指令,控制类都要加回车,数据传输时不加回车。

上电后,串口输出系统开机信息,购买的部分模块可能电压不稳乱码,以 ready 为准。

通过一下命令配置成9600波特率

AT+UART=9600,8,1,0,0

1.设置工作模式

AT+CWMODE=3 //1. 是station(设备)模式 2.是AP(路由)模式 3.是双模
OK

2.以设备模式接入家中路由器配置

AT+CWJAP="TP-LINK_3E30","18650711783" //指令
WIFI CONNECTED //结果
WIFI GOT IP   //结果
OK     //结果

3.连接服务器

AT+CIPSTART="TCP","192.168.0.113",8888 //指令,注意双引号逗号都要半角(英文)输入
CONNECT  //结果:成功
OK    //结果:成功

4.开启透传模式

AT+CIPMODE=1  //开启透传模式
Response :OK

5.发送数据

AT+CIPSEND //带回车
Response: >  //这个时候随意发送接收数据咯

CubeMX设置

打开串口1、及其中断;打开串口2;打开GPIO8-led;中断优先级降低;

函数代码

#include "string.h"
#include "stdio.h"

uint8_t buf=0;
unsigned char ch[200] ;
uint16_t UART1_RX_STA=0;

int LAN_mark=0;
int other_land_mark=0;
int suceed_mark=0;
int error=1;

char LAN_connect[]         ="AT+CWJAP=\"yangkai\",\"12345678\"\r\n";
char TCP_server_connect[]  ="AT+CIPSTART=\"TCP\",\"172.20.10.5\",80\r\n";
char touchuan_start[]      ="AT+CIPMODE=1\r\n";
char datatransport_start[] ="AT+CIPSEND\r\n";
char reset[]               ="AT+RST\r\n";
char my_word[]             ="hello world\r\n";

int fputc(int ch1,FILE *f)
{
	uint8_t temp[1]={ch1};  //必须要用uint8_t承接,将int char变为uint8_t
	
	HAL_UART_Transmit(&huart1, temp, 1, 0xffff);
	return ch1;
}


//重写串口中断服务函数——————串口接受到的数据
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
	//如果来自串口1的数捿
	if(huart->Instance==USART1){
		//如果没有接收完成
		if((UART1_RX_STA & 0x8000)==0){
			//如果已经收到迿0x0d回车
			if(UART1_RX_STA & 0x4000){
				//如果这个数是0x0a换行
				if(buf==0x0a){
					//,接收完成,弿始下丿次接政
					UART1_RX_STA|=0x8000;
					//可以用ch匹配数据了
					//HAL_UART_Transmit(&huart2, ch, strlen(ch), 0xffff);
					// 这里用来测试可以,但是不能用串口2来打印CH,影响串口接收函数,影响时序。
					
					if(!strcmp(ch,"WIFI GOT IP")){						//收到wifi got ip
						LAN_mark=1;
					}
					if(!strcmp(ch,"OK")){						//收到OK
						other_land_mark=1;
					}
					if(!strcmp(ch,"LED")){						//收到led翻转LED
						HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_8);
					}
					// 查看是否收到 FAIL
					if(!strcmp(ch, "FAIL"))
					{
						int i = 0;
						for (i = 0; i < 5; i++)
						{
							HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_8);
							HAL_Delay(1000);
						}
						printf(reset);
					}
					
					
					memset(ch,'\0',200);
					UART1_RX_STA=0;
				//如果这个数不昿0x0a换行
				}else{
					//接收失败,数据清穿
					UART1_RX_STA=0;
					//memset(ch,0,200);
				}
		
			//如果没有收到迿0x0d
			}else{
				//如果现在这个数是0x0d回车
				if(buf==0x0d){
					//状濁为标记改变为收到了0x0d
					UART1_RX_STA|=0x4000;
			//如果现在这个数不昿0x0d换行
				}else{
				//进行接收进入ch里面
					ch[UART1_RX_STA&0x3fff]=buf;
					UART1_RX_STA++;
					
					if(UART1_RX_STA>199)
						UART1_RX_STA = 0;
				}
			}
		}
		//重新弿启串口中断接政
		HAL_UART_Receive_IT(&huart1, &buf,1);
	}
}


main函数中代码

	HAL_NVIC_SetPriority(SysTick_IRQn,0,0);
	//打开串口1接收中断  接收到的字符存在buf里,有一个字? 
	HAL_UART_Receive_IT(&huart1, &buf, 1);


	HAL_UART_Transmit(&huart2, "let's go\r\n", strlen("let's go\r\n"), 100);
	

	
		printf(LAN_connect);
		//printf(LAN_connect);	   //发送联网指令    "yangkai\",\"12345678\"\r\n";
		//while(!LAN_mark) HAL_Delay(50);   //接收到 wifi  GOTIP执行下一步LAN_mark变为1
		while(!other_land_mark) HAL_Delay(50);   //接收到OK执行下一步other_land_mark 变为1	
		HAL_UART_Transmit(&huart2, (uint8_t *)"111", strlen("111"), 100);	 //连上就111
		other_land_mark=0;       //other_land_mark接收到OK执行下一步
		
		printf(TCP_server_connect);			//发送"TCP\",\"172.20.10.5\",80\r\n";
		while(!other_land_mark) HAL_Delay(50); //接收到OK执行下一步other_land_mark 变为1
		other_land_mark=0;       //other_land_mark接收到OK执行下一步
 
		printf(touchuan_start);		//AT+CIPMODE=1\r\n";
		while(!other_land_mark) HAL_Delay(50); //other_land_mark接收到OK执行下一步
		other_land_mark=0;   //重新置0


		printf(datatransport_start);	   //"AT+CIPSEND\r\n"
		while(!other_land_mark) HAL_Delay(50); //other_land_mark接收到OK执行下一步


	
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */

  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
		//如果sta高位丿1 ==受到带换行的数据 
		HAL_UART_Transmit(&huart2, (uint8_t *)"已连接服务器\r\n", strlen("已连接服务器\r\n"), 100);	 //连上就111
		printf("hello yk\r\n");
		
		//printf("hello world.\r\n");
		HAL_Delay(3000);
  }


2.ESP8266作为服务器

步骤:

//0重启
+STA_CONNECTED:"c0:a5:dd:54:0c:ef"
+DIST_STA_IP:"c0:a5:dd:54:0c:ef","192.168.4.2"
WIFI DISCONNECT
隔5秒后下一个
//1 配置成双模
AT+CWMODE=2
Response :OK
//2 使能多链接
AT+CIPMUX=1
Response :OK
//3 建立TCPServer
AT+CIPSERVER=1,8888 // default port = 333
Response :OK
 
//然后TCP client去连接服务器1,8888
Response :0,CONNECT

while(1){ 
    //4 发送数据设置
    AT+CIPSEND=0,4 // 发送4个字节在连接0通道上
    //5 发送数据
    "hello yk"
    Response :SEND OK
}

//断开连接
AT+CIPCLOSE=0
Response :0, CLOSED OK

CubeMX是同样上的设置

函数代码如下

#include "string.h"
#include "stdio.h"

uint8_t buf=0;
unsigned char ch[200] ;
uint16_t UART1_RX_STA=0;

int TCP_mark=0;
int other_land_mark=0;

char mode_AP[]             ="AT+CWMODE=2\r\n";
char mutiple_connect[]     ="AT+CIPMUX=1\r\n";
char TCPserver[]		   ="AT+CIPSERVER=1,8888\r\n";
char data_trans[]		   ="AT+CIPSEND=0,11\r\n";
char reset[]               ="AT+RST\r\n";
char my_word[]             ="hello world";

int fputc(int ch1,FILE *f)
{
	uint8_t temp[1]={ch1};  //必须要用uint8_t承接,将int char变为uint8_t
	
	HAL_UART_Transmit(&huart1, temp, 1, 0xffff);
	return ch1;
}


//重写串口中断服务函数——————串口接受到的数据
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
	//如果来自串口1的数捿
	if(huart->Instance==USART1){
		//如果没有接收完成
		if((UART1_RX_STA & 0x8000)==0){
			//如果已经收到迿0x0d回车
			if(UART1_RX_STA & 0x4000){
				//如果这个数是0x0a换行
				if(buf==0x0a){
					//,接收完成,弿始下丿次接政
					UART1_RX_STA|=0x8000;
					//可以用ch匹配数据了
					//HAL_UART_Transmit(&huart2, ch, strlen(ch), 0xffff);
					// 这里用来测试可以,但是不能用串口2来打印CH,影响串口接收函数,影响时序。
					
					if(!strcmp(ch,"0,CONNECT")){						//收到0,CONNECT
						TCP_mark=1;
					}
					if(!strcmp(ch,"OK")){						//收到OK
						other_land_mark=1;
					}
					if(!strcmp(ch,"LED")){						//收到led翻转LED
						HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_8);
					}
					// 查看是否收到 FAIL
					if(!strcmp(ch, "ERROR"))
					{
						int i = 0;
						for (i = 0; i < 5; i++)
						{
							HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_8);
							HAL_Delay(1000);
						}
						printf(reset);
					}
					
					
					memset(ch,'\0',200);
					UART1_RX_STA=0;
				//如果这个数不昿0x0a换行
				}else{
					//接收失败,数据清穿
					UART1_RX_STA=0;
					//memset(ch,0,200);
				}
		
			//如果没有收到迿0x0d
			}else{
				//如果现在这个数是0x0d回车
				if(buf==0x0d){
					//状濁为标记改变为收到了0x0d
					UART1_RX_STA|=0x4000;
			//如果现在这个数不昿0x0d换行
				}else{
				//进行接收进入ch里面
					ch[UART1_RX_STA&0x3fff]=buf;
					UART1_RX_STA++;
					
					if(UART1_RX_STA>199)
						UART1_RX_STA = 0;
				}
			}
		}
		//重新弿启串口中断接政
		HAL_UART_Receive_IT(&huart1, &buf,1);
	}
}

//main函数中代码
	HAL_NVIC_SetPriority(SysTick_IRQn,0,0);
	//打开串口1接收中断  接收到的字符存在buf里,有一个字? 
	HAL_UART_Receive_IT(&huart1, &buf, 1);


	HAL_UART_Transmit(&huart2, "let's go\r\n", strlen("let's go\r\n"), 100);
	
		printf(mode_AP);    //设置路由器模式
		while(!other_land_mark) HAL_Delay(50);   //接收到OK执行下一步other_land_mark 变为1	
		HAL_UART_Transmit(&huart2, (uint8_t *)"111", strlen("111"), 100);	 //连上就111
		other_land_mark=0;       //other_land_mark接收到OK执行下一步
		
		printf(mutiple_connect);			//使能多连接
		while(!other_land_mark) HAL_Delay(50); //接收到OK执行下一步other_land_mark 变为1
		HAL_UART_Transmit(&huart2, (uint8_t *)"222", strlen("222"), 100);	 //连上就111
		other_land_mark=0;       //other_land_mark接收到OK执行下一步
 
		printf(TCPserver);		//建立TCP服务器
		while(!TCP_mark) HAL_Delay(50); //TCP_mark接收到0,CONNECT执行下一步
		HAL_UART_Transmit(&huart2, (uint8_t *)"333", strlen("333"), 100);	 //连上就111
		TCP_mark=0;   //重新置0


		printf(data_trans);	   //设置数据传输端口和字数
		while(!other_land_mark) HAL_Delay(50); //other_land_mark接收到OK执行下一步
		
		HAL_UART_Transmit(&huart2, (uint8_t *)"已建立服务器\r\n", strlen("已建立服务器\r\n"), 100);	 //连上就111


	
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */

  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */	

		HAL_UART_Transmit(&huart2, (uint8_t *)"hello yk\r\n", strlen("hello yk\r\n"), 100);	
		printf(data_trans);
		HAL_Delay(2000);
		//发送数据
		printf(my_word);
		HAL_Delay(2000);
		//data2=SBUF;   //接受外部数据后产生中断	 进入interrupt 4

  }
  /* USER CODE END 3 */
}

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

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

相关文章

mongo副本集的一些操作

开启副本集 修改配置文件/etc/mongod.conf replication:replSetName: main重启mongod相关服务systemctl restart mongod 注意:每个在副本集中的成员&#xff0c;无论主副replSetName都一样&#xff0c;表示一个副本集的名称 如果添加的节点的replSetName和主节点不一致&…

退出卸载企业奇安信360

一般退出&卸载企业奇安信需要密码&#xff0c;然后我们又都不知道密码是多少的情况下怎么退出奇安信呢 1.打开奇安信的设置 2.找到 "防护中心"--"自我保护" 然后点击确定 3.找到奇安信的安装目录 找到"D:\奇安信\360Safe\EntClient\conf"下面…

python带你获取TripAdvisor旅游景点的真实评价

前言 嗨喽&#xff0c;大家好呀~这里是爱看美女的茜茜呐 猫途鹰&#xff08;TripAdvisor&#xff09;是一个旅游点评网站&#xff0c; 如果您想要爬取该网站的数据&#xff0c;需要了解该网站的访问规则和爬取限制。 所使用软件工具&#xff1a; python 3.8 运行代码 pycha…

【PTA】温故知新模拟题

目录 L1-2 日期格式化 输入格式&#xff1a; 输出格式&#xff1a; 输入样例&#xff1a; 输出样例&#xff1a; 代码&#xff1a; L1-4 心理阴影面积 输入格式&#xff1a; 输出格式&#xff1a; 输入样例&#xff1a; 输出样例&#xff1a; 代码&#xff1a; 7-3…

『论文精读』Vision Transformer(VIT)论文解读

『论文精读』Vision Transformer(VIT)论文解读 文章目录 一. 简介二. 模型架构2.1. 关于image presentation2.2. 关于positional encoding2.3. 关于CNNTransformer2.4. 关于输入图片大小 三. 实验部分3.1. 数据集3.2. 模型及变体3.3. 实验结果3.4. 模型可视化 参考文献 论文下…

CSS3_03:各种卡券优惠券模板制作,开箱即用,学得会,用得着

本文首发于微信公众号&#xff1a;布依前端 微信号&#xff1a;qny-1009 转载请注明出处 原创不易&#xff0c;觉得有用的话&#xff0c;多转发点赞支持 作为前端开发者&#xff0c;经常碰到不规则元素需求&#xff0c;尤其是购物类的优惠券&#xff0c;元素长相怪异&#xff0…

looks调色插件 Red Giant Magic Bullet Looks for Mac

Magic Bullet Looks for Mac版是一款looks调色插件&#xff0c;提供强大的外观和色彩校正功能&#xff0c;无论是对初学者还是影视专业制作人员&#xff0c;从冷酷惊艳的的动作场面到红色&#xff0c;暖色的浪漫色调&#xff0c;都可以帮助快速的完成&#xff0c;满足用户的所有…

LabVIEW开发基于Web数字图像处理

LabVIEW开发基于Web数字图像处理 数字图像处理已在各个领域找到了应用&#xff0c;并已成为一个高度活跃的研究领域。实际实施和实验在教育和研究活动中起着不可或缺的作用。为了方便快捷地实施数字图像处理操作&#xff0c;设计了一个先进的基于Web的数字图像处理虚拟实验室&…

vue3中引入tailwingcss

1、安装依赖 cnpm i -D tailwindcss postcss autoprefixer 2、安装完成后&#xff0c;创建tailwind.config.js 和 postcss.config.js配置文件&#xff0c;继续再控制台输入命令如下&#xff1a; npx tailwindcss init -P 3、修改tailwind.config.js content: ["./ind…

<Linux> 进程

文章目录 进程基本概念描述进程-PCBtask_struct-PCB的一种task_ struct内容分类 组织进程查看进程通过系统调用获取进程标示符fork创建子进程进程状态操作系统原理进程状态linux进程状态 优先级基本概念查看系统进程PRI and NI查看进程优先级的命令其他概念 环境变量基本概念常…

又双叒反转?美国院士复现室温超导!

室温超导又双叒反转&#xff1f; 没错&#xff0c;就是今年3月差点掀翻物理界的“21℃室温超导新材料”成果&#xff0c;来自美国罗彻斯特大学Ranga Dias团队。 尽管存在置疑&#xff0c;目前原论文仍然在《自然》期刊上可以查阅、并没有撤稿。 当时国内外很多团队都立刻尝试复…

程序员常用速查表总览

程序员常用速查表总览 文章目录 程序员常用速查表总览linux命令速查表vim命令速查表git命令速查表c知识速查表matplotlib 速查表数据科学方面的速查表-机器学习、概率论等 在使用linux、vims时命令老是忘记&#xff0c;在网上一番翻找&#xff0c;总结了一下文章&#xff0c;特…

如何使用 Python 自动购买 Interpark 演唱会门票 ?

前言 大家早好、午好、晚好吖 ❤ ~欢迎光临本文章 Interpark是韩国的一家知名网上购物网站&#xff0c;成立于1996年。 它是韩国最早开展网上零售业务的公司之一&#xff0c;提供各种产品&#xff0c;包括各种书籍、电子产品、珠宝、户外用品、食品和服装等等。 Interpark还…

String类(Java)

文章目录 1. 介绍2. 分析3. 方法3.1 String()方法3.2 equal()方法3.3 compareTo()方法3.4 contains()方法3.5 toCharArray()方法3.6 trim()方法3.7 valueOf()方法 1. 介绍 A. 类介绍&#xff1a;   Java将字符串看作对象(不同于c语言, c语言直接使用字符数组来表示字符串)&…

新型的类型转换

C 方式的强制类型转换 (Type)Expression Type(Expression) C 方式强制类型转换存在的问题 过于粗暴 任意类型之间都可以进行转换&#xff0c;编译器很难判断其正确性 难于定位 在源码中无法快速定位所有使用强制类型转换的语句 问题 强制类型转换在实际工程中是很难完全…

炫龙笔记本毁灭者dc更换CPU记录

文章目录 前言一、确认cpu和主板芯片型号二、搜索可更换的cpu三 、拆机更换cpu四 、蜿蜒曲折的咨询之路总结 前言 本来只想给老笔记本换个512g固态&#xff0c;原先的128g太小了&#xff0c;原装的是一个128g sata接口固态 发现我这台炫龙毁灭者dc居然还能换cpu&#xff0c;除…

回归预测 | MATLAB实现KNN(K近邻)多输入单输出回归预测

回归预测 | MATLAB实现KNN(K近邻)多输入单输出回归预测 目录 回归预测 | MATLAB实现KNN(K近邻)多输入单输出回归预测效果一览基本介绍模型回归程序设计学习总结参考资料效果一览

技术旋风!快速采集建模装备、重建大师6.1版、大面积实景三维轻量化技术...

6月20日 14:30 大势智慧 海量数据轻量化技术与新品夏季发布会 新产品&#xff1a;大势速影&#xff0c;让实景三维建模“快”人一步 实景三维模型应用广度和深度日益扩大&#xff0c;传统测绘技术体系和生产体系正经历数字化变革。 传统激光点云数据量大、空间点离散、缺少…

Video-LLaMA 开源,大语言模型也能读懂视频了!

出品人&#xff1a;Towhee 技术团队 作者&#xff1a;张晨 架构 Video-LLaMA 旨在使冻结的 LLM 能够理解视频中的视觉和听觉内容。如图所示&#xff0c;本文设计了两个分支&#xff0c;即视觉语言分支和音频语言分支&#xff0c;分别将视频帧和音频信号转换为与 LLM 的文本输入…

首次使用云服务器搭建网站(一)

这是本人第一次使用云服务器搭建网站。 一、挑选云服务器 1、我此次使用的是腾讯云赠送的免费云服务器。 2、购买后&#xff0c;进入腾讯云总控制台。 3、点击云服务、云服务器、实例&#xff0c;进入云服务器的实例界面 4、大致就能看到这样一个界面 二、重装系统 腾讯云允许系…