7 WIFI

1、ESP8266模块

  • ESP8266系列无线模块是安信可科技自主研发设计的一系列高性价比WIFI SOC模组。该系列模块支持标准的IEEE802.11 b/g/n协议,内置完整的TCP/IP协议栈。用户可以使用该系列模块为现有的设备添加联网功能,也可以构建独立的网络控制器。
  • 安信可科技为客户提供完整的硬件、软件参考方案,以便缩短您的产品研发周期,为您节省成本投入。

2、烧写固件

1:将USB转TTL模块上位机USB口
2:运行\ESP烧录工具\ESP_TOOLS\ESPFlashDownloadTool_v3.4.1.exe
在这里插入图片描述

1.选中烧写的固件文件,路径位于:ESP烧录工具\Ai-Thinker_ESP8266_DOUT_8Mbit_v1.5.4.1-a_20171130.bin
2.指定USB转TTL模块端口号,到设备管理器查看,并且指定波特率115200
3.最后点击”START”按钮烧写即可,烧写固件完毕,按USB转TLL调试小板的复位键,复位模块

3、调试工具

1:启动:ESP调试工具\AiThinker Serial Tool V1.2.3.exe调试工具,并且配置串口工作参数并且打开USB转TTL模块
在这里插入图片描述

2.启动上位机网络调试助手,启动一个TCP Server
在这里插入图片描述

3:ESP8266连接Server
在命令输入框中分别输入以下AT指令:

AT+CWMODE=1//设置为STA模式
AT+CWAUTOCONN=0//上电不自动连接
AT+CWJAP= “tarena” ,959948ye”//连接WIFI路由
AT+CIPSTA?//查看分配的IP地址
AT+CIPMODE=1//设置为透传模式
AT+CIPMUX=0//设置单连接
AT+CIPSTART= “TCP” ,192.168.0.7,8080//连接服务器
AT+CIPSEND//启动发
输入发送的数据给服务器
当然服务器也可以发送数据给8266模块,通过串口工具显示信息

在这里插入图片描述

4、使用库函数实现wifi

4.1 实现串口3和DMA的初始化

在system目录下的USART目录,打开keil工程,新建uart3.c和uart3.h文件,实现串口3的配置和dma的使用

#ifndef __UART3_H_
#define __UART3_H_

#include "stm32f10x.h"

// 定义接收/发送缓存区大小
#define UART3_RXBUFF_SIZE 2048
#define UART3_TXBUFF_SIZE 2048

typedef struct{
	// 声明发送/接收缓冲区
	u8 UART3_RxBUFF[UART3_RXBUFF_SIZE];
	u8 UART3_TxBUFF[UART3_TXBUFF_SIZE];
	int UART3_RxCounter;// 串口3接收数据计数
	int Rx_Flag; // 接收标志位
	int Tx_Flag; // 发送标志位
	
} UART3_DATA;

extern UART3_DATA uart3_data;

void UART3_Init(void); // 串口3初始化

void UART3_Puts(char* fmt,...); // 可变参函数
#endif

编辑uart3.c文件

#include "uart3.h"
#include "string.h" // va_list va_start va_end
#include "stdarg.h"
#include "stdio.h"
// 定义
UART3_DATA uart3_data={{0},{0},0,0,0};

