stm32学习:hal库usart+esp8266+tcp+onenet+可以远程监督家里情况

news2024/12/25 10:12:14

目录

准备材料

步骤

stm32f103c8t6

在stm32clube里创建项目

先配置调试接口SYS(博主用的是stlink,选的是SW),配置外部时钟源RCC,总线时钟频数72

配置串口(波特率为115200)

​编辑 看各自需要配置不同硬件的io口

esp8266

代码

订阅串口数据,在usart.h里,可以更改

先配置usart2中断函数,在main.c里

在main函数里配置中断优先级,和使能串口中断

再写按顺序发送AT指令来初始化esp8266函数,在esp8266.c里

我们在发送指令的同时,要判断它是否成功配置指令,在串口中断函数里有判断,来改变标志位,获取标志位来判断是否成功配置指令

构建发送到onenet的数据,最后的数据要json格式

发送onenet数据

main主函数

完整文件在标题下,博主的加了一些其他文件,你们要加到自己的文件里就把esp8266.c和esp8266.c拉到你们的项目中调用就好 


准备材料

  1. stm32f103c8t6
  2. esp8266
  3. 各种器件,例如温湿度,烟雾,灯光,按钮什么都可以(只是让我们有信息可以传,没有就传数字来测试)
  4. onenet的配置请看前面发的文章物联网平台:网络调试助手+HTTP+上传数据到onenet-CSDN博客

步骤

stm32f103c8t6

在stm32clube里创建项目

先配置调试接口SYS(博主用的是stlink,选的是SW),配置外部时钟源RCC,总线时钟频数72
配置串口(波特率为115200)

 看各自需要配置不同硬件的io口

esp8266

大家可以先学习一下AT指令,这里简单讲一下案例要用的(下面返回值空的是空行)

需要先配置好波特率,esp8266接线也是用ttl,用串口调试助手,选择厂家初始的波特率,然后就可以调试esp8266了 ,修改波特率指令是(记住勾选新行)

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

代码

我们要用stm32的usart2来发送AT指令来控制esp8266来连接网络

订阅串口数据,在usart.h里,可以更改

//串口2
//串口接收缓存(1字节)
uint8_t buf1=0;
//定义最大接收字节数 200,可根据需求调整
#define UART2_REC_LEN 200
// 接收缓冲, 串口接收到的数据放在这个数组里,最大UART2_REC_LEN个字节
uint8_t UART2_RX_Buffer[UART2_REC_LEN];
//  接收状态bit15,      接收完成标志,bit14,      接收到0x0d,bit13~0,    接收到的有效字节数目
uint16_t UART2_RX_STA=0;

先配置usart2中断函数,在main.c里

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
	// 判断中断是由哪个串口触发的
	if(huart->Instance == USART2)
	{
		// 判断接收是否完成(UART1_RX_STA bit15 位是否为1)
		if((UART2_RX_STA & 0x8000) == 0)
		{
			// 如果已经收到了 0x0d (回车),
			if(UART2_RX_STA & 0x4000)
			{
				// 则接着判断是否收到 0x0a (换行)
				if(buf1 == 0x0a)
				{
					// 如果 0x0a 和 0x0d 都收到,则将 bit15 位置为1
					UART2_RX_STA |= 0x8000;

					// 查看是否收到 WIFI GOT IP
					if(!strcmp((char *)UART2_RX_Buffer, "WIFI GOT IP"))
						AT_Connect_Net_Flag = 1;
					
					// 查看是否收到 OK
					if(!strcmp((char *)UART2_RX_Buffer, "OK"))
						AT_OK_Flag = 1;
					
					if(!strcmp((char *)UART2_RX_Buffer, ">"))
						fuhao_Connect_Flag = 1;
					
					// 查看是否收到 FAIL
					if(!strcmp((char *)UART2_RX_Buffer, "CONNECT"))
						Client_Connect_Flag	= 1;
					
					if(!strcmp((char *)UART2_RX_Buffer, "{\"errno\":0,\"error\":\"succ\""))
						succ_Flag	= 1;
					
					memset(UART2_RX_Buffer, 0, UART2_REC_LEN);
					UART2_RX_STA = 0;
				}
				else
					// 否则认为接收错误,重新开始
					UART2_RX_STA = 0;
			}
			else	// 如果没有收到了 0x0d (回车)
			{
				//则先判断收到的这个字符是否是 0x0d (回车)
				if(buf1 == 0x0d)
				{
					// 是的话则将 bit14 位置为1
					UART2_RX_STA |= 0x4000;
				}
				else
				{
					// 否则将接收到的数据保存在缓存数组里
					UART2_RX_Buffer[UART2_RX_STA & 0X3FFF] = buf1;
					UART2_RX_STA++;
					
					// 如果接收数据大于UART1_REC_LEN(200字节),则重新开始接收
					if(UART2_RX_STA > UART2_REC_LEN - 1)
						UART2_RX_STA = 0;
				}
			}
		}
		// 重新开启中断
		HAL_UART_Receive_IT(&huart2, &buf1, 1);
	}
}

