stm32实现esp8266毗连到TCP服务器(二)

打印 上一主题 下一主题

主题 893|帖子 893|积分 2679

1.2 毗连到TCP Server
                1.2.1 利用网络助手,设立TCP服务器

编辑
                1.2.2 毗连服务器
   AT+CIPSTART="TCP","192.168.1.18",8080 //指令,注意双引号逗号都要半角(英文)输入 CONNECT //结果:成功 OK //结果:成功
OK
                  1.2.3 发送数据
   AT+CIPSEND=4 //设置即将发送数据的长度
  >abcd        //看到大于号后,输入消息,abcd,不要带回车
  Response :SEND OK //结果:成功
  //注意,这种环境下,每次发送前都要线发送AT+CIPSEND=长度,的指令,在发数据!
  1.3 透传
   用AT + CIPSEND = 4,每次发送数据都要举行字符长度设定
  今天透传模式
  AT+CIPMODE=1 //开启透传模式
  Response :OK
  AT+CIPSEND //带回车
  Response: > //这个时间随意发送吸收数据咯
  退出透传模式
   在透传发送数据过程中,若辨认到单独的⼀包数据 “+++”,则退出透传发送
   
      头文件
  1. #include "sys.h"
  2. #include "esp8266.h"
  3. #include "string.h"
  4. #include "delay.h"
  5. #include "stdarg.h"
  6. uint8_t esp8266_tx_buf[ESP8266_TX_BUF_SIZE];
  7. uint8_t esp8266_rx_buf[ESP8266_RX_BUF_SIZE];
  8. uint16_t esp8266_cnt = 0 ,esp8266_cntPre = 0; /* esp8266接收缓冲区 */
  9. UART_HandleTypeDef esp8266_handle;             /* esp8266句柄 */
复制代码
esp8266模块串口配置初始化
  1. //正常会有启动的流程只是作为一个串口的初始化
  2. void esp8266_uart_init(uint16_t baudrate)
  3. {
  4.     esp8266_handle.Instance = USART2;                  /* USART1 */
  5.     esp8266_handle.Init.Baudrate = baudrate;           /*波特率*/
  6.     esp8266_handle.Init.WordLength= UART_WORDLENGTH_8B;/*字长为8位的数据格式传输*/
  7.     esp8266_handle.Init.StopBits = UART_STOPBITS_1;    /*一个停止位*/
  8.     esp8266_handle.Init.Parity   = UART_PARITY_NONE;                   /*无奇偶校验位*/
  9.     esp8266_handle.Init.HwFlowCtl = UART_HWCONTRL_NONE;/*无硬件流控制*/
  10.     esp8266_handle.Init.Mode      = UART_MODE_TX_RX;   /*收发模式*/
  11.     HAL_UART_Init(esp8266_handle);
  12. }
复制代码
清除吸收缓存
  1. void esp8266_rx_clear(void)
  2. {
  3.     memset(esp8266_rx_buf,0,sizeof(esp8266_rx_buf));
  4.     esp8266_cnt = 0;
  5. }
复制代码
中断服务函数
  1. void USART2_IRQHandler(void)
  2. {
  3.     uint8_t receive_data = 0;
  4.     /* 获取接收RXNE标志位是否被置位 */
  5.     if(__HAL_UART_GET_FLAG(&esp8266_handle,UART_FLAG_RXNE) !=RESET)
  6.     {
  7.         /* 则将接收计数器清零 */
  8.         if(esp8266_cnt >=sizeof(esp8266_rx_buf))
  9.         esp8266_cnt = 0;
  10.         /* 接收一个字符 */
  11.         HAL_UART_Receive(&esp8266_handle,&receive_data, 1,1000);
  12.         /* 将接收到的字符保存在接收缓冲区 */
  13.         esp8266_rx_buf[esp8266_cnt++] = receive_data;
  14. }
  15.         /* 获取接收空闲中断标志位是否被置位 */
  16.         if(__HAL_UART_GET_FLAG(&esp8266_handle,UART_FLAG_IDLE) != RESET)
  17.         {
  18.                                  /* 将接收到的数据打印出来 */
  19.         printf("recv: %s\r\n", esp8266_rx_buf);
  20.         esp8266_rx_clear();      /* 清除UART总线空闲中断 */
  21.         __HAL_UART_CLEAR_IDLEFLAG(&esp8266_handle)
  22. }
  23. }
