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

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

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

KEIL

组网方式 WIFI
服务器协议 MQTT

硬件连接

STM32 ESP01S
3.3V 3.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上所有的原创文章未经本人许可,不得用于商业用途及传统媒体。网络媒体转载请注明出处,否则属于侵权行为。

猜你喜欢

转载自blog.csdn.net/weixin_61908666/article/details/131742992