void UART3_Init(void){
	// 1、打开时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);// 打开GPIOB时钟
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3,ENABLE);// 打开串口3的时钟
	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE);// 打开dma的时钟
	
	// 配置GPIOB10 PB11
	GPIO_InitTypeDef GPIO_Config;
	GPIO_Config.GPIO_Mode = GPIO_Mode_AF_PP;
	GPIO_Config.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Config.GPIO_Pin = GPIO_Pin_10;
	GPIO_Init(GPIOB,&GPIO_Config); // PB10 TX
	
	GPIO_Config.GPIO_Pin = GPIO_Pin_11;
	GPIO_Config.GPIO_Mode = GPIO_Mode_IPU;
	GPIO_Init(GPIOB,&GPIO_Config); // PB11 RX
	
	// 配置串口3
	USART_InitTypeDef USART_Config;
	USART_Config.USART_BaudRate = 115200;
	USART_Config.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
	USART_Config.USART_Mode = USART_Mode_Rx|USART_Mode_Tx;
	USART_Config.USART_Parity = USART_Parity_No;
	USART_Config.USART_StopBits = USART_StopBits_1;
	USART_Config.USART_WordLength = USART_WordLength_8b;
	USART_Init(USART3,&USART_Config);
	
	// 配置串口3的rx和tx的dma
	USART_DMACmd(USART3,USART_DMAReq_Rx,ENABLE);
	USART_DMACmd(USART3,USART_DMAReq_Tx,ENABLE);
	
	// 使能串口3
	USART_Cmd(USART3,ENABLE);
	
	// 中断配置 总线空闲中断
	USART_ITConfig(USART3,USART_IT_IDLE,ENABLE);
	
	// 配置发送的DMA DMA1通道2的tx
	DMA_InitTypeDef DMA_Config;
	DMA_Config.DMA_BufferSize = UART3_TXBUFF_SIZE;
	DMA_Config.DMA_DIR = DMA_DIR_PeripheralDST;
	DMA_Config.DMA_M2M = DMA_M2M_Disable;
	DMA_Config.DMA_MemoryBaseAddr = (u32)uart3_data.UART3_TxBUFF;
	DMA_Config.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
	DMA_Config.DMA_MemoryInc = DMA_MemoryInc_Enable;
	DMA_Config.DMA_Mode = DMA_Mode_Normal;
	DMA_Config.DMA_PeripheralBaseAddr = (u32) (&(USART3->DR));
	DMA_Config.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
	DMA_Config.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
	DMA_Config.DMA_Priority = DMA_Priority_High;
	DMA_Init(DMA1_Channel2,&DMA_Config);
	
	// 配置接收的DMA DMA1通道3 rx
	DMA_Config.DMA_BufferSize = UART3_RXBUFF_SIZE;
	DMA_Config.DMA_DIR = DMA_DIR_PeripheralSRC;
	DMA_Config.DMA_M2M = DMA_M2M_Disable;
	DMA_Config.DMA_MemoryBaseAddr = (u32)uart3_data.UART3_RxBUFF;
	DMA_Config.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
	DMA_Config.DMA_MemoryInc = DMA_MemoryInc_Enable;
	DMA_Config.DMA_Mode = DMA_Mode_Normal;
	DMA_Config.DMA_PeripheralBaseAddr = (u32) (&(USART3->DR));
	DMA_Config.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
	DMA_Config.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
	DMA_Config.DMA_Priority = DMA_Priority_High;
	DMA_Init(DMA1_Channel3,&DMA_Config);
	
	// 使能接收的通道
	DMA_Cmd(DMA1_Channel3,ENABLE);
	
	// 配置dma的发送中断
	NVIC_InitTypeDef NVIC_Config;
	NVIC_Config.NVIC_IRQChannel = DMA1_Channel2_IRQn;
	NVIC_Config.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Config.NVIC_IRQChannelPreemptionPriority = 0;
	NVIC_Config.NVIC_IRQChannelSubPriority=2;
	NVIC_Init(&NVIC_Config);
	DMA_ITConfig(DMA1_Channel2,DMA_IT_TC,ENABLE);
	
	// 配置串口3的接收中断
	NVIC_Config.NVIC_IRQChannel = USART3_IRQn;
	NVIC_Init(&NVIC_Config);
	
}

// 串口3的接收中断
void USART3_IRQHandler(void){
	if(USART_GetITStatus(USART3,USART_IT_IDLE) == SET){
		// 清除中断标志位
		USART3->SR;
		USART3->DR;
		// 获取接收数据的长度
		uart3_data.UART3_RxCounter = UART3_RXBUFF_SIZE-DMA_GetCurrDataCounter(DMA1_Channel3);
		// 关闭dma
		DMA_Cmd(DMA1_Channel3,DISABLE);
		DMA_SetCurrDataCounter(DMA1_Channel3,UART3_RXBUFF_SIZE);
		// 打开dma
		DMA_Cmd(DMA1_Channel3,ENABLE);
		// 接收标志位置1
		uart3_data.Rx_Flag =1;
	}
}

// dma1 通道2 的发送中断
void DMA1_Channel2_IRQHandler(void){
	if(DMA_GetITStatus(DMA1_IT_TC2) == SET){
		// 清除标志
		DMA_ClearITPendingBit(DMA1_IT_TC2);
		uart3_data.Tx_Flag = 1;
		DMA_Cmd(DMA1_Channel2,DISABLE);
	}
}

// 定义串口3发送可变参数函数
void UART3_Puts(char* fmt,...){
	// 清空发送缓冲区
	memset(uart3_data.UART3_TxBUFF,0,UART3_TXBUFF_SIZE); 
	// 构造得到的字符串发送到缓冲区
	va_list ap;
	va_start(ap,fmt);
	vsprintf((char*)uart3_data.UART3_TxBUFF,fmt,ap);
	va_end(ap);
	uart3_data.Tx_Flag=0;
	// 设置发送字节长度
	DMA_SetCurrDataCounter(DMA1_Channel2,UART3_TXBUFF_SIZE);
	// 使能
	DMA_Cmd(DMA1_Channel2,ENABLE);
}

