快速上手!STM32实战教程之Web服务器实现 (stm32 web服务器教程)

随着物联网的普及,越来越多的设备需要通过Web访问来控制和监控。如何在嵌入式系统上实现一个高效稳定的Web服务器,成为了一个不可避免的问题。本文将介绍如何使用STM32系列微控制器实现一个简单的Web服务器,并通过实例演示如何实现一个具有实际应用价值的远程控制系统。

一、STM32开发环境搭建

为了使用STM32开发板实现Web服务器,我们需要先准备好必要的开发环境。此处以Windows平台为例,其他操作系统类似。

1. 软件准备

a) Keil MDK-ARM

Keil MDK-ARM是一款由英国Keil公司开发的 Cortex-M 系列微控制器开发环境,通过其专业的C语言编译器和强大的单片机仿真调试功能,可以轻松实现STM32的开发。

b) ST-LINK驱动程序

ST-LINK是ST公司推出的一款仿真调试接口,可与Keil等开发软件相连,用于下载程序和调试。在Windows下,需要安装相应的驱动程序。

c) sCons

sCons是一款功能强大的构建工具,可以自动化构建和管理工程,能够有效提高开发效率。

2. 硬件准备

a) STM32开发板

根据实际需求选择相应的STM32开发板,例如STM32F103ZET6开发板等。

b) 网络模块

为了实现Web服务器功能,我们需要一个支持TCP/IP协议栈的网络模块。

二、Web服务器实现

1. 基础功能实现

为了实现Web服务器功能,我们需要先实现网络通信的基础功能。这里使用W5500网络模块,具体实现过程如下。

a) 硬件连接

将W5500模块与STM32开发板相连接,具体连接方式如下。

W5500模块 | STM32开发板

———-|————-

MISO | PA6

MOSI | PA7

SCK | PA5

SS | PA4

RST | PA3

INT | PA2

VCC | VCC

GND | GND

b) 网络初始化

在mn函数中添加以下代码,用于初始化网络模块。

int mn(void)

{

NVIC_SetPriorityGrouping(NVIC_PriorityGroup_4);

W5500_Init();

//….

}

其中W5500_Init()函数用于初始化网络模块。

c) 建立TCP连接

在socket模块中添加以下代码,用于建立TCP连接。

if(sockstat == SOCK_UCAST_CLOSE_WT)

{

if((ret = connect(sn, destip, destport)) == SOCK_OK)

{

sockstat = SOCK_UCAST_ESTABLISHED;

}

}

其中,sn是SOCKET号,destip和destport是服务器的IP地址和端口号。

2. 远程控制系统实现

了解了Web服务器的基础功能,我们换一个角度思考,如何在嵌入式系统上实现一个具有实际价值的远程控制系统。下面是基于Web服务器的智能家居控制系统实现过程。

a) 硬件连接

在STM32开发板上加入控制模块(例如LED灯),并将模块与W5500模块相连接。具体连接方式如下。

W5500模块 | LED模块

———-|————-

INT | –

RST | –

SCK | SCK

MISO | MISO

MOSI | MOSI

SS | CS

VCC | VCC

GND | GND

b) 系统设计

通过Web浏览器访问服务器,将显示一个包含控制按钮的页面。用户单击按钮可以控制对应的LED灯亮灭。具体实现过程如下。

c) 网页设计

在Web服务器上建立一个名为“control.html”的页面,页面上添加两个按钮和一个文本框,用于提示控制状态。

控制按钮的代码如下。

其中,id属性用于给按钮一个唯一的标识,onclick属性用于定义按钮单击时的操作,sendCmd()函数将发送一个控制命令给服务器。

文本框代码如下。

其中,id属性用于给文本框一个唯一的标识,rows和cols属性用于设置文本框的大小,readonly属性用于设置文本框为只读模式。

d) 发送命令

在Web浏览器中单击按钮时,将调用sendCmd()函数,该函数将发送一个HTTP GET请求给Web服务器,请求的路径为“/control.cgi?cmd=[on|off]”,其中cmd参数表示控制命令(on表示打开LED灯,off表示关闭LED灯)。

void sendCmd(char *cmd)

{

char path[32];

sprintf(path, “/control.cgi?cmd=%s”, cmd);

uint8_t txbuf[1400];

memset(txbuf, 0, sizeof(txbuf));

//…

sprintf((char*)txbuf, GET_TEMPLATE, path, ip2str(ipaddr), port);

if((len = send(ch, txbuf, strlen((char*)txbuf), 0)) == SOCKET_ERROR)

{

return;

}

}

其中,GET_TEMPLATE为一个字符串常量,定义如下。

#define GET_TEMPLATE “GET %s HTTP/1.1\r\nHost: %s:%d\r\nUser-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:50.0) Gecko/20230101 Firefox/50.0\r\nAccept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\nAccept-Language: en-US,en;q=0.5\r\nAccept-Encoding: gzip, deflate\r\nConnection: keep-alive\r\nUpgrade-Insecure-Requests: 1\r\n\r\n”

e) 处理命令

Web服务器收到来自Web浏览器的请求后,将调用相应的处理函数进行处理。在此处,我们先将请求的路径(即控制命令)解析出来,再调用相应的控制函数。

void handle_request(uint8_t ch, uint8_t *rxbuf, uint16_t len, uint8_t *ipaddr, uint16_t port)

{

//解析请求中的路径,获取控制命令

char *pcmd = strstr((char*)rxbuf, “cmd=”);

if(pcmd != NULL)

{

if(strncmp(pcmd + 4, “on”, 2) == 0)

{

led_on();

send_response(ch, “application/json”, “{\”status\”:\”ok\”,\”result\”:\”on\”}”);

}

else if(strncmp(pcmd + 4, “off”, 3) == 0)

{

led_off();

send_response(ch, “application/json”, “{\”status\”:\”ok\”,\”result\”:\”off\”}”);

}

else

{

send_response(ch, “application/json”, “{\”status\”:\”error\”,\”result\”:\”invalid command\”}”);

}

}

}

其中,led_on()和led_off()函数分别用于控制LED灯打开和关闭。

f) 响应命令

Web服务器处理完成命令后,需要将结果返回给Web浏览器。在此处,我们将使用ON格式返回响应信息。

void send_response(uint8_t ch, char *content_type, char *response)

{

uint8_t txbuf[1400];

memset(txbuf, 0, sizeof(txbuf));

char *header = “”

“HTTP/1.1 200 OK\r\n”

“Server: STM32 WebServer\r\n”

“Content-Type: %s\r\n”

“Cache-Control: no-cache\r\n”

“Content-Length: %d\r\n”

“Connection: keep-alive\r\n”

“\r\n”;

char *body = response;

int len = sprintf((char*)txbuf, header, content_type, strlen(body));

memcpy(txbuf + len, body, strlen(body));

if((send(ch, txbuf, len + strlen(body), 0)) == SOCKET_ERROR)

{

return;

}

}

三、

通过上述实例,我们了解了如何使用STM32系列微控制器实现一个简单的Web服务器,并通过演示如何实现一个具有实际应用价值的远程控制系统。为使该系统更加完善,我们还可以增加用户认证、消息推送等功能,以满足不同的应用场景。


数据运维技术 » 快速上手!STM32实战教程之Web服务器实现 (stm32 web服务器教程)