复制代码
吸收等待
  1. uint8_t esp8266_wait_receive(void)
  2. {
  3.     if(esp8266_cnt == 0)
  4.     return ESP8266_ERROR;
  5.     if(esp8266_cnt == esp8266_cntPre)
  6.     {
  7.     esp8266_cnt = 0;
  8.     return ESP8266_EOK;
  9.     }
  10.     esp8266_cntPre = esp8266_cnt;
  11.     return ESP8266_ERROR;
  12. }
复制代码
发送命令与期待回复函数
  1. uint8_t esp8266_send_command(char *cmd,cahr *res)
  2. {
  3.     uint8_t timeout_out = 250;
  4.    
  5.     esp8266_rx_clear();//防止缓冲区内的数据影响
  6.     HAL__UART_Tramsmit(&esp8266_handle,(uint8_t *)cmd,strlen(cmd),100);
  7.    
  8.     while(timeout_out--)//不停的等待
  9.     {
  10.     if(esp8266_wait_receive() == ESP8266_EOK)
  11.     {
  12.     if(strstr(const char *)esp8266_rx_buf, res) != NULL)//判断是否又有期待的字符串
  13.     return ESP8266_EOK
  14. }
  15.     return ESP8266_ERROR;
  16. }
  17. }
复制代码
吸收数据
  1. void esp8266_receiv_data(void)
  2. {
  3.     if(esp8266_wait_receive() = ESP8266_EOK)
  4.     {
  5.     printf("esp8266 recv: %s\r\n",esp8266_rx_buf);
  6.     esp8266_rx_clear();
  7.     }
  8. }
复制代码
发送不定长数据
  1. void esp8266_send_data(char *fmt, ...)
  2. {
  3.     va_list ap;
  4.     uint16_len;
  5.    
  6.     va_start(ap,fmt);
  7.     vsprintf((char *)esp8266_tx_buf,fmt,ap);
  8.     va_end(ap);
  9.    
  10.     len = strlen((const char*)esp8266_tx_buf);
  11.     HAL__UART_Transmit(&esp8266_handle,esp8266_tx_buf,len,100);// 发送
  12. }
复制代码
at测试指令
  1. uint8_t esp8266_at_test(void)
  2. {
  3.     return esp8266_send_command("AT\r\n", "OK");//记得加回车
  4. }
复制代码
模式设置函数封装
  1. uint8_t esp8266_set_mode(uint8_t mode)
  2. {
  3.     switch(mode)
  4. {
  5.     case ESP8266_STA_MODE:
  6.         return esp8266_send_command("AT+CWMODE=1\r\n");
  7.     case ESP8266_AP_MODE:
  8.         return esp8266_send_command("AT+CWMODE=2\r\n");
  9.     case ESP8266_STA_AP_MODE:
  10.         return esp8266_send_command("AT+CWMODE=3\r\n");
  11.     default:
  12.         return esp8266_EINVL;
  13. }
  14. }
复制代码
加入服务器输入账号暗码
  1. uint8_t esp8266_join_ap(char *ssid,char *pwd)
  2. {
  3.     char cmd[64];
  4.     sprintf(cmd, "AT+CWJAP="%s","%s"\r\n",ssid,pwd);//作为模式传输进入
  5.     return esp8266_send_command(cmd."OK");
  6. }
复制代码
设置单路毗连的esp8266毗连模式
  1. /*设置单路连接的模式(透传只能用此模式)*/
  2. uint8_t esp8266_connect_mode(uint8_t mode)
  3. {
  4.     char cmd[64];
  5.     sprintf(cmd,"AT+CIPMUX=%d\r\n",mode);
  6.     return esp8266_send_command(cmd,"OK");//发送cmd指令期待回复OK
  7. }
复制代码
毗连tcp服务器
  1. uint8_t esp8266_connect_tcp_sever(char *server_ip,char *server port)
  2. {
  3.     char cmd[64];
  4.     sprintf(cmd,"AT+CIPSTART="TCP","%s",%s\r\n",server_ip,server_port);
  5.     return esp8266_send_command,"CONNECT");
  6. }
复制代码
进入透传模式
  1. uint8_t esp8266_enter_unvarnished(void)//进入透传模式
  2. {
  3.     uint8_t ret;
  4.    
  5.     ret  =  esp8266_send_command("AT+CIPMODE=1\r\n","OK");
  6.     ret +=  esp8266_send_command("AT+CIPSEND\r\n",">");//调用指令函数
  7.     if(ret == ESP8266_EOK)
  8.         return ESP8266_EOK;
  9.     else
  10.         return ESP8266_ERROR;
  11. }