在main函数里配置中断优先级,和使能串口中断


	HAL_NVIC_SetPriority(SysTick_IRQn,0,0);//设置特定中断的优先级
	HAL_UART_Receive_IT(&huart2, &buf1, 1);

再写按顺序发送AT指令来初始化esp8266函数,在esp8266.c里


#define ESP8266_WIFI_INFO		"AT+CWJAP=\"Reds\",\"23333334\"\r\n"

#define ESP8266_ONENET_INFO		"AT+CIPSTART=\"TCP\",\"183.230.40.33\",80\r\n"
//初始化ESP8266
void ESP8266_Init(void)
{
	
	while(ESP8266_SendCmd("AT\r\n", 1))
		HAL_Delay(1500);
		HAL_Delay(2000);
	
	while(ESP8266_SendCmd("AT+CWMODE=1\r\n", 1))
		HAL_Delay(1500);
		HAL_Delay(2000);
	
	while(ESP8266_SendCmd(ESP8266_WIFI_INFO, 2))
		HAL_Delay(1500);
		HAL_Delay(2000);
	
	while(ESP8266_SendCmd(ESP8266_ONENET_INFO, 3))
		HAL_Delay(1500);
		HAL_Delay(2000);

}

我们在发送指令的同时,要判断它是否成功配置指令,在串口中断函数里有判断,来改变标志位,获取标志位来判断是否成功配置指令

int AT_OK_Flag = 0;				//OK返回值的标志位
int AT_Connect_Net_Flag = 0;		//WIFI GOT IP返回值的标志位
int Client_Connect_Flag = 0;    //连接tcp服务端标志位
int fuhao_Connect_Flag = 0;    //进入发送数据标志位
int succ_Flag = 0;            //发送成功标志位



//发送命令  cmd 命令  res要选择什么标志位
int ESP8266_SendCmd(char *cmd,int res)
{
	
	unsigned char timeOut = 200;
	
	HAL_UART_Transmit(&huart2, (unsigned char *)cmd, strlen((const char *)cmd), 0xffff);
	
		if(res == 1)
		{
			while(!AT_OK_Flag&&timeOut--) HAL_Delay(50);
			if(AT_OK_Flag)
			{
				AT_OK_Flag = 0;
				return 0;
			}
		}
		else if(res == 2)
		{
			while( ( !AT_OK_Flag || !AT_Connect_Net_Flag ) && timeOut--) HAL_Delay(50);
			if(fuhao_Connect_Flag||AT_OK_Flag)
			{
				AT_OK_Flag = 0;
				AT_Connect_Net_Flag = 0;
				return 0;
			}
		}
		else if(res == 3)
		{
			while(!Client_Connect_Flag&&timeOut--)  HAL_Delay(50);
			if(Client_Connect_Flag)
			{
				Client_Connect_Flag = 0;
				return 0;
			}
		}
		else if(res == 4)
		{
			while( ( !AT_OK_Flag || !fuhao_Connect_Flag ) && timeOut--) HAL_Delay(50);
			if(fuhao_Connect_Flag||AT_OK_Flag)
			{
				AT_OK_Flag = 0;
				fuhao_Connect_Flag = 0;
				return 0;
			}
		}
	 
	return 1;

}

构建发送到onenet的数据,最后的数据要json格式

//设备id
#define DEVID	"1026566033"
//密钥
#define APIKEY	"C7elqJfUjB=ynk=fpdQVJZ7yTfY="

void OneNet_FillBuf(char *buf)
{
	
	char data[24];
	char json[128];
	
	memset(data, 0, sizeof(data));
	memset(json, 0, sizeof(json));
	
	strcpy(json, "{");
	
	memset(data, 0, sizeof(data));
	sprintf(data, "\"Test1\":123,");
	strcat(json, data);
	
	memset(data, 0, sizeof(data));
	sprintf(data, "\"Test2\":789,");
	strcat(json, data);
	
	strcat(json, "}");
	
	sprintf(buf, "POST /devices/%s/datapoints?type=3 HTTP/1.1\r\napi-key:%s\r\nHost:api.heclouds.com\r\nConnection:close\r\n"
					"Content-Length:%d\r\n\r\n",
	
					DEVID, APIKEY, strlen(json));
					
	strcat(buf, json);

}

发送onenet数据

