基于STM32的homeassistant(采用FreeRTOS操作系统)【第一、二章优化拓展:Wifi、服务器连接验证以及UASRT串口区分】

 

第一、二章优化拓展开发环境:

主控STM32F103C8T6
WIFI模块ESP01S
开发语言C
开发编译器·

KEIL

组网方式WIFI
服务器协议MQTT

硬件连接

STM32ESP01S
3.3V3.3V

GND

GND

GPIO2  (USRAT2-TX)

RX
GPIO3 (USART3-RX)TX

本章要点:

  • 对ESP01S的AT指令的反馈指令进行验证解析
  • 对ESP的USART2通信串口进行printf端口重映射
  • 对调试用的USART1通信串口编写USART_printf函数并且解析%d、%s等可变参数

抽象理解

1、对ESP01S的AT指令的反馈指令进行验证解析

        进入循环函数:在STM32对ESP01S进行USART通信发送完AT指令后,进行串口监听,然后接收AT反馈指令,接着调用strstr()函数对指令进行解析,当解析到AT指令任务实现的反馈指令后,才执行下一步,跳出循环函数

_Bool ESP8266_SendCmd(char *cmd, char *res, u16 time)
{	
	Usart2_SendString((unsigned char *)cmd, strlen((const char *)cmd));

	while(time--)
	{
		if(ESP8266_WaitRecive() == REV_OK)							//如果收到数据
		{
			if(strstr((const char *)esp8266_buf, res) != NULL)		//如果检索到关键词
			{
				ESP8266_Clear();									//清空缓存
				
				return 0;
			}
		}
		
		delay_ms(10);
	}
	return 1;
}

2、对ESP的USART2通信串口进行printf端口重映射

#if 1
#pragma import(__use_no_semihosting)             
//标准库需要的支持函数                 
struct __FILE 
{ 
	int handle; 

}; 

FILE __stdout;       
//定义_sys_exit()以避免使用半主机模式    
void _sys_exit(int x) 
{ 
	x = x; 
} 
//重定义fputc函数 
int fputc(int ch, FILE *f)
{      
//	while((USART2->SR&0X40)==0);//循环发送,直到发送完毕   
//    USART2->DR = (u8) ch;
	while((USART2->SR&0X40)==0);//循环发送,直到发送完毕   (若需要使用usart串口通信进行信息验证调试则取消注释,正常使用请关闭,避免printf打印两次)
    USART2->DR = (u8) ch;  	
	return ch;
}
#endif 

3、对调试用的USART1通信串口编写USART_printf函数并且解析%d、%s等可变参数

#include <stdarg.h> 

//C库重写
#include <mystdlib.h> 

void USART1_printf (char * Data, ... )
{
	const char *s;
	int d;   
	char buf[16];
	
	va_list ap;
	va_start(ap, Data);
 
	while ( * Data != 0 )     // 判断是否到达字符串结束符
	{				                          
		if ( * Data == 0x5c )  //'\'
		{									  
			switch ( *++Data )
			{
				case 'r':							          //回车符
				USART_SendData(USART1, 0x0d);
				Data ++;
				break;
 
				case 'n':							          //换行符
				USART_SendData(USART1, 0x0a);	
				Data ++;
				break;
 
				default:
				Data ++;
				break;
			}			 
		}
		
		else if ( * Data == '%')
		{									  //
			switch ( *++Data )
			{				
				case 's':										  //字符串
				s = va_arg(ap, const char *);
				
				for ( ; *s; s++) 
				{
					USART_SendData(USART1,*s);
					while( USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET );
				}
				
				Data++;
				
				break;
 
				case 'd':			
					//十进制
				d = va_arg(ap, int);
				
				myitoa(d, buf, 10);
				
				for (s = buf; *s; s++) 
				{
					USART_SendData(USART1,*s);
					while( USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET );
				}
				
				Data++;
				
				break;
				
				default:
				Data++;
				
				break;
				
			}		 
		}
		
		else USART_SendData(USART1, *Data++);
		
		while ( USART_GetFlagStatus ( USART1, USART_FLAG_TXE ) == RESET );
		
	}
}

代码:

由于在stm32内,无法使用stdlib.h的C语言库,因此我们重写编写了stdlib.h库的部分函数

mystdlib.h

#ifndef __MYSTDLIB_H
#define __MYSTDLIB_H


/*
将整数转化为字符串:
num,转换对象
str,转换后存储字符串的数组
radix,转换(给于的字符串)的长度
*/
char *myitoa(int num,char *str,int radix) 
{  
	/* 索引表 */ 
	char index[]="0123456789abcdefghijklmnopqrstuvwxz"; 
	unsigned unum; /* 中间变量 */ 
	int i=0,j,k; 
	/* 确定unum的值 */ 
	if(radix==10&&num<0) /* 十进制负数 */ 
	{ 
		unum=(unsigned)-num; 
		str[i++]='-'; 
	} 
	else unum=(unsigned)num; /* 其它情况 */ 
	/* 逆序 */ 
	do  
	{ 
		str[i++]=index[unum%(unsigned)radix]; 
		unum/=radix; 
	}while(unum); 
	str[i]='\0'; 
	/* 转换 */ 
	if(str[0]=='-') k=1; /* 十进制负数 */ 
	else k=0; 
	/* 将原来的“/2”改为“/2.0”,保证当num在16~255之间,radix等于16时,也能得到正确结果 */ 
	char temp; 
	for(j=k;j<=(i-k-1)/2.0;j++) 
	{ 
		temp=str[j]; 
		str[j]=str[i-j-1]; 
		str[i-j-1]=temp; 
	} 
	return str; 
} 