复制代码
esp8266初始化
  1. uint8_t esp8266_init(uint32_t baudrate)
  2. {
  3.     printf("esp8266初始化开始...\r\n");   
  4.     esp8266_init_uart(baudrate);
  5.   
  6.     printf("1. 测试esp8266是否存在\r\n")
  7.     while(esp8266_at_test())
  8.         delay_ms(500);
  9.    
  10.     printf("2. 设置工作模式为STA...\r\n");
  11.     while(esp8266_set_mode(ESP8266_STA_MODE)
  12.         delay_ms(500);
  13.     printf("3. 设置单路链接模式\r\n");
  14.     while(esp8266_connect_mode(ESP8266_SINGLE_CONNECTION))
  15.     delay_ms(500);
  16.    
  17.     printf("4. 连接wifi,SSID: %s ,PWD:%s\r\n",WIFI_SSID,WIFI_PWD);
  18.     while(esp8266_join_ap(WIFI_SSID,WIFI,PWD))
  19.     delay_ms(1500);//时间长一些
  20.     printf("6. 进入透传模式...\r\n");
  21.     while(esp8266_enter_unvarnished())
  22.     delay_ms(500);
  23.     print("esp8266已经连接上tcp服务器并进入透传模式")
  24. }
复制代码
测试函数
  1. void esp8266_test(void)
  2. {
  3.         esp8266_send_data("this is from esp8266\r\n");
  4.         esp8266_receiv_data();
  5. }
复制代码
main函数
  1. #include "delay.h"
  2. #include "led.h"
  3. #include "uart1.h"
  4. #include "esp8266.h"
  5. int main(void)
  6. {
  7.     HAL_Init();                         /* 初始化HAL库 */
  8.     stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟, 72Mhz */
  9.     led_init();        /* LED初始化 */
  10.                 uart1_init(115200);
  11.                 esp8266_init(115200);
  12.                 printf("helloworld!\r\n");               
  13.     while(1)
  14.     {                              
  15.                         esp8266_test();
  16.                         delay_ms(500);
  17.     }
  18. }
复制代码
2. ESP8266作为服务器
USB转TTL插入电脑,TX--RX RX-TX VCC-3.3V GND-GND
查询IP地点:AT+CIFSR
//1 配置成AP模式
   AT+CWMODE=2
  Response :OK
  //2 使能多链接
   AT+CIPMUX=1 Response :OK
  //3 建立TCPServer
   AT+CIPSERVER=1 // default port = 333 Response :OK
  //4 发送数据
   AT+CIPSEND=0,4      // 发送4个字节在毗连0通道上 >abcd//输入数据,
  Response :SEND OK //不带回车
  //5 吸收数据
   +IPD, 0, n: xxxxxxxxxx //+IPD是固定字符串 0是通道,n是数据长度,xxx是数据
  //断开毗连
   AT+CIPCLOSE=0
  Response :0, CLOSED OK
   头文件
  1. #include "sys.h"
  2. #include "esp8266.h"
  3. #include "string.h"
  4. #include "delay.h"
  5. #include "stdarg.h"
  6. uint8_t esp8266_tx_buf[ESP8266_TX_BUF_SIZE];
  7. uint8_t esp8266_rx_buf[ESP8266_RX_BUF_SIZE];
  8. uint16_t esp8266_cnt = 0 ,esp8266_cntPre = 0; /* esp8266接收缓冲区 */
  9. UART_HandleTypeDef esp8266_handle;             /* esp8266句柄 */
复制代码
esp8266串口初始化配置
  1. void esp8266_uart_init(uint32_t baudrate)//正常会有启动的流程只是作为一个串口的初始化
  2. {
  3.     /*esp8266 初始化设置*/
  4.     esp8266_handle.Instance = USART2;                               /* USART1 */
  5.     esp8266_handle.Init.BaudRate = baudrate;                        /* 波特率 */
  6.     esp8266_handle.Init.WordLength = UART_WORDLENGTH_8B;            /* 字长为8位数据格式*/
  7.     esp8266_handle.Init.StopBits = UART_STOPBITS_1;                 /* 一个停止位 */
  8.     esp8266_handle.Init.Parity = UART_PARITY_NONE;                  /* 无奇偶校验位 */
  9.     esp8266_handle.Init.HwFlowCtl = UART_HWCONTROL_NONE;            /* 无硬件流控 */
  10.     esp8266_handle.Init.Mode = UART_MODE_TX_RX;                     /* 收发模式 */
  11.     HAL_UART_Init(&esp8266_handle);                                 /*会使能esp8266 */                 
  12. }
复制代码
吸收缓冲区配置
  1. void esp8266_rx_clear(void)
  2. {
  3.     memset(esp8266_rx_buf, 0, sizeof(esp8266_rx_buf)); /* 清空接收缓冲区 */
  4.     esp8266_cnt = 0;                                   /* 接收计数器清零 */
  5. }
复制代码
中断服务函数
  1. void USART2_IRQHandler(void)
  2. {
  3.     uint8_t receive_data = 0;   
  4.     if(__HAL_UART_GET_FLAG(&esp8266_handle, UART_FLAG_RXNE) != RESET){/* 获取接收RXNE标志位是否被置位 */
  5.         if(esp8266_cnt >= sizeof(esp8266_rx_buf))                     /* 如果接收的字符数大于接收缓冲区大小, */
  6.             esp8266_cnt = 0;                                          /* 则将接收计数器清零 */
  7.         HAL_UART_Receive(&esp8266_handle, &receive_data, 1, 1000);    /* 接收一个字符 */
  8.         esp8266_rx_buf[esp8266_cnt++] = receive_data;    /* 将接收到的字符保存在接收缓冲区 */
  9.     }
  10.     if (__HAL_UART_GET_FLAG(&esp8266_handle, UART_FLAG_IDLE) != RESET) /* 获取接收空闲中断标志位是否被置位 */
  11.     {
  12.         printf("recv: %s\r\n", esp8266_rx_buf);                  /* 将接收到的数据打印出来 */
  13.         esp8266_rx_clear();
  14.         __HAL_UART_CLEAR_IDLEFLAG(&esp8266_handle);              /* 清除UART总线空闲中断 */
  15.     }
  16. }
复制代码
等待吸收函数
  1. uint8_t esp8266_wait_receive(void)
  2. {
  3.         if(esp8266_cnt == 0)
  4.                         return ESP8266_ERROR;
  5.         if(esp8266_cnt == esp8266_cntPre)
  6.         {
  7.                 esp8266_cnt = 0;
  8.                 return ESP8266_EOK;
  9.         }
  10.                 esp8266_cntPre = esp8266_cnt;
  11.                 return ESP8266_ERROR;
  12. }
复制代码
发送指令并期待返回值
  1. uint8_t esp8266_send_command(char *cmd,char *res)//发送一个指令去   在指定时间内返回回来 否则没有接收到一个返回值
  2. {
  3.         uint8_t timeout_out = 250;
  4.        
  5.         esp8266_rx_clear(); //防止忍心内的数据影响
  6.         HAL_UART_Transmit(&esp8266_handle,(uint8_t *)cmd,strlen(cmd),100);//发送命令 cmd在这里是一个uint8_t的数据 长度 阻塞的值
  7.         //等待
  8.         while(timeout_out--)//不停的等待
  9.         {
  10.                 if(esp8266_wait_receive() == ESP8266_EOK)
  11.                 {
  12.                         if(strstr((const char*)esp8266_rx_buf, res) != NULL)//判断是否又有期待的字符串
  13.                         return ESP8266_EOK;
  14.                 }
  15.                 delay_ms(10);
  16.                 }
  17.                 return ESP8266_ERROR;//否则接收错误
  18.        
  19. }
复制代码
吸收数据
  1. //接收的函数
  2. void esp8266_receiv_data(void)
  3. {
  4.         if(esp8266_wait_receive() == ESP8266_EOK)
  5.         {
  6.                 printf("esp8266 recv: %s\r\n", esp8266_rx_buf);
  7.                 esp8266_rx_clear();
  8.         }
  9. }
复制代码
发送不定长数据
  1. //发送的函数  不定长数据 参数不固定
  2. void esp8266_send_data(char *fmt, ...)
  3. {
  4.         va_list ap;
  5.         uint16_t len;
  6.        
  7.         va_start(ap,fmt);
  8.         vsprintf((char *)esp8266_tx_buf,fmt, ap);
  9.         va_end(ap);
  10.        
  11.         len = strlen((const char*)esp8266_tx_buf);
  12.         HAL_UART_Transmit(&esp8266_handle, esp8266_tx_buf, len,100);//发送
  13. }
复制代码
设置a模块是否存在测试
  1. uint8_t esp8266_at_test(void)
  2. {
  3.                 return esp8266_send_command("AT\r\n", "OK");//记得加回车换行才能作为指令发送期待返回值为OK  直接作为返回值发送
  4. }
复制代码
设置模式
  1. uint8_t esp8266_set_mode(uint8_t mode)//s四个函数
  2. {
  3.         switch(mode)
  4.         {
  5.                 case ESP8266_STA_MODE:
  6.                                 return esp8266_send_command("AT+CWMODE=1\r\n","OK");
  7.                
  8.                 case ESP8266_AP_MODE:
  9.                                 return esp8266_send_command("AT+CWMODE=2\r\n","OK");
  10.                
  11.                 case ESP8266_STA_AP_MODE:
  12.                                 return esp8266_send_command("AT+CWMODE=3\r\n","OK");
  13.                
  14.                 default:
  15.                                 return ESP8266_EINVAL;//如果指令不存在
  16.         }
  17. }
复制代码
加入AP
  1. uint8_t esp8266_join_ap(char *ssid,char *pwd)//账号密码
  2. {
  3.                 char cmd[64];
  4.                 sprintf(cmd, "AT+CWJAP="%s","%s"\r\n",ssid,pwd);//"HUAWEIAP-1",="%s\  就指令带引号直接写不行,我们需要如此就不会将“”认为是配对的
  5.                 return esp8266_send_command(cmd,"WIFI GOT IP");;//调用指令函数
  6. }
复制代码
毗连模式
  1.        
  2. uint8_t esp8266_connect_mode(uint8_t mode)//设置单路连接的模式(透传只能用此模式)
  3. {
  4.                 char cmd[64];
  5.                 sprintf(cmd, "AT+CIPMUX=%d\r\n",mode);//作为模式传输进入
  6.                 return esp8266_send_command(cmd,"OK");;//调用指令函数
  7. }
  8. //连接TCP服务器
复制代码
esp8266_毗连模式
  1. uint8_t esp8266_connect_mode(uint8_t mode)//设置单路连接的模式(透传只能用此模式)
  2. {
  3.                 char cmd[64];
  4.                 sprintf(cmd, "AT+CIPMUX=%d\r\n",mode);//作为模式传输进入
  5.                 return esp8266_send_command(cmd,"OK");;//调用指令函数
  6. }
复制代码
 esp8266毗连tpc服务器ip和端口
  1. uint8_t esp8266_connect_tcp_server(char *server_ip,char*server_port)
  2. {
  3.                 char cmd[64];
  4.                 sprintf(cmd, "AT+CIPSTART="TCP","%s",%s\r\n",server_ip,server_port);//作为模式传输进入
  5.                 return esp8266_send_command(cmd,"CONNECT");;//调用指令函数
  6. }
复制代码
进入透传模式
  1. uint8_t esp8266_enter_unvarnished(void)//发送的模式
  2. {
  3.                 uint8_t ret;//取巧的方式定义一个返回值
  4.                 //两次返回值都等于0,如果有一个不为0就为不为零的情况
  5.                 ret  = esp8266_send_command("AT+CIPMODE=1\r\n","OK");;//调用指令函数
  6.                 ret += esp8266_send_command("AT+CIPSEND\r\n",">");;//调用指令函数
  7.                 if(ret == ESP8266_EOK)
  8.                                 return ESP8266_EOK;
  9.                 else
  10.                                 return ESP8266_ERROR;               
  11. }
复制代码
建立tcp服务器
  1. uint8_t esp8266_build_tcp_server(void)
  2. {
  3.                 return esp8266_send_command("AT+CIPSERVER=1\r\n","OK");//发送AT+CIPSEVER=1,期待回复OK
  4. }
复制代码
初始化esp8266
  1. void esp8266_init(uint32_t baudrate)//所以增加新添加一个
  2. {
  3.                 printf("esp8266初始化开始...\r\n");
  4.                 esp8266_uart_init(baudrate);
  5.        
  6.                 printf("1. 测试esp8266是否存在\r\n");
  7.                 while(esp8266_at_test())//esp8266_at_test();也是可以的不过一直不成功那就一直等待更为保险
  8.                         delay_ms(500);
  9.                 printf("2. 设置工作模式为AP...\r\n");
  10.                 while(esp8266_set_mode(ESP8266_AP_MODE))
  11.                         delay_ms(500);
  12.                
  13.                 printf("3. 设置多路链接模式\r\n");
  14.                 while(esp8266_connect_mode(ESP8266_MULTI_CONNECTION))
  15.                         delay_ms(500);
  16.                 printf("4. 建立TCP服务器...\r\n");
  17.                 while(esp8266_build_tcp_server())
  18.                         delay_ms(500);               
  19.                 printf("esp8266初始化完成...\r\n");
  20.                
  21.                
  22.         //esp8266的其他初始化
  23. }
复制代码
esp8266初始化测试
  1. //测试函数void esp8266_test(void)
  2. {
  3.         esp8266_send_data("this is from esp8266\r\n");
  4.         esp8266_receiv_data();
  5. }
复制代码
 
 
 

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

正序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

王海鱼

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表