2248|2

155

帖子

1

TA的资源

一粒金砂(高级)

楼主
 

七、USART1驱动ESP8266做TCP Client [复制链接]

在下的GD32L233C-START专题测评:

一、开箱评测 https://bbs.eeworld.com.cn/thread-1192788-1-1.html

二、GD32L233C-START环境搭建https://bbs.eeworld.com.cn/thread-1193053-1-1.html

三、点灯案例与扩展https://bbs.eeworld.com.cn/thread-1193183-1-1.html

四、Demo工程的分析https://bbs.eeworld.com.cn/thread-1193279-1-1.html

五、USART0的printf实现和DMA实现https://bbs.eeworld.com.cn/thread-1193517-1-1.html

六、USART1发送和接收的DMA实现https://bbs.eeworld.com.cn/thread-1196550-1-1.html


       本篇沿袭第六篇测评,在USART1口开启DMA收发的基础上驱动ESP8266 AT模组,进行TCP Client测试,AP使用手机热点,并通过网络调试助手APP开启了TCP Server。ESP的代码是以前教学时,STM32案例中就开发过的。

       按照习惯,建立aita_esp.h和aita_esp.c。

       aita_esp.h是一些宏定义和函数说明,ESP8266模块Rx和Tx连接GD32L233的USART1(PA2、PA3),且RST脚连接PA4,已实现MCU重启,控制ESP模块一并重启的效果。其中的宏定义包括:ESP驱动时的错误码(自定义)、复位脚PA4的配置、AITA_ESP_ECHO_EN作为条件编译启用串口提示信息输出、发送和清空接收缓存用了宏以提高可移植性。

#ifndef __AITA_ESP_H
#define __AITA_ESP_H


/* Includes ------------------------------------------------------- */
#include "gd32l23x.h"


/* Exported macro ------------------------------------------------- */
//错误码
#define AITA_ESP_REV_OK  0//ESP接收完成标志
#define AITA_ESP_WAIT    1//ESP接收未完成标志
//ESP模块Reset管脚及初始化
#define AITA_ESP_RSTPIN  GPIO_PIN_4
#define AITA_ESP_RSTPORT GPIOA
//#define AITA_ESP_RST     PAout(4) //GD MCU中无效
#define AITA_ESP_RST_SET \
  gpio_bit_set(AITA_ESP_RSTPORT, AITA_ESP_RSTPIN)
#define AITA_ESP_RST_CLR \
  gpio_bit_reset(AITA_ESP_RSTPORT, AITA_ESP_RSTPIN)
#define AITA_ESP_RSTPIN_INIT \
  rcu_periph_clock_enable(RCU_GPIOA); \
  gpio_mode_set(AITA_ESP_RSTPORT, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, AITA_ESP_RSTPIN); \
  gpio_output_options_set(AITA_ESP_RSTPORT, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, AITA_ESP_RSTPIN);
//ESP模块操作printf输出提示使能
#define AITA_ESP_ECHO_EN 1
//ESP模块接口API
#define AITA_ESP_SEND    aita_U1SendStr
#define AITA_ESP_CLEAR   aita_ClearU1RxBuffer


/* Exported function prototypes ----------------------------------- */
void aita_InitESP(void);
uint16_t aita_WaitRecvESP(void);
uint16_t aita_SendCmdESP(char *cmd, char *res);
void aita_SendDatESP(uint8_t *data, uint16_t len);
uint8_t* aita_GetIPDESP(uint16_t timeout);

#endif

 

       aita_esp.c的代码中预留了HTTP和MQTT(旧版)连接OneNet的接口(宏),这也是以前STM32案例中创建的,本例中没有使用到。

/* Includes ------------------------------------------------------- */
#include "aita_sys.h"


/* Private macro -------------------------------------------------- */
//延时API
#define AITA_ESP_DELAYMS   delay_1ms

//联网命令
#define AITA_ESP_WIFI_INFO "AT+CWJAP=\"SSID\",\"PASSWORD\"\r\n"
//测试TCP接口
#define AITA_ESP_TCP_SERVER_SOCKET \
            "AT+CIPSTART=\"TCP\",\"192.168.43.1\",1234\r\n"
