stm32项目实战一之智能家居(六)

#esp8266 01s

stm32与wifi模块通信使用串口,stm32与电脑通信也使用串口,在这里我们使用串口1连接电脑进行通信(这里使用ch340n芯片),串口2与wifi模块进行通信。

在上一节中我们通过八个步骤配置wifi模块,但是这里我们需要用单片机代替人工操作。在前面部分已经介绍过“printf”的使用方式。

stm32项目实战一之智能小屋(二)-CSDN博客

usart1和usart2的配置方式是一样的。下文中进行了一定的修改,u1_printf()为串口1的输出,u2_printf()为端口二的输出。

函数介绍:

  首先介绍一下

windows中\r\n表示回车+换行        Linux中\n表示回车+换行        Mac中\r表示回车+换行

(1)sizeof()与strlen()函数的区别:sizeof()把\0也算入其中,而strlen()未\0未算入其中。

(2)memset函数,void *memset(void*str,int c,size_t n)将已开辟内存空间str的首个字节的值设为值c。


    char str[50];
    strcpy(str,"huifeideqiewang")
    memset(str,'*',10);
    printf("%s\n",str);

如在此函数中printf将输出**********ewang。

(3)strstr函数介绍,char *strstr(const char *str1,const char *str2)判断字符串str2是否是str1的子串。如果是,则该函数返回str2在str1中首次出现的地址;否则返回NULL。

例:

const char str1[10] = "huifeideqie";
const char str2[10] = "huifei";
char *ret;
ret =strstr(str1,str2);
printf("子字符串是:%s\n",ret);

此代码将输出"子字符串是:deqie"。

const char str1[10] = "huifeideqie";
const char str2[10] = "huifee";
char *ret;
ret =strstr(str1,str2);
printf("子字符串是:%s\n",ret);

此代码将输出"子字符串是 :(null)。

代码移植:

当要移植USART1使用USART2时要注意:

(1)USART1挂载在APB1总线上,USARET2挂载在APB2总线。

(2)USART1使用引脚9和引脚10,USART2使用引脚2和引脚3。

(3)波特率的修改,串口1使用的是9600,串口2使用的是15200

(4)删除USART_SendByte()函数,如果在串口1和串口2函数中都使用,则此程序会报错,此时在串口2中用extern声明一下,即可调用。

(5)增加中断功能NVIC()配置,如下:

void NVIC_Config(void)
{
		
	NVIC_InitTypeDef NVIC_InitStructure;	
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	
	NVIC_InitStructure.NVIC_IRQChannel=USART2_IRQn;	
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority=0;
	NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
	NVIC_Init(&NVIC_InitStructure);
	        	
}

中断函数的编程思路,首先判断是否能接收到数据,可以接收的话就接收数据,再发送到串口助手。

串口2的接受数据中断如下:

void USART2_IRQHandler(void)   
{ 
    if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET)//
    {  
		                              
		if(USART2->DR)//判断DR寄存器中是否有数据
		{                                 	
			USART2_RxBuff[USART2_RxCounter]=USART_ReceiveData(USART2); //如果有数据将数据放于USART2_RxBuff[USART2_RxCounter]数组中		
			USART2_RxCounter++;    //  每循环一次数组变量USART2_RxCounter加1                  
		}		
		
	}
};

用单片机代替人工操作:

单片机通过串口2发送指令;如:u2_printf("AT+RST\r\n");

单片机等待响应;//计划用time判断这条指令是否执行成功,如果到了time时间没响应,表示模块响应失败;如果过了小于time的时间响应,退出这time的计划,执行下一条语句!

建立WiFi程序模块:

1、按键复位

void WIFI_Config1(int time)//wifi模块初始化
{
    memset(WiFi_RX_BUF,0,1024);//容器数组WiFi_RX_BUF清零
    WiFi_RxCounter = 0;//计数器清零
    while(time--)
    {
        delay_ms(100);    
        if(strstr(WiFi_RX_BUF,"ready"))
        break;
        u1_printf("%d ",time);
    }
        u1_printf("\r\n");
    if(time>0)
        u1_printf("复位成功!\r\n");
    else
       u1_printf("复位失败!\r\n"); 

}

 2、配置wifi模式

 

void WIFI_Config2(int time)//wifi模块初始化
{
    memset(WiFi_RX_BUF,0,1024);//容器数组WiFi_RX_BUF清零
    WiFi_RxCounter = 0;//计数器清零
    u2_printf("AT+CWMODE=1\r\n");
    while(time--)
    {
        delay_ms(100);    
        if(strstr(WiFi_RX_BUF,"OK"))
        break;
        u1_printf("%d ",time);
    }
        u1_printf("\r\n");
    if(time>0)
        u1_printf("配置成功!\r\n");
    else
       u1_printf("配置失败!\r\n"); 

}

 3、完成配置重启

 

void WIFI_Config3(int time)//wifi模块初始化
{
    memset(WiFi_RX_BUF,0,1024);//容器数组WiFi_RX_BUF清零
    WiFi_RxCounter = 0;//计数器清零
    u2_printf("AT+RST\r\n");
    while(time--)
    {
        delay_ms(100);    
        if(strstr(WiFi_RX_BUF,"ready"))
        break;
        u1_printf("%d ",time);
    }
        u1_printf("\r\n");
    if(time>0)
        u1_printf("重启成功!\r\n");
    else
       u1_printf("重启失败!\r\n"); 

}

 第二步和第三步的函数对比发现,只有发送的命令不一样,还有返回的值不一样,所以我们可以将其写成一个函数,如下:

void WIFI_Config(int time,char*cmd,char*response)
{
	memset(WiFi_RX_BUF,0,1024);
	WiFi_RxCounter = 0;
	u2_printf("%s\r\n",cmd); 
	while(time--)
	{
		delay_ms(100);
		if(strstr(WiFi_RX_BUF,response))
			break;
		u1_printf ("%d ",time); 
	}
	u1_printf ("\r\n");
	if(time>0)
       u1_printf ("成功!\r\n"); 
    else
       u1_printf ("失败!\r\n");

}

此程序成为公共函数可实现下面多个步骤。 但在实现第4步和第七步时候,由于多重引号的问题,会报错。

当我们使用printf(""")会出现报错的情况,这里需添加一个转义字符\,我们可以printf("\"")这样使用转义字符,则不会报错。

如下为4和7的程序:

void WIFI_Router(int time)
{
	memset(WiFi_RX_BUF,0,1024);
	WiFi_RxCounter=0;
	u2_printf("AT+CWJAP=\"%s\",\"%s\"\r\n",ID,PASSWORD);
	while(time--)
	{
			delay_ms(1000);
			if(strstr(WiFi_RX_BUF,"OK"))
		    break;
			u1_printf(" %d",time);
	}
	u1_printf("\r\n");
	if(time>0)
			u1_printf("成功!\r\n");
	else
			u1_printf("失败!\r\n");
}
void WiFi_TCP(int time)
{
	memset(WiFi_RX_BUF,0,1024);
	WiFi_RxCounter=0;
	u2_printf("AT+CIPSTART=\"TCP\",\"%s\",%d\r\n",IP,DK);
	while(time--)
	{
			delay_ms(1000);
			if(strstr(WiFi_RX_BUF,"OK"))
		    break;
			u1_printf(" %d",time);
	}
	u1_printf("\r\n");
	if(time>0)
			u1_printf("成功!\r\n");
	else
			u1_printf("失败!\r\n");
}

因为这两个配置时间将会较长所以将延时较长时间。 

  • 10
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值