基于原子开发板STM32精英版的WIFI模块:ATK-ESP8266的实验

基于原子开发板STM32精英版的WIFI模块:ATK-ESP8266的实验

  • 实验环境
    • 一、 串口
    • 二、WIFI
  • 快下班了,后续更新

实验环境

开发板的USART1与电脑连接,WIFI模块发送信号与手机连接。
在电脑上安装串口助手,在手机上安装网络调试助手app

正文开始!

串口使用到了USART1和USART3
其中USART1负责与电脑连接,相互通信
USART3负责与WIFI模块连接,MCU通过USART3将数据发送到WIFI模块,WIFI模块再将数据发送给手机app。

其中串口初始化的代码不再复述。关键讲解功能的实现步骤。

一、 串口

MCU向USART1和USART3打印字符串的代码:
其中MCU向USART1打印字符串是默认的,所以直接使用printf() 即可
但是MCU向USART3打印字符串 使用u3_printf()

void u3_printf(char* fmt,...)  
{  
	u16 i,j; 
	va_list ap; 
	va_start(ap,fmt);
	vsprintf((char*)USART3_TX_BUF,fmt,ap);
	va_end(ap);
	i=strlen((const char*)USART3_TX_BUF);		//此次发送数据的长度
	for(j=0;j<i;j++)							//循环发送数据
	{
	  while(USART_GetFlagStatus(USART3,USART_FLAG_TC)==RESET); //循环发送,直到发送完毕   
		USART_SendData(USART3,USART3_TX_BUF[j]); 
	} 
}

且需要注意: 在本案例中,USART3初始化中需要初始化 定时器
该定时器的作用为:
通过判断接收连续2个字符之间的时间差不大于10ms来决定是不是一次连续的数据.
如果2个字符接收间隔超过10ms,则认为不是1次连续数据.也就是超过10ms没有接收到。

二、WIFI

main.c

int main(void)
{				
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置中断优先级分组为组2:2位抢占优先级,2位响应优先级
	delay_init();
	KEY_Init();  
	uart1_init(115200);	     //串口初始化为115200
	uart3_init(115200);	
	printf("Init_Ready\n");//如果初始化成功,则向USART1发送Init_Ready
	printf("check wifi online:");//这里是等待WIFI模块返回自检成功的标志"OK"
	atk_8266_test();
} 

随着我们的目光落在atk_8266_test()函数上,让我们来分析一下这个函数的功能,这里有一个重要的函数 atk_8266_send_cmd() 我们来先分析一下:
它有三个参数
cmd:发送的命令字符串
ack:期待的应答结果,如果为空,则表示不需要等待应答
waittime:等待时间(单位:10ms)
返回值:0,发送成功(得到了期待的应答结果) 1,发送失败

 u8 atk_8266_send_cmd(u8 *cmd,u8 *ack,u16 waittime)
{
	u8 res=0; 
	USART3_RX_STA=0;
	u3_printf("%s\r\n",cmd);	//发送命令
	if( ack && waittime)		//需要等待应答
	{
		while(--waittime)	//等待倒计时
		{
			delay_ms(10);
			if(USART3_RX_STA&0X8000)//接收到期待的应答结果
			{
				if(atk_8266_check_cmd(ack))
				{
					printf("ack:%s\r\n",(u8*)ack);
					break;//得到有效数据 
				}
					USART3_RX_STA=0;
			} 
		}
		if(waittime==0)res=1; 
	}
	return res;
} 