//OneNet HTTP接口
#define AITA_ESP_ONENET_HTTP_SOCKET \
            "AT+CIPSTART=\"TCP\",\"183.230.40.33\",80\r\n"
//OneNet MQTT接口
#define AITA_ESP_ONENET_MQTT_SOCKET \
            "AT+CIPSTART=\"TCP\",\"183.230.40.39\",6002\r\n"
//主要AT命令及返回
#define AITA_ESP_AT_CMD    "AT\r\n"
#define AITA_ESP_AT_OK     "OK"
#define AITA_ESP_AT_STA    "AT+CWMODE=1\r\n"
#define AITA_ESP_AT_AP     "AT+CWMODE=2\r\n"
#define AITA_ESP_AT_STA_AP "AT+CWMODE=3\r\n"
#define AITA_ESP_AT_JAP    AITA_ESP_WIFI_INFO
#define AITA_ESP_AT_JAP_OK "GOT IP"
//请根据接入方式设置宏定义
//AITA_ESP_ONENET_HTTP_SOCKET HTTP接入
//AITA_ESP_ONENET_MQTT_SOCKET MQTT接入
#define AITA_ESP_AT_CIP    AITA_ESP_TCP_SERVER_SOCKET
#define AITA_ESP_AT_CIP_OK "CONNECT"
//ESP接收缓存
#define AITA_ESP_BUF       u1rxbuffer
#define AITA_ESP_BUF_LEN   USART1_BUF_LENGTH
//ESP接收计数
#define AITA_ESP_CNT       u1rxindex


/* Private variables ---------------------------------------------- */
//uint8_t  aita_esp_buf[AITA_ESP_BUF_LEN];
//uint16_t aita_esp_cntnow = 0;
uint16_t aita_esp_cntpre = 0;


