STM32开发——串口通讯(第2篇)——WIFI(Esp8266)

目录

1.ESP8266 作为设备

2.ESP8266作为服务器


STM32开发——串口通讯(第2篇)——WIFI(Esp8266)_第1张图片

 

注意:1.在中断中一般不直接在中断服务函数里处理数据,而是在收到数据后直接丢给队列,再处理数据;
2.在中断服务函数里尽量减少使用延时函数及打印函数。

1.ESP8266 作为设备

1.1项目需求

ESP8266接入同一WIFI局域网下的服务器,向服务器发送数据

ESP-01s出厂波特率正常是115200, 注意:AT指令,控制类都要加回车,数据传输时不加回车。

上电后,串口输出系统开机信息,购买的部分模块可能电压不稳乱码,以 ready 为准。

通过一下命令配置成9600波特率

AT+UART=9600,8,1,0,0

1.设置工作模式

AT+CWMODE=3 //1. 是station(设备)模式 2.是AP(路由)模式 3.是双模
OK

2.以设备模式接入家中路由器配置

AT+CWJAP="TP-LINK_3E30","18650711783" //指令
WIFI CONNECTED //结果
WIFI GOT IP   //结果
OK     //结果

3.连接服务器

AT+CIPSTART="TCP","192.168.0.113",8888 //指令,注意双引号逗号都要半角(英文)输入
CONNECT  //结果:成功
OK    //结果:成功

4.开启透传模式

AT+CIPMODE=1  //开启透传模式
Response :OK

5.发送数据

AT+CIPSEND //带回车
Response: >  //这个时候随意发送接收数据咯

CubeMX设置

打开串口1、及其中断;打开串口2;打开GPIO8-led;中断优先级降低;

函数代码

#include "string.h"
#include "stdio.h"

uint8_t buf=0;
unsigned char ch[200] ;
uint16_t UART1_RX_STA=0;

int LAN_mark=0;
int other_land_mark=0;
int suceed_mark=0;
int error=1;

char LAN_connect[]         ="AT+CWJAP=\"yangkai\",\"12345678\"\r\n";
char TCP_server_connect[]  ="AT+CIPSTART=\"TCP\",\"172.20.10.5\",80\r\n";
char touchuan_start[]      ="AT+CIPMODE=1\r\n";
char datatransport_start[] ="AT+CIPSEND\r\n";
char reset[]               ="AT+RST\r\n";
char my_word[]             ="hello world\r\n";

int fputc(int ch1,FILE *f)
{
	uint8_t temp[1]={ch1};  //必须要用uint8_t承接,将int char变为uint8_t
	
	HAL_UART_Transmit(&huart1, temp, 1, 0xffff);
	return ch1;
}


//重写串口中断服务函数——————串口接受到的数据
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
	//如果来自串口1的数捿
	if(huart->Instance==USART1){
		//如果没有接收完成
		if((UART1_RX_STA & 0x8000)==0){
			//如果已经收到迿0x0d回车
			if(UART1_RX_STA & 0x4000){
				//如果这个数是0x0a换行
				if(buf==0x0a){
					//,接收完成,弿始下丿次接政
					UART1_RX_STA|=0x8000;
					//可以用ch匹配数据了
					//HAL_UART_Transmit(&huart2, ch, strlen(ch), 0xffff);
					// 这里用来测试可以,但是不能用串口2来打印CH,影响串口接收函数,影响时序。
					
					if(!strcmp(ch,"WIFI GOT IP")){						//收到wifi got ip
						LAN_mark=1;
					}
					if(!strcmp(ch,"OK")){						//收到OK
						other_land_mark=1;
					}
					if(!strcmp(ch,"LED")){						//收到led翻转LED
						HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_8);
					}
					// 查看是否收到 FAIL
					if(!strcmp(ch, "FAIL"))
					{
						int i = 0;
						for (i = 0; i < 5; i++)
						{
							HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_8);
							HAL_Delay(1000);
						}
						printf(reset);
					}
					
					
					memset(ch,'\0',200);
					UART1_RX_STA=0;
				//如果这个数不昿0x0a换行
				}else{
					//接收失败,数据清穿
					UART1_RX_STA=0;
					//memset(ch,0,200);
				}
		
			//如果没有收到迿0x0d
			}else{
				//如果现在这个数是0x0d回车
				if(buf==0x0d){
					//状濁为标记改变为收到了0x0d
					UART1_RX_STA|=0x4000;
			//如果现在这个数不昿0x0d换行
				}else{
				//进行接收进入ch里面
					ch[UART1_RX_STA&0x3fff]=buf;
					UART1_RX_STA++;
					
					if(UART1_RX_STA>199)
						UART1_RX_STA = 0;
				}
			}
		}
		//重新弿启串口中断接政
		HAL_UART_Receive_IT(&huart1, &buf,1);
	}
}