4.2 利用串口3实现wifi

在system目录下,新建的ESP8266目录,打开keil工程,新建esp8266.c和esp8266.h文件
编辑esp8266.h

#ifndef __ESP8266_H_
#define __ESP8266_H_
#include "stm32f10x.h"
#include "uart3.h"
#include "system.h"

#define 	WIFI_RESET       PAout(15) 	        	     // 指定ESP8266复位引脚
#define 	WIFI_Printf    	 UART3_Puts  			     // 指定WIFI发送数据使用串口3
#define 	WIFI_RxCounter 	 uart3_data.UART3_RxCounter  // 指定WIFI接收数据个数
#define 	WIFI_RxBuff			 uart3_data.UART3_RxBUFF // 指定wifi接收缓冲区
#define 	WIFI_RXBUFF_SIZE UART3_RXBUFF_SIZE  		 // 指定wifi接收缓冲区大小

#define     SSID   "zpyl" // wifi 路由名字
#define 	PASSWD  "12345678" // wifi路由密码

#define   ServerIP "192.168.43.214"   // 服务器IP地址
#define	  ServerPort 8090				// 服务器端口号


// 函数声明
void WIFI_ResetIO_Init(void);//WIFI复位引脚初始化函数

int WIFI_SendCmd(u8* cmd, u32 timeout);//发送AT指令
int WIFI_Reset(u32 timeout);//复位函数
int WIFI_JoinAP(u32 timeout);//连接路由器函数
int WIFI_Connect_Server(u32 timeout);//连接服务器函数 
int WIFI_Connect_IOTServer(void);//连接服务器总函数 

void WIFI_Connect(void);//连接服务器测试函数
void WIFI_Send_Data(void);//发送数据测试函数 
#endif

编辑esp8266.c

#include "esp8266.h"
#include "systick.h"
#include "stdio.h"
#include "string.h"

void WIFI_ResetIO_Init(void){//WIFI复位引脚初始化函数
	// 1、打开时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);// 打开GPIOA时钟
	// 解除PA15的JTAG功能,将其作为普通io功能  坑点
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
	GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable,ENABLE);
	// 配置GPIOA15
	GPIO_InitTypeDef GPIO_Config;
	GPIO_Config.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_Config.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Config.GPIO_Pin = GPIO_Pin_15;
	GPIO_Init(GPIOA,&GPIO_Config); // PA15
	// 默认将其拉高,后续拉低实现复位
	WIFI_RESET = 1;
}

// 实现wifi复位 成功返回0 失败返回-1
int WIFI_Reset(u32 timeout){
	WIFI_RESET = 0;
	delay_ms(500);// 复位 + 固件加载 + 初始化
	WIFI_RESET = 1;
	while(--timeout){
		delay_ms(100);
		if(strstr((char*)WIFI_RxBuff,"ready")){// 跳出循环
			printf("复位成功\r\n");
			break;
		}
	}
	if(timeout <= 0){
		return -1;// 超时,复位失败
	}
	return 0;// 复位成功
}

// 发送指令给wifi路由 cmd:要发送的指令 timeout 超时时间 
// 通过判断ESP8266回复的字符串中寻找OK,找到则返回0 ,没找到则返回-1
int WIFI_SendCmd(u8* cmd,u32 timeout){
	// 清空接收缓冲区清空
	WIFI_RxCounter =0; // 接收到wifi的数据个数
	// 从wifi接收缓冲区首地址开始的WIFI_RXBUFF_SIZE 个字节设置为0
	memset(WIFI_RxBuff,0,WIFI_RXBUFF_SIZE); 
	// 发送指令给8266
	WIFI_Printf("%s\r\n",cmd);
	printf("%s",cmd);
	while(--timeout){
		delay_ms(100);
		if(strstr((char*)WIFI_RxBuff,"OK")){// 跳出循环
			break;
		}
	}
	if(timeout <= 0){
		printf("发送失败 \r\n");
		return -1;// 失败
	}else{
		printf("发送成功 \r\n");
		return 0;// 成功
	}
}

// 定义连接WIFI路由的函数
int WIFI_JoinAP(u32 timeout){
	// 清空接收缓冲区清空
	WIFI_RxCounter =0; // 接收到wifi的数据个数
	// 从wifi接收缓冲区首地址开始的WIFI_RXBUFF_SIZE 个字节设置为0
	memset(WIFI_RxBuff,0,WIFI_RXBUFF_SIZE); 
	
	// 发送连接wifi的指令
	WIFI_Printf("AT+CWJAP=\"%s\",\"%s\"\r\n",SSID,PASSWD);
	printf("AT+CWJAP=\"%s\",\"%s\"",SSID,PASSWD);
	int flag =0;
	while(--timeout){
		delay_ms(100);
		if(strstr((char*)WIFI_RxBuff,"WIFI GOT IP") && flag == 0){// 连接上路由
			flag =1;
		}
		if(strstr((char*)WIFI_RxBuff,"OK") && flag == 1){// 配置完成ip
			break;
		}
		
	}
	if(timeout <= 0){
		printf("发送失败 \r\n");
		return -1;// 失败
	}else{
		printf("发送成功 \r\n");
		return 0;// 成功
	}
}