void OneNet_SendData(void)
{
	char buf[256];
	
	memset(buf, 0, sizeof(buf));
	
	OneNet_FillBuf(buf);								
	
	ESP8266_SendData((unsigned char *)buf, strlen(buf));
	
}

main主函数

int main(void)
{
  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_TIM2_Init();
  MX_USART2_UART_Init();
  MX_TIM4_Init();
  /* USER CODE BEGIN 2 */
  HAL_NVIC_SetPriority(SysTick_IRQn,0,0);//设置特定中断的优先级
  HAL_UART_Receive_IT(&huart2, &buf1, 1);
	
  int i=0;
  int flag=0;
	
  ESP8266_Init();
  OneNet_SendData();
  
  
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
	i++;
	if(i == 20)
	{	
	  i=0;
		if(flag==0)
		{
			open_led();
			flag =1;
		}
		else
		{
			close_led();
			flag =0;
		}
		HAL_Delay(1000);
	}
  }
  /* USER CODE END 3 */
}

完整文件在标题下,博主的加了一些其他文件,你们要加到自己的文件里就把esp8266.c和esp8266.c拉到你们的项目中调用就好 

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

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

相关文章

input 获取焦点后样式的修改

一、实现目标 1.没有获取焦点时样子 2.获取焦点时 代码&#xff1a; <input class"input"placeholder"请输入关键字" input"loadNode" />css .input {border-radius: 14px;border:1px solid #e4e4e4;margin: 5px;margin-top: 10px;wi…

编程应用实际场景:台球厅怎么样用电脑给客人计时,台球计时收费系统操作教程

一、前言 准确控制顾客在店内游玩的时间&#xff0c;从而控制店内的各项成本&#xff0c;并提升店内的客流量。在顾客享受计时项目的时候&#xff0c;可以同时添加其他食物消费&#xff0c;并将单据合并统一结账。软件中的会员功能可以为客户办理会员可以使用灯控器控灯&#…

【LeetCode刷题笔记(1)】【Python】【两数之和】【简单】

LeetCode: 两数之和 题目描述 给定一个整数数组 nums 和一个整数目标值 target&#xff0c;找出数组中和为目标值 target 的两个整数&#xff0c;并返回它们的数组下标。 输入&#xff1a;一个整数数组 nums 和一个整数目标值 target输出&#xff1a;返回一个包含两个整数下…

【大数据】详解 AVRO 格式

详解 AVRO 格式 1.Avro 介绍2.schema2.1 原始类型2.2 复杂类型2.2.1 Records2.2.2 Enums2.2.3 Arrays2.2.4 Maps2.2.5 Unions2.2.6 Fixed 3.Avro 的文件存储格式3.1 数据编码3.1.1 原始类型3.1.2 复杂类型 3.2 存储格式3.3 存储格式 4.小结 1.Avro 介绍 Apache Avro 是 Hadoop…

阿里云SMC迁移RedHat/CentOS 5 内核升级

阿里云SMC迁移RedHat/CentOS 5 内核升级 1. 起因 服务器需要迁移上阿里云,有几台服务器用的是Redhat 5.x,在使用SMC进行迁移时出现以下报错. [2023-12-13 09:50:55] [Error] Check System Info Failed, codeS16_111, msgGet OS Info Failed: [error] grub is too old for C…

Python——数据库操作

目录 &#xff08;1&#xff09;安装Flask-SQLAlchemy &#xff08;2&#xff09;使用Flask-SQLAlchemy操作数据库 &#xff08;3&#xff09;连接数据库 •创建数据表 •增加数据 •查询数据 •更新数据 •删除数据 Flask-SQLAlchemy是Flask中用于操作关系型数据库的扩展…

Linux中使用podman管理容器

本章主要介绍使用podman管理容器 了解什么是容器&#xff0c;容器和镜像的关系安装和配置podman拉取和删除镜像给镜像打标签导出和导入镜像创建和删除镜像数据卷的使用管理容器的命令使用普通用户管理容器 对于初学者来说&#xff0c;不太容易理解什么是容器&#xff0c;这里…

【Azure 架构师学习笔记】- Azure Databricks (3) - 再次认识DataBricks

本文属于【Azure 架构师学习笔记】系列。 本文属于【Azure Databricks】系列。 接上文 【Azure 架构师学习笔记】- Azure Databricks (2) -集群 前言 在对Databricks有了初步了解之后&#xff0c;如果要深入使用则需要对其进行更深层次的了解。 Databricks ADB 是一个统一的…

C# Winfrm 编写一个天气查看助手

#前言# 最近这个北方的天气啊经常下雪&#xff0c;让我想起来我上学时候写的那个天气预报小功能了&#xff0c;今天又复现了一下&#xff0c;哈哈哈&#xff0c;大家当个乐子看哈&#xff01; 1.创建项目 2.添加引用 上图所示&#xff0c;下载所需天气预报标识&#xff0c;网站…