main函数中代码

	HAL_NVIC_SetPriority(SysTick_IRQn,0,0);
	//打开串口1接收中断  接收到的字符存在buf里,有一个字? 
	HAL_UART_Receive_IT(&huart1, &buf, 1);


	HAL_UART_Transmit(&huart2, "let's go\r\n", strlen("let's go\r\n"), 100);
	

	
		printf(LAN_connect);
		//printf(LAN_connect);	   //发送联网指令    "yangkai\",\"12345678\"\r\n";
		//while(!LAN_mark) HAL_Delay(50);   //接收到 wifi  GOTIP执行下一步LAN_mark变为1
		while(!other_land_mark) HAL_Delay(50);   //接收到OK执行下一步other_land_mark 变为1	
		HAL_UART_Transmit(&huart2, (uint8_t *)"111", strlen("111"), 100);	 //连上就111
		other_land_mark=0;       //other_land_mark接收到OK执行下一步
		
		printf(TCP_server_connect);			//发送"TCP\",\"172.20.10.5\",80\r\n";
		while(!other_land_mark) HAL_Delay(50); //接收到OK执行下一步other_land_mark 变为1
		other_land_mark=0;       //other_land_mark接收到OK执行下一步
 
		printf(touchuan_start);		//AT+CIPMODE=1\r\n";
		while(!other_land_mark) HAL_Delay(50); //other_land_mark接收到OK执行下一步
		other_land_mark=0;   //重新置0


		printf(datatransport_start);	   //"AT+CIPSEND\r\n"
		while(!other_land_mark) HAL_Delay(50); //other_land_mark接收到OK执行下一步


	
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */

  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
		//如果sta高位丿1 ==受到带换行的数据 
		HAL_UART_Transmit(&huart2, (uint8_t *)"已连接服务器\r\n", strlen("已连接服务器\r\n"), 100);	 //连上就111
		printf("hello yk\r\n");
		
		//printf("hello world.\r\n");
		HAL_Delay(3000);
  }


2.ESP8266作为服务器

步骤:

//0重启
+STA_CONNECTED:"c0:a5:dd:54:0c:ef"
+DIST_STA_IP:"c0:a5:dd:54:0c:ef","192.168.4.2"
WIFI DISCONNECT
隔5秒后下一个
//1 配置成双模
AT+CWMODE=2
Response :OK
//2 使能多链接
AT+CIPMUX=1
Response :OK
//3 建立TCPServer
AT+CIPSERVER=1,8888 // default port = 333
Response :OK
 
//然后TCP client去连接服务器1,8888
Response :0,CONNECT

while(1){ 
    //4 发送数据设置
    AT+CIPSEND=0,4 // 发送4个字节在连接0通道上
    //5 发送数据
    "hello yk"
    Response :SEND OK
}

//断开连接
AT+CIPCLOSE=0
Response :0, CLOSED OK

CubeMX是同样上的设置

函数代码如下

#include "string.h"
#include "stdio.h"

uint8_t buf=0;
unsigned char ch[200] ;
uint16_t UART1_RX_STA=0;

int TCP_mark=0;
int other_land_mark=0;

char mode_AP[]             ="AT+CWMODE=2\r\n";
char mutiple_connect[]     ="AT+CIPMUX=1\r\n";
char TCPserver[]		   ="AT+CIPSERVER=1,8888\r\n";
char data_trans[]		   ="AT+CIPSEND=0,11\r\n";
char reset[]               ="AT+RST\r\n";
char my_word[]             ="hello world";

int fputc(int ch1,FILE *f)
{
	uint8_t temp[1]={ch1};  //必须要用uint8_t承接,将int char变为uint8_t
	
	HAL_UART_Transmit(&huart1, temp, 1, 0xffff);
	return ch1;
}