/*
将字符串转换成整数
str,转换的字符串数组目标
返回值:为转换后的整数;
*/
int myatoi(char * str)
{
    int n=0;//保存整形  
    char firstChar = *str;//记录str的第一个字符
    if (firstChar == '+' || firstChar == '-')//+123 -123
    {
        ++str;
    }
    while(*str == '0')//00123  -00123
    {
        ++str;
    }

    while (*str)
    {
        char temp = *str;
        if (*str < '0' || *str> '9')
        {
            puts("literal does not match format string ") ;
            return n;//该字符串含有非数字字符,不能转为整数
        }
        else
        {
            temp -= '0';
            n = n * 10 + temp;//将字符串转为整形
        }
        str++;
    }
    if (firstChar == '-')
    {
        n = -n;
    }
    return n;
}


#endif

如果要本第一、二章优化拓展的完整工程文件,可以直接到百度网盘提取(解压密码同下)

链接:https://pan.baidu.com/s/1ECxx125pRlKVo366fzyTiw?pwd=1016 
提取码:1016

 本文为作者独立编写 

 本BLOG上所有的原创文章未经本人许可,不得用于商业用途及传统媒体。网络媒体转载请注明出处,否则属于侵权行为。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Kafka消息监控管理工具Offset Explorer的使用教程

1、kafka监控管理工具 Offset Explorer是一款用于监控和管理Apache Kafka集群中消费者组偏移量的开源工具。它提供了一个简单直观的用户界面&#xff0c;用于查看和管理Kafka消费者组偏移量的详细信息。 Offset Explorer具有以下主要功能和特点&#xff1a; 实时监控&#x…

Java开发中使用sql简化开发

引语&#xff1a; 在Java开发中&#xff0c;我们更希望数据库能直接给我们必要的数据&#xff0c;然后在业务层面直接进行使用&#xff0c;所以写一个简单的sql语句有助于提高Java开发效率&#xff0c;本文由简单到复杂的小白吸收&#xff0c;还请多多指教。 使用MySQL数据库…

微服务系列文章 之 SpringCloud中遇到的一些bug

1、There was a problem with the instance info replicator 错误原因&#xff1a; 该服务尝试将自己作为客服端注册解决办法&#xff1a; 在application.yml配置文件中&#xff0c;设置 # 注册Eureka服务 eureka:client:# Eureka服务注册中心会将自己作为客户端来尝试注册它自…

Unity基础 弹簧关节SpringJoint

弹簧关节 在游戏开发中&#xff0c;物体之间的交互性是非常重要的。为了模拟现实世界中的弹性特性&#xff0c;Unity提供了弹簧关节&#xff08;Spring Joint&#xff09;组件。通过弹簧关节&#xff0c;我们可以轻松实现物体之间的弹性交互效果。本文将详细介绍Unity中的弹簧…

OpenCv之Canny

目录 一、自适应阈值 二、边缘检测Canny 一、自适应阈值 引入前提:在前面的部分我们使用是全局闻值&#xff0c;整幅图像采用同一个数作为闻值。当时这种方法并不适应与所有情况&#xff0c;尤其是当同一幅图像上的不同部分的具有不同亮度时。这种情况下我们需要采用自适应闻…

如何清除视频和照片中水印的几种方式

文章目录 如何清除视频和照片中水印的几种方式一、清除视频中水印的几种方式1、截除水印区域2、模糊水印区域3、使用人工智能技术工具3.1 通过【iMyFone-MarkGo[^1]】消除水印3.2 通过【嗨格式视频转换器[^2]】消除水印3.3 通过【PR 视频编辑器】消除水印3.4 通过 【美图秀秀】…

【运维小知识】(一)——centos系统安装(小白入门级)

目录 1.制作系统U盘 2.安装centos系统 3.系统配置 3.1【语言】配置​编辑 3.2【软件选择】配置 3.3【安装位置】配置 3.4【主机名、root密码、网络】配置 1.制作系统U盘 首先下载软件ventoy&#xff0c;制作系统U盘&#xff0c;买个新U盘。先在笔记本电脑安装ventoy软件&a…

利用数据分析告警机制,实现鸿鹄与飞书双向集成

需求描述 实现鸿鹄与飞书的双向集成&#xff0c;依赖鸿鹄的告警机制&#xff0c;可以发送用户关心的信息到飞书。同时依赖飞书强大的卡片消息功能&#xff0c;在飞书消息里面能够通过链接&#xff08;如下图&#xff09;返回到鸿鹄以方便用户进一步排查和分析问题。 解决方案 1…