atk_8266_test() 函数

 void atk_8266_test(void)
{
	u8 key;
	while(atk_8266_send_cmd("AT","OK",20))//检查WIFI模块是否在线
	{
		printf("WIFI_init_fall\n");
		atk_8266_quit_trans();//退出透传
		printf("AT+CIPMODE=0:");
		atk_8266_send_cmd("AT+CIPMODE=0","OK",20);  //关闭透传模式		
	}  
	printf("-------------------\n");
	printf("KEY0:STAAP_MODE\n");
	printf("----------\n");	
	printf("KEY1:STA_MODE\n");
	printf("----------\n");	
	printf("WK_UP:AP_MODE\n");
	printf("-------------------\n");
	while(1)
	{		
		delay_ms(10);
		atk_8266_at_response(1);
		key=KEY_Scan(0); 
		if(key)
		{
			switch(key)
			{
				case KEY0_PRES: //这里偷懒没写完 本该是WIFI STA+APmode测试		
				break;
				//-------
				case KEY1_PRES:
					printf("Selected mode is: STA_mode\n");
					atk_8266_wifista_test();//WIFI STA测试
				break;
				//-------
				case WKUP_PRES:
					printf("Selected mode is: AP_mode\n");
					atk_8266_wifiap_test();	//WIFI AP测试
				break;			
			}
		}
	}				
}

此时我们按下KEY1键,执行atk_8266_wifista_test()
atk_8266_wifista_test()函数
其中WIFI_STA_SSID要自己设置一下,可以设置成手机开启的热点名
WIFI_STA_PASSWORD就是WIFI密码了

但是看下面的代码之前有3个内存的利用函数:
malloc()


p=malloc(sizeof(int)*8);//申请8个int大小的地址,用指针p指向申请到的地址的首地址

sprintf()

sprintf((char*)p," AT+CWJAP= \"%s\"  , \"%s\"  ",WIFI_STA_SSID,WIFI_STA_PASSWORD);
//将WIFI_STA_SSID和WIFI_STA_PASSWORD 和 AT+CWJAP= 组装起来,放入到p指向的内存中

free()