//重写串口中断服务函数——————串口接受到的数据
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
	//如果来自串口1的数捿
	if(huart->Instance==USART1){
		//如果没有接收完成
		if((UART1_RX_STA & 0x8000)==0){
			//如果已经收到迿0x0d回车
			if(UART1_RX_STA & 0x4000){
				//如果这个数是0x0a换行
				if(buf==0x0a){
					//,接收完成,弿始下丿次接政
					UART1_RX_STA|=0x8000;
					//可以用ch匹配数据了
					//HAL_UART_Transmit(&huart2, ch, strlen(ch), 0xffff);
					// 这里用来测试可以,但是不能用串口2来打印CH,影响串口接收函数,影响时序。
					
					if(!strcmp(ch,"0,CONNECT")){						//收到0,CONNECT
						TCP_mark=1;
					}
					if(!strcmp(ch,"OK")){						//收到OK
						other_land_mark=1;
					}
					if(!strcmp(ch,"LED")){						//收到led翻转LED
						HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_8);
					}
					// 查看是否收到 FAIL
					if(!strcmp(ch, "ERROR"))
					{
						int i = 0;
						for (i = 0; i < 5; i++)
						{
							HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_8);
							HAL_Delay(1000);
						}
						printf(reset);
					}
					
					
					memset(ch,'\0',200);
					UART1_RX_STA=0;
				//如果这个数不昿0x0a换行
				}else{
					//接收失败,数据清穿
					UART1_RX_STA=0;
					//memset(ch,0,200);
				}
		
			//如果没有收到迿0x0d
			}else{
				//如果现在这个数是0x0d回车
				if(buf==0x0d){
					//状濁为标记改变为收到了0x0d
					UART1_RX_STA|=0x4000;
			//如果现在这个数不昿0x0d换行
				}else{
				//进行接收进入ch里面
					ch[UART1_RX_STA&0x3fff]=buf;
					UART1_RX_STA++;
					
					if(UART1_RX_STA>199)
						UART1_RX_STA = 0;
				}
			}
		}
		//重新弿启串口中断接政
		HAL_UART_Receive_IT(&huart1, &buf,1);
	}
}

//main函数中代码
	HAL_NVIC_SetPriority(SysTick_IRQn,0,0);
	//打开串口1接收中断  接收到的字符存在buf里,有一个字? 
	HAL_UART_Receive_IT(&huart1, &buf, 1);


	HAL_UART_Transmit(&huart2, "let's go\r\n", strlen("let's go\r\n"), 100);
	
		printf(mode_AP);    //设置路由器模式
		while(!other_land_mark) HAL_Delay(50);   //接收到OK执行下一步other_land_mark 变为1	
		HAL_UART_Transmit(&huart2, (uint8_t *)"111", strlen("111"), 100);	 //连上就111
		other_land_mark=0;       //other_land_mark接收到OK执行下一步
		
		printf(mutiple_connect);			//使能多连接
		while(!other_land_mark) HAL_Delay(50); //接收到OK执行下一步other_land_mark 变为1
		HAL_UART_Transmit(&huart2, (uint8_t *)"222", strlen("222"), 100);	 //连上就111
		other_land_mark=0;       //other_land_mark接收到OK执行下一步
 
		printf(TCPserver);		//建立TCP服务器
		while(!TCP_mark) HAL_Delay(50); //TCP_mark接收到0,CONNECT执行下一步
		HAL_UART_Transmit(&huart2, (uint8_t *)"333", strlen("333"), 100);	 //连上就111
		TCP_mark=0;   //重新置0


		printf(data_trans);	   //设置数据传输端口和字数
		while(!other_land_mark) HAL_Delay(50); //other_land_mark接收到OK执行下一步
		
		HAL_UART_Transmit(&huart2, (uint8_t *)"已建立服务器\r\n", strlen("已建立服务器\r\n"), 100);	 //连上就111


	
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */

  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */	

		HAL_UART_Transmit(&huart2, (uint8_t *)"hello yk\r\n", strlen("hello yk\r\n"), 100);	
		printf(data_trans);
		HAL_Delay(2000);
		//发送数据
		printf(my_word);
		HAL_Delay(2000);
		//data2=SBUF;   //接受外部数据后产生中断	 进入interrupt 4

  }
  /* USER CODE END 3 */
}

你可能感兴趣的:(#,STM32开发,嵌入式开发,stm32,单片机,嵌入式硬件)