服务器漏洞防护措施有哪些?

随着互联网的普及和发展&#xff0c;服务器在各个领域的应用越来越广泛&#xff0c;同时也面临着越来越多的安全威胁。服务器漏洞一旦被攻击者利用&#xff0c;不仅可能导致数据泄露、系统崩溃等严重后果&#xff0c;还可能影响到企业的正常运营和声誉。因此&#xff0c;加强服…

jmeter简单压测kafka

前言 这也是一个笔记&#xff0c;就是计划用jmeter做性能测试&#xff0c;但是这里是只要将数据放到kafka的topic里&#xff0c;后面查看下游业务处理能力。 一、方案 因为只要实现数据放到kafka&#xff0c;参考了下博友的方案&#xff0c;可行。 二、方案验证 详细过程就不…

DevExpress WinForms Pivot Grid组件,一个类似Excel的数据透视表控件(二)

界面控件DevExpress WinForms的Pivot Grid组件是一个类似Excel的数据透视表控件&#xff0c;用于多维(OLAP)数据分析和跨选项卡报表。在上文中&#xff08;点击这里回顾>>&#xff09;我们介绍了DevExpress WinForms Pivot Grid组件的性能、分析服务、数据塑造能力等&…

23种策略模式之策略模式

23种策略模式之策略模式 文章目录 23种策略模式之策略模式前言优缺点使用场景角色定义UML模拟示例小结 前言 在软件开发中&#xff0c;设计模式是为了解决常见问题而提供的一套可重用的解决方案。策略模式&#xff08;Strategy Pattern&#xff09;是其中一种常见的设计模式&a…

Mac配置环境变量不生效

Mac配置环境变量不生效 Mac中的环境变量介绍 Mac系统的环境变量&#xff0c;加载顺序为&#xff1a; /etc/profile /etc/paths ~/.bash_profile ~/.bash_login ~/.profile ~/.bashrc 当然/etc/profile和/etc/paths是系统级别的&#xff0c;系统启动就会加载&#xff0c;后面…

Linux驱动入门 —— 利用引脚号操作GPIO进行LED点灯

目录 一、字符设备驱动程序框架 编写驱动程序的步骤&#xff1a; 对于 LED 驱动&#xff0c;我们想要什么样的接口&#xff1f; LED 驱动能支持多个板子的基础&#xff1a;分层思想 二、Linux驱动如何指向一个GPIO 直接通过寄存器来操作GPIO 利用引脚号操作GPIO IMX6UL…

基于自动化脚本批量上传依赖到nexus内网私服

前言 因为某些原因某些企业希望私服是不能连接外网的&#xff0c;所以需要某些开源依赖需要我们手动导入到nexus中&#xff0c;尽管nexus为我们提供了web页面。但是一个个手动导入显然是一个庞大的工程。 对此我们就不妨基于脚本的方式实现这一过程。 预期效果 笔者本地仓库…

【Java】网络编程-UDP回响服务器客户端简单代码编写

这一篇文章我们将讲述网络编程中UDP服务器客户端的编程代码 1、前置知识 UDP协议全称是用户数据报协议&#xff0c;在网络中它与TCP协议一样用于处理数据包&#xff0c;是一种无连接的协议。 UDP的特点有&#xff1a;无连接、尽最大努力交付、面向报文、没有拥塞控制 本文讲…

为什么FPGA是战略芯片?

FPGA&#xff08;Field Programmable Gate Array&#xff09;是在PAL&#xff08;可编程阵列逻辑&#xff09;、GAL&#xff08;通用阵列逻辑&#xff09;等可编程器件的基础上进一步发展的产物&#xff0c;它是作为一种半定制电路而出现的&#xff0c;既解决了定制电路的不足&…

提升数据采集技能:用 Axios 实现的 Twitter 视频下载器全面解析

引入 在当今数据驱动的时代&#xff0c;高效的数据采集是实现成功数据科学项目的关键。数据采集不仅涉及到数据的获取&#xff0c;还包括数据的清洗、转换、存储和分析等多个环节。Twitter作为全球最大的社交媒体平台之一&#xff0c;蕴含着丰富的信息和海量的多媒体内容&…

计算机网络:数据链路层(网桥)

带你速通计算机网络期末 目录 一、冲突域和广播域 二、网桥介绍 三、网桥分类—―透明网桥 四、网桥分类―—源路由网桥 五、多接口网桥―—以太网交换机 总结 一、冲突域和广播域 冲突域:在同一个冲突域中的每一个节点都能收到所有被发送的帧。简单的说就是同一时间内只…