旅游卡加盟代理合伙人模式软件开发

旅游卡加盟代理合伙人模式是近年来逐渐兴起的一种旅游产业发展模式&#xff0c;它通过将旅游卡加盟商与代理商紧密结合&#xff0c;实现资源共享、风险共担、合作共赢的目标。而软件开发作为旅游卡加盟代理合伙人模式的重要技术支持&#xff0c;对于该模式的实施和发展起着至关…

【Linux系统】结合有趣的小故事让你学懂生产者消费者模型

目录 由故事引入模型故事背景供货商们的矛盾市民们和供货商之间的矛盾一市民们和供货商之间的矛盾二市民们的矛盾模型总结 生产者消费者模型为什么要使用生产者消费者模型&#xff1f;生产者消费者模型的特点生产者消费者模型优点 基于BlockingQueue的生产者消费者模型C queue模…

行为式验证码(成语点选)(C#版和Java版)

一、先看效果图 二、背景介绍 图形验证码网上有挺多&#xff0c;比如&#xff1a;网易易盾、腾讯防水墙、阿里云验证码等等。参考了一下&#xff0c;自己实现了一个简单的成语点选的模式。 三、实现思路 1.选择若干张图片&#xff08;这里使用的是320x160的尺寸&#xff09;…

【Linux】生产者消费者模型 -- RingQueue

文章目录 1. 信号量1.1 信号量的引入1.2 信号量的概念1.3 信号量函数 2. 二元信号量模拟实现互斥功能3. 基于环形队列的生产消费模型3.1 空间资源和数据资源3.2 生产者和消费者申请和释放资源3.3 必须遵守的两个规则3.4 代码实现3.5 信号量保护环形队列的原理 1. 信号量 1.1 信…

Java 串口通讯 Demo

为什么写这篇文章 之前职业生涯中遇到的都是通过tcp协议与其他设备进行通讯&#xff0c;而这个是通过串口与其他设备进行通讯&#xff0c;意识到这里是承重板的连接&#xff0c;但实际上比如拉力、压力等模拟信号转换成数字信号的设备应该是有相当一大部分是通过这种方式通讯的…

6.溢出的文字省略号显示

6.1单行文本溢出显示省略号 必须满足三个条件 /*1. 先强制一行内显示文本*/ white-space: nowrap; &#xff08; 默认 normal 自动换行&#xff09; /*2. 超出的部分隐藏*/ overflow: hidden; /*3. 文字用省略号替代超出的部分*/ text-overflow: ellipsis;【示例代码】 <…

Redis学习(三)持久化机制、分布式缓存、多级缓存、Redis实战经验

文章目录 分布式缓存Redis持久化RDB持久化AOF持久化 Redis主从Redis数据同步原理全量同步增量同步 Redis哨兵哨兵的作用和原理sentinel&#xff08;哨兵&#xff09;的三个作用是什么&#xff1f;sentinel如何判断一个Redis实例是否健康&#xff1f;master出现故障后&#xff0…

Windows下PyTorch深度学习环境配置(GPU)

一&#xff1a;下载Anaconda &#xff08;路径最好全英文&#xff09; &#xff08;下载好后&#xff0c;可以创建其他虚拟环境&#xff0c;因为是自己学习&#xff0c;所以先不放步骤&#xff0c;有需要者可以参考B站up我是土堆的视频&#xff09; 二&#xff1a;利用 conda…

本地生活直播,和电商直播有什么不一样?

直播正在成为零售业的标配&#xff0c;当下最新的一条赛道是“本地生活直播”。 &#xff08;商家开始在美团等平台进行本地生活直播。摄影&#xff1a;李崧稷&#xff09; 今年618&#xff0c;在老牌电商平台拉着无数网店&#xff0c;拼尽全力想要堆高销量的时候&#xff0c;一…

《TCP IP网络编程》第六章

《TCP IP网络编程》第六章&#xff1a;基于 UDP 的服务端/客户端 UDP 套接字的特点&#xff1a; 通过寄信来说明 UDP 的工作原理&#xff0c;这是讲解 UDP 时使用的传统示例&#xff0c;它与 UDP 的特点完全相同。寄信前应先在信封上填好寄信人和收信人的地址&#xff0c;之后…

pytorch+CRNN实现

最近接触了一个仪表盘识别的项目&#xff0c;简单调研以后发现可以用CRNN来做。但是手边缺少仪表盘数据集&#xff0c;就先用ICDAR2013试了一下。 结果遇到了一系列坑。为了不使读者和自己在以后的日子继续遭罪。我把正确的代码发到下面了。 1&#xff09;超参数请不要调整&am…

抖音新号起号正确方法,如何操作?

抖音上有着越来越多的卖家注册账号&#xff0c;但刚开始在注册账号后&#xff0c;新号是没有什么流量的&#xff0c;所以想要获得更多的流量的话&#xff0c;在刚开始进行起号的时候就需要按照以下方式进行&#xff0c;下面就一起了解清楚。 第一个找对标内容&#xff0c;抖音…