七、USART1驱动ESP8266做TCP Client
<p>在下的GD32L233C-START专题测评:</p><p>一、开箱评测 <a href="https://bbs.eeworld.com.cn/thread-1192788-1-1.html" target="_blank">https://bbs.eeworld.com.cn/thread-1192788-1-1.html</a></p>
<p>二、GD32L233C-START环境搭建<a href="https://bbs.eeworld.com.cn/thread-1193053-1-1.html" target="_blank">https://bbs.eeworld.com.cn/thread-1193053-1-1.html</a></p>
<p>三、点灯案例与扩展<a href="https://bbs.eeworld.com.cn/thread-1193183-1-1.html" target="_blank">https://bbs.eeworld.com.cn/thread-1193183-1-1.html</a></p>
<p>四、Demo工程的分析<a href="https://bbs.eeworld.com.cn/thread-1193279-1-1.html" target="_blank">https://bbs.eeworld.com.cn/thread-1193279-1-1.html</a></p>
<p>五、USART0的printf实现和DMA实现<a href="https://bbs.eeworld.com.cn/thread-1193517-1-1.html" target="_blank">https://bbs.eeworld.com.cn/thread-1193517-1-1.html</a></p>
<p>六、USART1发送和接收的DMA实现<a href="https://bbs.eeworld.com.cn/thread-1196550-1-1.html" target="_blank">https://bbs.eeworld.com.cn/thread-1196550-1-1.html</a></p>
<hr />
<p> 本篇沿袭第六篇测评,在USART1口开启DMA收发的基础上驱动ESP8266 AT模组,进行TCP Client测试,AP使用手机热点,并通过网络调试助手APP开启了TCP Server。ESP的代码是以前教学时,STM32案例中就开发过的。</p>
<p> 按照习惯,建立aita_esp.h和aita_esp.c。</p>
<p> aita_esp.h是一些宏定义和函数说明,ESP8266模块Rx和Tx连接GD32L233的USART1(PA2、PA3),且RST脚连接PA4,已实现MCU重启,控制ESP模块一并重启的效果。其中的宏定义包括:ESP驱动时的错误码(自定义)、复位脚PA4的配置、AITA_ESP_ECHO_EN作为条件编译启用串口提示信息输出、发送和清空接收缓存用了宏以提高可移植性。</p>
<pre>
<code>#ifndef __AITA_ESP_H
#define __AITA_ESP_H
/* Includes ------------------------------------------------------- */
#include "gd32l23x.h"
/* Exported macro ------------------------------------------------- */
//错误码
#define AITA_ESP_REV_OK0//ESP接收完成标志
#define AITA_ESP_WAIT 1//ESP接收未完成标志
//ESP模块Reset管脚及初始化
#define AITA_ESP_RSTPINGPIO_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</code></pre>
<p> </p>
<p> aita_esp.c的代码中预留了HTTP和MQTT(旧版)连接OneNet的接口(宏),这也是以前STM32案例中创建的,本例中没有使用到。</p>
<pre>
<code>/* 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_taita_esp_buf;
//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;
AITA_ESP_CLEAR();
sprintf(atsendcmd, "AT+CIPSEND=%d\r\n", len);
if(!(aita_SendCmdESP(atsendcmd, ">")))
AITA_ESP_SEND(data, len);
}</code></pre>
<p> </p>
<p> main.c中编写了一个测试函数,非常简单——上电连接wifi、连接TCP Server、循环发送字串。</p>
<pre>
<code>//在main函数中调用
void aita_TestESP(void) {
char buf;
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);
}
}</code></pre>
<p> </p>
<p> 最后的效果如下,开了两个串口终端,一个连接USART0接收系统输出信息,一个连接到USART1(并联ESP8266 Rx脚)查看ESP接收到的AT命令。</p>
<p class="imagemiddle" style="text-align: center;"></p>
<p style="text-align:justify"> </p>
<p>归纳总结的比较好</p>
<p>楼主你好,最近在学GD32,按照您的代码复现有点问题,可以参考一下您的源码吗</p>
<p> </p>
页:
[1]