free(p)//释放P指向的地址
u8 atk_8266_wifista_test(void)
{
	unsigned short ano;
	u8 key;
	u8 *p;
	u8 res=0;
	u8 ipbuf[16]; 	//IP缓存
	u16 rlen=0;
	p=malloc(sizeof(int)*8);//一个int 4B 一共32个B
	printf("Set AT+CWMODE=1:");	
	atk_8266_send_cmd("AT+CWMODE=1","OK",20);		//设置WIFI STA模式
	atk_8266_send_cmd("AT+RST","OK",20);		//DHCP服务器关闭(仅AP模式有效) 
	delay_ms(1000);         //延时3S等待重启成功
	delay_ms(1000);
	delay_ms(1000);
	delay_ms(1000);
	sprintf((char*)p," AT+CWJAP= \"%s\"  , \"%s\"  ",WIFI_STA_SSID,WIFI_STA_PASSWORD);
	
	while(!atk_8266_send_cmd(p,"WIFI GOT IP",300))
	{break;}
	
	printf("get ip success!\n");
	//PRESTA:
	printf("-------------------\n");
	printf("KEY0:UDP_MODE\n");
	printf("-------------------\n");	
	printf("KEY1:TCP_Client_MODE\n");
	printf("-------------------\n");	
	printf("WK_UP:TCP_Sever_MODE\n");
	printf("-------------------\n");	
	while(1)
	{
		key=KEY_Scan(0);
		if(key) 
		break;	
	}
//----------------STA_UDP_MODE---------------------
	if(key==KEY0_PRES)
	{
		key=0;
		printf("Current mode is:STA_UDP_MODE\n"); 		/*偷懒,没写完*/
		
	}
//----------------STA_TCP_CLIENT---------------------
//到这一步就要进行人机互动了
//需要打开手机上的网络调试助手(作为Server),且MCU(作为client)
//MCU正在等待电脑上输入手机端的网络调试助手上的IP地址
	else if(key== KEY1_PRES)
	{
		key=0;
		printf("Current mode is:STA_TCP_Client_MODE\n");	
		printf("Now Input Server IP address:\n");//等待USART1输入网络调试助手的IP地址
		ano=!(USART1_RX_STA&0x8000);
	    while( ano)//MCU的USART1一旦收到IP地址,就配网(这里并没有防止IP地址输入的格式不正确的情况)
		{
			if(USART1_RX_STA&0x8000)
			{
				printf("Single Link:");
				atk_8266_send_cmd("AT+CIPMUX=0","OK",20);   //0:单连接,1:多连接
				sprintf((char*)p,"AT+CIPSTART=\"TCP\",\"%s\",%s",USART1_RX_BUF,WIFI_SERVER_PORT);    //配置目标TCP服务器
				USART1_RX_STA=0;
				Clear_USART1_RX_BUF();
				break;
			}
			
		}
		printf("Connect to Server state:");
		while(atk_8266_send_cmd(p,"OK",200))
		{
			printf("Fall\n");
			key=KEY_Scan(0);
			if(key==WKUP_PRES)break;
				//goto PRESTA;
		}
		printf("Turn Transport Mode to 1:");
		atk_8266_send_cmd("AT+CIPMODE=1","OK",200);      //传输模式为:透传	
		printf("-------------------\n");
		printf("WK_UP:goto main menu\n");
		printf("-------------------\n");
		USART3_RX_STA=0;
		Clear_USART3_RX_BUF();
		while(1)
		{
			key=KEY_Scan(0);
			if(key==WKUP_PRES)
			{
				key=0;
				atk_8266_quit_trans();	//退出透传
				printf("Set AT+CIPMODE=0:\n");
				atk_8266_send_cmd("AT+CIPMODE=0","OK",20);   //关闭透传模式		
				atk_8266_send_cmd("AT_RST","OK",20);
				printf("WIFI Reset:\n");				
				delay_ms(1000);
				delay_ms(1000);
				delay_ms(1000);
				//goto 	PRESTA;
				printf("-------------------\n");
				printf("KEY0:STAandAP_MODE\n");
				printf("----------\n");	
				printf("KEY1:STA_MODE\n");
				printf("----------\n");	
				printf("WK_UP:AP_MODE\n");
				printf("-------------------\n");
				break;
			}
			if(USART3_RX_STA&0X8000)		//WIFI接收到一次数据了
			{
				rlen=USART3_RX_STA&0X7FFF;	//得到本次接收到的数据长度
				USART3_RX_BUF[rlen]=0;		//添加结束符 
				printf("%s",USART3_RX_BUF);	//发送到串口 
				USART3_RX_STA=0;	
				Clear_USART3_RX_BUF();				
			}
			if(USART1_RX_STA&0X8000)		//板子收到数据了接收到一次数据了
			{
				rlen=USART1_RX_STA&0X7FFF;	//得到本次接收到的数据长度
				USART1_RX_BUF[rlen]=0;		//添加结束符 
				u3_printf("%s",USART1_RX_BUF);	//发送到串口 
				USART1_RX_STA=0;	
				Clear_USART1_RX_BUF();			
			}
		}	
					
	}
//----------------STA_TCP_SERVER---------------------
	 else  
	 {
		key=0;
	 	printf("Current mode is:STA_TCP_Server_MODE\n");
	    printf("Single Link:");
		atk_8266_send_cmd("AT+CIPMUX=1","OK",20);   //0:单连接,1:多连接
		sprintf((char*)p,"AT+CIPSERVER=1,%s",WIFI_SERVER_PORT);    //开启Server模式(0,关闭;1,打开),端口号为portnum
		printf("Server mode open:");
		atk_8266_send_cmd(p,"OK",50);  
		atk_8266_get_wanip(ipbuf);//服务器模式,获取WAN IP
		sprintf((char*)p,"IP地址:%s 端口:%s",ipbuf,WIFI_SERVER_PORT);
		USART3_RX_STA=0;
		
	 }
//-------------------------------------	 
	 
	 
	 
	 
	free(p);
	return res;

}

下方是开机的USART1显示的画面

基于原子开发板STM32精英版的WIFI模块:ATK-ESP8266的实验_第1张图片
按下 KEY1,且已经连接到了手机热点
基于原子开发板STM32精英版的WIFI模块:ATK-ESP8266的实验_第2张图片
按下KEY1,等待输入IP地址
在这里插入图片描述
输入IP地址后,手机上的网络调试助手连接成功
基于原子开发板STM32精英版的WIFI模块:ATK-ESP8266的实验_第3张图片

快下班了,后续更新

你可能感兴趣的:(嵌入式,STM32,WIFI模块,stm32,单片机,物联网)