/* Exported functions --------------------------------------------- */
/*********************************************************************
 * FunctionName : aita_InitESP()
 * Description  : ESP模块初始化,使用串口需单独初始化
 * Parameters   : void
 * Returns      : void
*********************************************************************/
void aita_InitESP(void) {
  AITA_ESP_RSTPIN_INIT;
  AITA_ESP_RST_CLR;
  AITA_ESP_DELAYMS(250);
  AITA_ESP_RST_SET;
  AITA_ESP_DELAYMS(500);

  AITA_ESP_CLEAR();

#if AITA_ESP_ECHO_EN
  printf("1. ESP AT\r\n");
  while(aita_SendCmdESP(AITA_ESP_AT_CMD, AITA_ESP_AT_OK))
    AITA_ESP_DELAYMS(500);
#endif

#if AITA_ESP_ECHO_EN
  printf("2. ESP STA MODE\r\n");
  while(aita_SendCmdESP(AITA_ESP_AT_STA, AITA_ESP_AT_OK))
    AITA_ESP_DELAYMS(500);
#endif

#if AITA_ESP_ECHO_EN
  printf("3. ESP Join AP\r\n");
  while(aita_SendCmdESP(AITA_ESP_AT_JAP, AITA_ESP_AT_JAP_OK))
    AITA_ESP_DELAYMS(500);
#endif

#if AITA_ESP_ECHO_EN
  printf("4. ESP START CIPSEND\r\n");
  while(aita_SendCmdESP(AITA_ESP_AT_CIP, AITA_ESP_AT_CIP_OK))
    AITA_ESP_DELAYMS(500);
#endif

#if AITA_ESP_ECHO_EN
  printf("5. ESP Inialization Done!\r\n");
#endif
}
/*********************************************************************
 * FunctionName : aita_GetIPDESP()
 * Description  : 获取平台返回的数据
 * Parameters   : uint16_t timeout  ——> 等待超时(乘以10ms)
 * Returns      : 平台返回的原始数据
*********************************************************************/
uint8_t* aita_GetIPDESP(uint16_t timeout) {
  char *pIPD = 0;
  do {
    if(aita_WaitRecvESP() == AITA_ESP_REV_OK) {
      pIPD = strstr((char *)AITA_ESP_BUF, "IPD,");
      if(pIPD == 0) {}
      else {
        pIPD = strchr(pIPD, ':');
        if(pIPD != 0) {
          pIPD++;
          return (uint8_t *)pIPD;
        } else {
          return 0;
        }
      }
    }
    AITA_ESP_DELAYMS(10);
  } while(timeout--);				
  return 0;
}
//void aita_ClearESPBuf(void) {
//  memset(AITA_ESP_BUF, 0, AITA_ESP_BUF_LEN);
//  AITA_ESP_CNT = 0;
//}
/*********************************************************************
 * FunctionName : aita_WaitRecvESP()
 * Description  : 判断ESP接收状态
 * Parameters   : void
 * Returns      : AITA_ESP_REV_OK-接收完成,AITA_ESP_WAIT-接收未完成
*********************************************************************/
uint16_t aita_WaitRecvESP(void) {
//接收0字节,说明还要等待接收完毕
  if(AITA_ESP_CNT == 0) return AITA_ESP_WAIT;
//上次和本次字节数一致,说明接收完毕
  if(aita_esp_cntpre == AITA_ESP_CNT) {
    return AITA_ESP_REV_OK;
  }
  aita_esp_cntpre = AITA_ESP_CNT;
  return AITA_ESP_WAIT;
}
/*********************************************************************
 * FunctionName : aita_SendCmdESP()
 * Description  : 向ESP发送AT命令
 * Parameters   : char *cmd  ——> 发送的命令字串
 *                char *res  ——> 期待的回复字串
 * Returns      : 0-成功;1-失败
*********************************************************************/
uint16_t aita_SendCmdESP(char *cmd, char *res) {
  uint16_t timeout = 200;
  AITA_ESP_SEND((uint8_t *)cmd, strlen(cmd));

  while(timeout--) {
    if(aita_WaitRecvESP() == AITA_ESP_REV_OK) {
      if(strstr((const char *)AITA_ESP_BUF, res) != 0) {
        AITA_ESP_CLEAR();
        return 0;
      }
    }
    AITA_ESP_DELAYMS(10);
  }
  return 1;
}
/*********************************************************************
 * FunctionName : aita_SendDatESP()
 * Description  : 利用AT+SEND命令发送数据
 * Parameters   : uint8_t *data  ——> 发送的数据
 *                uint16_t len  ——> 数据串长度
 * Returns      : void
*********************************************************************/
void aita_SendDatESP(uint8_t *data, uint16_t len) {
  char atsendcmd[32];
  AITA_ESP_CLEAR();
  sprintf(atsendcmd, "AT+CIPSEND=%d\r\n", len);
  if(!(aita_SendCmdESP(atsendcmd, ">")))
    AITA_ESP_SEND(data, len);
}

 

       main.c中编写了一个测试函数,非常简单——上电连接wifi、连接TCP Server、循环发送字串。

//在main函数中调用
void aita_TestESP(void) {
  char buf[32];
  uint16_t i = 0;
  while(1) {
    memset(buf, 0, 32);
    sprintf(buf, "Times %d\r\n", i++);
    aita_SendDatESP((uint8_t *)buf, sizeof(buf));
    delay_1ms(5000);
  }
}

 

       最后的效果如下,开了两个串口终端,一个连接USART0接收系统输出信息,一个连接到USART1(并联ESP8266 Rx脚)查看ESP接收到的AT命令。

 

此帖出自GD32 MCU论坛

最新回复

楼主你好,最近在学GD32,按照您的代码复现有点问题,可以参考一下您的源码吗     详情 回复 发表于 2024-4-26 01:49
点赞 关注
 

回复
举报

6593

帖子

0

TA的资源

五彩晶圆(高级)

沙发
 

归纳总结的比较好

此帖出自GD32 MCU论坛
 
 
 

回复

3

帖子

0

TA的资源

一粒金砂(初级)

板凳
 

楼主你好,最近在学GD32,按照您的代码复现有点问题,可以参考一下您的源码吗

 

此帖出自GD32 MCU论坛
 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

开源项目 更多>>
    随便看看
    查找数据手册?

    EEWorld Datasheet 技术支持

    相关文章 更多>>
    关闭
    站长推荐上一条 1/10 下一条

     
    EEWorld订阅号

     
    EEWorld服务号

     
    汽车开发圈

    About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

    站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

    北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

    电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved
    快速回复 返回顶部 返回列表