要注意的是,
不是每条 AT 指令都具备上面 4 种类型,具体要去看该条 AT 指令的说明。
使用双引号表示字符串数据。比如“123”,就是一个字符串,而 123 就是数字。
开头的 AT 指令两个字符必须大写,每条命令以回车换行符结尾“\r\n”
ESP8266 的 AT 指令集又分为:基础 AT 命令(对模块的配置,串口设置等),WIFI 功能 AT 命令(设置 wifi 模式,连接 AP
等),TCP/IP 功能 AT 命令(建立 TCP 连接,收发数据等)。
作为 TCP 客户端工作
模块初始化
程序上电运行后,在开始使用 WIFI 模块前,必须先对其进行初始化。除了 GPIO 口以及串口的初始化外,还需要对 WIFI 模
块进行配置,使其工作在我们希望的模式下。在 STM32 FOTA demo 里 ESP8266 应该工作在 STATION 模式和多连接模式下。
所以在初始化的时候,需要通过相应的 AT 指令进行配置。下面是初始化的代码以及 AT 指令执行的过程。
ESP8266_StatusTypeDef ESP8266_Init(void)
{
ESP8266_StatusTypeDef Ret;
/* Configuration the IO low layer */
if (ESP8266_IO_Init() < 0)
{
return ESP8266_ERROR;
}
/* Disable the Echo mode */
/* Construct the command */
memset (AtCmd, '\0', MAX_AT_CMD_SIZE);
sprintf((char *)AtCmd, "ATE0%c%c", '\r', '\n');
/* Send the command */
Ret = runAtCmd(AtCmd, strlen((char *)AtCmd), (uint8_t*)AT_OK_STRING,NULL);
/* Exit in case of error */
if (Ret != ESP8266_OK)
{
return ESP8266_ERROR;
}
关回显功能
设置 wifi 模块工作在 STATION 模式
/* Setup the module in Station Mode*/
/* Construct the command */
memset (AtCmd, '\0', MAX_AT_CMD_SIZE);
sprintf((char *)AtCmd, "AT+CWMODE=1%c%c", '\r', '\n');
/* Send the command */
Ret = runAtCmd(AtCmd, strlen((char *)AtCmd), (uint8_t*)AT_OK_STRING,NULL);
//colse all socket connection
if(ESP8266_CheckMUXStatus()==1)
{
uint8_t i=0;
for(i=0;i<4;i++)
{
ESP8266_CloseConnection(i); //don't check and return the returned status
}
}
else //this application is mult-connection application,if MUXMODE is 0,it means this is
the first time run
ESP8266_SetMuxMode(1);
return Ret;
}
AT 指令的运行记录:
设置多连接模式
关回显功能
设置 wifi 模块工作在 STATION 模式
设置多连接模式
连接到 AP
调用 ESP8266_JoinAccessPoint 函数,输入 AP 的 SSID 和密码,连接到对应的 wifi 热点。
ESP8266_StatusTypeDef ESP8266_JoinAccessPoint(uint8_t* Ssid, uint8_t* Password)
{
ESP8266_StatusTypeDef Ret;
/* List all the available Access points first
then check whether the specified 'ssid' exists among them or not.*/
memset(AtCmd, '\0', MAX_AT_CMD_SIZE);
sprintf((char *)AtCmd, "AT+CWJAP_DEF=\"%s\",\"%s\"%c%c", Ssid, Password, '\r', '\n');
/* Send the command */
Ret = runAtCmd(AtCmd, strlen((char *)AtCmd), (uint8_t*)AT_OK_STRING,NULL);
return Ret;
}
AT 指令运行记录:
设置 WIFI 热点的 SSID 和
密码,开始连接
返回:连接成功
上图的黄色部分是 WIFI 模块的返回状态。必须要接收到"OK\r\n",才能去读取 IP 地址。连接 WIFI 热点的过程,需要的时长
不一定,有时 2、,3 秒,有时 6、,7 秒。所以这里最好把等待的时间 留长一点,否则经常会出现连接 WIFI 热点失败的情况。
与服务器建立连接
连接到 WIFI 热点后,就可以开始与服务器建立连接了。ESP8266 支持 5 个并发连接。
一般我们知道的不是目标服务器的 IP 地址,而是域名。所以在开始创建连接之前需要先通过 DNS 服务获该取域名对应的 IP
地址。ESP8266 也提供了相应的 AT 指令。
下面是代码中的一段和建立连接相关的代码:
域名解析
if (WIFI_GetHostAddress((char *)hostname, ip_addr) != WIFI_STATUS_OK)
{
// TODO: Defect report on WIFI_GetHostAddress() which return code is not
informative.
// NB: This blocking call may take several seconds before returning. An
asynchronous interface should be added.
msg_info("The address of %s could not be resolved.\n", hostname);
rc = NET_ERR;
}
else
{
if( WIFI_STATUS_OK == WIFI_OpenClientConnection(
(uint32_t) sock->underlying_sock_ctxt, WIFI_TCP_PROTOCOL, "", ip_addr,
dstport, 0) )
{
rc = NET_OK;
}
else
{
underlying_socket_busy[(int) sock->underlying_sock_ctxt] = false;
msg_error("Failed opening the underlying Wifi socket %d.\n", (int) sock-
>underlying_sock_ctxt);
sock->underlying_sock_ctxt = (net_sockhnd_t) -1;
}
根据获得的 IP 地址
连接服务器
}
AT 指令运行记录:
域名解析
获得服务器的 IP 地址
向服务器发起连接,指明网络连接通道的 ID 号
连接成功
发送数据
发送数据过程分两步:
1.发送 AT+CIPSEND=,命令。说明要往哪个 socket 通道,发送多少字节的数据。
2.收到 WIFI 模块返回的"OK\r\n>"后,再发送数据。
下面是例程中,ESP8266 发送数据的代码实现。
准备发送数据,等待 WIFI
模块发的“发送数据提示符”
ESP8266_StatusTypeDef ESP8266_SendData(uint8_t socket,uint8_t* Buffer, uint32_t Length)
{
ESP8266_StatusTypeDef Ret = ESP8266_OK;
if (Buffer != NULL)
{
/* Construct the CIPSEND command */
memset(AtCmd, '\0', MAX_AT_CMD_SIZE);
sprintf((char *)AtCmd, "AT+CIPSEND=%lu,%lu%c%c", socket,Length, '\r', '\n');
/* The CIPSEND command doesn't have a return command
until the data is actually sent. Thus we check here whether
we got the '>' prompt or not. */
Ret = runAtCmd(AtCmd, strlen((char *)AtCmd), (uint8_t*)AT_SEND_PROMPT_STRING,NULL);
/* Return Error */
if (Ret != ESP8266_OK)
return ESP8266_ERROR;
/* Send the data */
Ret = runAtCmd(Buffer, Length, (uint8_t*)AT_SEND_OK_STRING,NULL);
{
}