// 定义连接服务器的函数
int WIFI_Connect_Server(u32 timeout){
	// 清空接收缓冲区清空
	WIFI_RxCounter =0; // 接收到wifi的数据个数
	// 从wifi接收缓冲区首地址开始的WIFI_RXBUFF_SIZE 个字节设置为0
	memset(WIFI_RxBuff,0,WIFI_RXBUFF_SIZE); 
	
	// 发送连接服务器的指令
	WIFI_Printf("AT+CIPSTART=\"TCP\",\"%s\",%d\r\n",ServerIP,ServerPort);
	printf("AT+CIPSTART=\"TCP\",\"%s\",%d",ServerIP,ServerPort);
	u32 timeout1 = timeout; 
	while(--timeout1){
		delay_ms(100);
		if(strstr((char*)WIFI_RxBuff,"CONNECT")){// 跳出循环
			break;
		}
		if(strstr((char*)WIFI_RxBuff,"CLOSED")){// 跳出循环
			printf("发送成功\r\n");
			return 1;
		}
	}
	
	if(timeout1<=0){
		printf("发送失败\r\n");
		return -1;// 失败
	}else{
		printf("发送成功\r\n");
		delay_ms(1000);
		delay_ms(1000);
		// 连接服务器成功,后续和服务器通信,AT+CIPSEND指令
		WIFI_RxCounter =0; // 接收到wifi的数据个数
		memset(WIFI_RxBuff,0,WIFI_RXBUFF_SIZE); 
		WIFI_Printf("AT+CIPSEND\r\n");
		printf("AT+CIPSEND");
		while(--timeout){
			delay_ms(100);
			printf("WIFI_RxBuff: %s\r\n",WIFI_RxBuff);
			if(strstr((char*)WIFI_RxBuff,"OK")){// 跳出循环
				break;
			}
		}
		if(timeout<=0){
			printf("发送失败\r\n");
			return -1; // 超时
		}else{
			printf("发送成功\r\n");
			return 0;// 成功
		}
	}
	
}

// 利用WiFi模块连接服务器总函数 
int WIFI_Connect_IOTServer(void){
	// 1.复位
	if(WIFI_Reset(50) == -1){
		printf("RESET FAILED\r\n");
		return 1;
	}
	printf("WIFI RESET SUCCESS\r\n");
	// 2.设置为STA模式 
	if(WIFI_SendCmd("AT+CWMODE=1", 200)){
		printf("set wifi sta FAILED\r\n");
		return 2;
	}
	printf("set wifi sta SUCCESS\r\n");
	delay_ms(500);
	// 3.上电不自动连接
	if(WIFI_SendCmd("AT+CWAUTOCONN=0", 200)){
		printf("cancel auto conn FAILED\r\n");
		return 3;
	}
	printf("cancel auto conn SUCCESS\r\n");	
	delay_ms(500);
	// 4.连接路由器
	if(WIFI_JoinAP(200)){
		printf("connect router FAILED\r\n");
		return 4;
	}
	printf("connect router SUCCESS\r\n");	
	// 5.设置透传模式
	if(WIFI_SendCmd("AT+CIPMODE=1", 200)){
		printf("set direct mode FAILED\r\n");
		return 5;
	}
	printf("set direct mode SUCCESS\r\n");	
	delay_ms(500);
    // 6.设置单连接
	if(WIFI_SendCmd("AT+CIPMUX=0", 200)){
		printf("set single mode FAILED\r\n");
		return 6;
	}
	printf("set single mode SUCCESS\r\n");	
	delay_ms(500);
	// 7.连接服务器+发送数据
	if(WIFI_Connect_Server(200)){
		printf("connect server FAILED\r\n");
		return 7;
	}
	printf("connect server SUCCESS\r\n");
	return 0;
}
//连接服务器测试函数
void WIFI_Connect(void){
	if(WIFI_Connect_IOTServer())
		WIFI_Connect();
}
//发送数据的测试函数
void WIFI_Send_Data(void){
	char* msg = "hello, wifi, esp8266\r\n";
	WIFI_Printf("%s", msg);
}

在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

启航zpyl

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值