單芯片解決方案,開啟全新體驗——W55MH32 高性能以太網單片機
W55MH32是WIZnet重磅推出的高性能以太網單片機,它為用戶帶來前所未有的集成化體驗。這顆芯片將強大的組件集于一身,具體來說,一顆W55MH32內置高性能Arm? Cortex-M3核心,其主頻最高可達216MHz;配備1024KB FLASH與96KB SRAM,滿足存儲與數據處理需求;集成TOE引擎,包含WIZnet全硬件TCP/IP協議棧、內置MAC以及PHY,擁有獨立的32KB以太網收發緩存,可供8個獨立硬件socket使用。如此配置,真正實現了All-in-One解決方案,為開發者提供極大便利。
在封裝規格上,W55MH32提供了兩種選擇:QFN100和QFN68。
W55MH32L采用QFN100封裝版本,尺寸為12x12mm,其資源豐富,專為各種復雜工控場景設計。它擁有66個GPIO、3個ADC、12通道DMA、17個定時器、2個I2C、5個串口、2個SPI接口(其中1個帶I2S接口復用)、1個CAN、1個USB2.0以及1個SDIO接口。如此豐富的外設資源,能夠輕松應對工業控制中多樣化的連接需求,無論是與各類傳感器、執行器的通信,還是對復雜工業協議的支持,都能游刃有余,成為復雜工控領域的理想選擇。同系列還有QFN68封裝的W55MH32Q版本,該版本體積更小,僅為8x8mm,成本低,適合集成度高的網關模組等場景,軟件使用方法一致。更多信息和資料請進入http://www.w5500.com/網站或者私信獲取。
此外,本W55MH32支持硬件加密算法單元,WIZnet還推出TOE+SSL應用,涵蓋TCP SSL、HTTP SSL以及 MQTT SSL等,為網絡通信安全再添保障。
為助力開發者快速上手與深入開發,基于W55MH32L這顆芯片,WIZnet精心打造了配套開發板。開發板集成WIZ-Link芯片,借助一根USB C口數據線,就能輕松實現調試、下載以及串口打印日志等功能。開發板將所有外設全部引出,拓展功能也大幅提升,便于開發者全面評估芯片性能。
若您想獲取芯片和開發板的更多詳細信息,包括產品特性、技術參數以及價格等,歡迎訪問官方網頁:http://www.w5500.com/,我們期待與您共同探索W55MH32的無限可能。

第八章 W55MH32 HTTP Client示例
本篇文章我們將詳細介紹如何在W55MH32芯片上面實現HTTP Client功能,并通過實戰例程,為大家講解如何向一個指定的網站提交數據。為方便講解,在該例程中,我們選用了一個專門測試HTTP協議的網站:httpbin.org,并實現了GET和POST這兩種常用的HTTP提交數據的方法,供大家參考。
該例程用到的其他網絡協議,例如DHCP和DNS,以及W55MH32的初始化過程,請參考相關章節,這里不再贅述。
1 HTTP協議簡介
HTTP(超文本傳輸協議,HyperText Transfer Protocol)是一種用于分布式、協作式、超媒體信息系統的應用層協議,基于 TCP/IP通信協議來傳遞數據,是萬維網(WWW)的數據通信的基礎。設計 HTTP最初的目的是為了提供一種發布和接收 HTML頁面的方法,通過 HTTP或者 HTTPS協議請求的資源由統一資源標識符(Uniform Resource Identifiers,URI)來標識。
以上是HTTP協議的簡介,如想深入了解該協議,請參考mozilla網站上的介紹:HTTP 概述 - HTTP | MDN
2 HTTP協議特點
基于請求-響應模型:客戶端發起請求,服務器處理后返回響應。例如,用戶在瀏覽器輸入網址時,瀏覽器會向對應服務器發送HTTP請求,服務器返回網頁內容。
無狀態性:HTTP本身不保存請求之間的狀態,每次請求獨立。但可以通過Cookie、Session等機制實現狀態保持。
無連接:無連接的含義是限制每次連接只處理一個請求。服務器處理完客戶的請求并收到客戶的應答后,便立即斷開連接。
3 HTTP應用場景
接下來,我們了解下在W55MH32上可以使用HTTP客戶端模式完成哪些操作及應用呢?
數據采集與上傳:將傳感器采集到的數據上傳到服務器中。
遠程配置與管理:通過向服務器上請求配置文件或者管理指令,實現遠程管理和控制。例如工控設備獲取最新的運行策略或指令。
固件更新(OTA):通過向服務器請求下載最新的固件包,實現遠程升級固件的功能。
日志和錯誤報告上傳:定時上傳系統運行日志,用于分析設備狀態,或在出現異常情況時上傳錯誤報告,方便快速定位和解決問題。
用戶認證與授權管理:通過服務器進行交互,驗證用戶或設備的身份。
4 HTTP協議的基本工作流程
HTTP的請求-響應模型通常由以下幾個步驟組成
建立連接:客戶端與服務器之間基于TCP/IP協議建立連接。
發送請求:客戶端向服務器發送請求,請求中包含要訪問的資源的 URL、請求方法(GET、POST、PUT、DELETE 等)、請求頭(例如,Accept、User-Agent)以及可選的請求體(對于 POST或 PUT 請求)。
處理請求:服務器接收到請求后,根據請求中的信息找到相應的資源,執行對應的處理操作。這可能涉及從數據庫中檢索數據、生成動態內容或者簡單地返回靜態文件。
發送響應:服務器將處理后的結果封裝在響應中,并將其發送回客戶端。響應包含狀態碼(用于指示請求的成功或失敗)、響應頭(例如,Content-Type、Content-Length)以及可選的響應體(例如,HTML 頁面、圖像數據)。
關閉連接:在完成請求-響應周期后,客戶端和服務器之間的連接將被關閉,除非使用了持久連接(如 HTTP/1.1中的 keep-alive)。
5 HTTP請求方法
在HTTP協議中,GET和POST是兩種常用的請求方法,用于客戶端向服務器發送數據和獲取資源。
GET方法
GET方法通常用于從服務器獲取資源。它有以下特點:
參數傳遞:請求參數通過URL中的查詢字符串傳遞,形如?key1=value1&key2=value2。
數據大小限制:由于參數附加在URL后,長度可能受URL長度限制(取決于瀏覽器和服務器設置)。
安全性:數據在URL中明文顯示,不適合傳遞敏感信息。
請求格式:
GET HTTP/
Request-URI:表示目標資源的路徑,可能包含參數。
Version:HTTP協議版本。
Headers:包含元信息,例如客戶端的屬性、支持的格式等。
Blank Line:空行。
POST方法
POST方法通常用于向服務器提交數據。它有以下特點:
參數傳遞:數據放在請求體中,而不是URL中。
數據大小限制:POST請求的體積沒有明顯限制,可以傳遞大量數據。
安全性:數據在請求體中傳輸,相對來說更安全。
請求格式:
POST HTTP/
Request-URI:目標資源的路徑,通常是API的端點。
Headers:元信息,例如內容類型和長度。
Blank Line:空行,區分頭和主體。
Body:數據的主體,包含客戶端發送到服務器的長度。
6 HTTP協議響應內容
HTTP協議響應內容包含狀態行、響應頭以及響應體三個部分。
狀態行
HTTP狀態行包含HTTP協議版本、狀態碼以及狀態描述。
狀態碼由三個十進制數字組成,第一個十進制數字定義了狀態碼的類型。
狀態碼分為五類:
1xx(信息性狀態碼):表示接收的請求正在處理。
2xx(成功狀態碼):表示請求正常處理完畢。
3xx(重定向狀態碼):需要后續操作才能完成這一請求。
4xx(客戶端錯誤狀態碼):表示請求包含語法錯誤或無法完成。
5xx(服務器錯誤狀態碼):服務器在處理請求的過程中發生了錯誤。
示例:
HTTP/1.1 200 OK
響應頭
響應頭則會包含內容類型、長度、編碼等信息。
常見的響應頭字段有:
Content-Type:響應內容的MIME類型,例如 text/html、application/json。
Content-Length:響應內容的字節長度。
Server:服務器信息。
Set-Cookie:設置客戶端的Cookie。
示例:
Content-Type: text/html; charset=UTF-8 Content-Length: 3495 Server: Apache/2.4.41 (Ubuntu)
響應體
響應體包含實際的數據內容,具體形式取決于響應的類型和請求內容。例如:HTML頁面內容,JSON數據,文件的二進制數據等。
如果是狀態碼為204 No Content或 304 Not Modified的響應,則通常沒有正文。
注意:響應體和響應頭之間會添加一個空行來分隔內容。
7 HTTP請求及響應實例
GET請求示例如下:
//請求
GET /get?username=admin&password=admin HTTP/1.1
Host:httpbin.org
//響應
HTTP/1.1 200 OK
Date: Tue, 10 Dec 2024 10:41:13 GMT
Content-Type: application/json
Content-Length: 278
Connection: keep-alive
Server: gunicorn/19.9.0
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true
{
"args": {
"password": "admin",
"username": "admin"
},
"headers": {
"Host": "httpbin.org",
"X-Amzn-Trace-Id": "Root=1-67581ac9-236349c67cb21dcc24c54215"
},
"origin": "118.99.2.9",
"url": "http://httpbin.org/get?username=admin&password=admin"
}
POST請求示例如下:
//請求
POST /post HTTP/1.1
Host:httpbin.org
Content-Type:application/x-www-form-urlencode
Content-Length:29
username=admin&password=admin
//響應
HTTP/1.1 200 OK
Date: Tue, 10 Dec 2024 10:44:52 GMT
Content-Type: application/json
Content-Length: 374
Connection: keep-alive
Server: gunicorn/19.9.0
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true
{
"args": {},
"data": "username=admin&password=admin",
"files": {},
"form": {},
"headers": {
"Content-Length": "29",
"Content-Type": "application/x-www-form-urlencode",
"Host": "httpbin.org",
"X-Amzn-Trace-Id": "Root=1-67581ba4-744fdecf1da1bcf3180f9fa3"
},
"json": null,
"origin": "118.99.2.9",
"url": "http://httpbin.org/post"
}
8實現過程
接下來,我們看看如何在W55MH32上實現HTTP客戶端模式發送GET和POST請求示例。
注意:因為本示例需要訪問互聯網,請確保W55MH32的網絡環境及配置能夠正常訪問互聯網。
例程中使用的是httpbin.org的服務器,它的get請求路徑為httpbin.org/get,post請求路徑為httpbin.org/post。
我們向httpbin.org發送請求后,它會把我們請求時提交的參數體現在響應內容中。
步驟一:通過DNS協議解析HTTP服務器的域名
在利用 HTTP向httpbin.org服務器提交數據時,首先要與該服務器建立 TCP鏈接。要知道,建立 TCP鏈接是必須基于 IP地址來進行連接操作的。而此處的 do_dns ()所承擔的任務,正是借助 DNS協議對域名進行解析,進而獲取到相應 IP地址的過程。
if (do_dns(ethernet_buf, org_server_name, org_server_ip)) { printf("DNS request failed.rn"); while (1) { } }
步驟二:進行HTTP GET和POST請求組包
接下來,我們需要按前面介紹的HTTP協議的規范來組包。
本例程中,我們定義了兩個函數來分別生產HTTP GET Header()和HTTP POST Header()。詳細代碼如下:
/**
* @brief HTTP GET : Request package combination package.
* @param pkt: Array cache for grouping packages
* @return pkt: Package length
*/
uint32_t http_get_pkt(uint8_t *pkt)
{
*pkt = 0;
// request type URL HTTP protocol version
strcat((char *)pkt, "GET /get?username=admin&password=admin HTTP/1.1rn");
// Host address, which can be a domain name or a specific IP address.
strcat((char *)pkt, "Host: httpbin.orgrn");
// end
strcat((char *)pkt, "rn");
return strlen((char *)pkt);
}
/**
* @brief HTTP POST : Request package combination package.
* @param pkt: Array cache for grouping packages
* @return pkt: Package length
*/
uint32_t http_post_pkt(uint8_t *pkt)
{
*pkt = 0;
// request type URL HTTP protocol version
strcat((char *)pkt, "POST /post HTTP/1.1rn");
// Host address, which can be a domain name or a specific IP address.
strcat((char *)pkt, "Host: httpbin.orgrn");
// Main content format
strcat((char *)pkt, "Content-Type:application/x-www-form-urlencodern");
// Main content lenght
strcat((char *)pkt, "Content-Length:29rn");
// separator
strcat((char *)pkt, "rn");
// main content
strcat((char *)pkt, "username=admin&password=admin");
return strlen((char *)pkt);
}
步驟三:發送HTTP請求以及超時和響應內容處理
len = http_get_pkt(ethernet_buf); do_http_request(SOCKET_ID, ethernet_buf, len, org_server_ip, org_port); // Send a POST request. len = http_post_pkt(ethernet_buf); do_http_request(SOCKET_ID, ethernet_buf, len, org_server_ip, org_port);
do_http_request()函數為發送HTTP請求并監聽響應,具體內容如下:
/**
* @brief HTTP Client get data stream test.
* @param sn: socket number
* @param buf: request message content
* @param len request message length
* @param destip: destion ip
* @param destport: destion port
* @return 0:timeout,1:Received response..
*/
uint8_t do_http_request(uint8_t sn, uint8_t *buf, uint16_t len, uint8_t *destip, uint16_t destport)
{
uint16_t local_port = 50000;
uint16_t recv_timeout = 0;
uint8_t send_flag = 0;
while (1)
{
switch (getSn_SR(sn))
{
case SOCK_INIT:
// Connect to http server.
connect(sn, destip, destport);
break;
case SOCK_ESTABLISHED:
if (send_flag == 0)
{
// send request
send(sn, buf, len);
send_flag = 1;
printf("send request:rn");
for (uint16_t i = 0; i < len; i++)
{
printf("%c", *(buf + i));
}
printf("rn");
}
// Response content processing
len = getSn_RX_RSR(sn);
if (len > 0)
{
printf("Receive response:rn");
while (len > 0)
{
len = recv(sn, buf, len);
for (uint16_t i = 0; i < len; i++)
{
printf("%c", *(buf + i));
}
len = getSn_RX_RSR(sn);
}
printf("rn");
disconnect(sn);
close(sn);
return 1;
}
else
{
recv_timeout++;
delay_ms(1000);
}
// timeout handling
if (recv_timeout > 10)
{
printf("request fail!rn");
disconnect(sn);
close(sn);
return 0;
}
break;
case SOCK_CLOSE_WAIT:
// If there is a request error, the server will immediately send a close request,
// so the error response content needs to be processed here.
len = getSn_RX_RSR(sn);
if (len > 0)
{
printf("Receive response:rn");
while (len > 0)
{
len = recv(sn, buf, len);
for (uint16_t i = 0; i < len; i++)
{
printf("%c", *(buf + i));
}
len = getSn_RX_RSR(sn);
}
printf("rn");
disconnect(sn);
close(sn);
return 1;
}
close(sn);
break;
case SOCK_CLOSED:
// close socket
close(sn);
// open socket
socket(sn, Sn_MR_TCP, local_port, 0x00);
break;
default:
break;
}
}
}
在該函數中,程序會執行一個TCP Client模式的狀態機,具體詳細講解請看TCP Client示例章節,當程序處于SOCK_ESTABLISHED狀態時,會發送1次請求內容到服務器。接著就是監聽服務器響應數據以及超時處理。
如果服務器返回異常響應,則會立即關閉鏈接,因此我們需要在SOCK_CLOSE_WAIT狀態中處理服務器異常響應的內容。
9運行結果
燒錄例程運行后,首先可以看到打印了PHY鏈路檢測和DHCP獲取網絡信息,然后是DNS解析HTTP服務器域名結果,如下圖所示:

接著我們發送了一次GET請求報文,然后HTTP服務器返回了響應報文。
請求和響應原文都通過串口打印出來,如下圖所示:

最后,我們發送了一次POST請求報文,然后HTTP服務器返回了響應報文。
請求和響應原文都通過串口打印出來,如下圖所示:

10總結
本文介紹了在 W55MH32芯片上實現 HTTP Client功能的方法,實現向httpbin.org網站獲取數據。闡述了 HTTP協議的概念、特點、應用場景、工作流程、請求方法、響應內容,并給出請求及響應實例。以及展示了在W55MH32上的實現過程。
下一篇將講解在該芯片上實現 HTTP Server功能,介紹通過瀏覽器修改 W55MH32網絡地址信息的原理和實現步驟。敬請期待!
WIZnet是一家無晶圓廠半導體公司,成立于 1998年。產品包括互聯網處理器 iMCU?,它采用 TOE(TCP/IP卸載引擎)技術,基于獨特的專利全硬連線 TCP/IP。iMCU?面向各種應用中的嵌入式互聯網設備。
WIZnet在全球擁有 70多家分銷商,在香港、韓國、美國設有辦事處,提供技術支持和產品營銷。
香港辦事處管理的區域包括:澳大利亞、印度、土耳其、亞洲(韓國和日本除外)。
審核編輯 黃宇
-
HTTP
+關注
關注
0文章
537瀏覽量
35345 -
Client
+關注
關注
0文章
13瀏覽量
9297
發布評論請先 登錄
信號發生電路基礎 第八章
第二章 W55MH32 DHCP示例
第五章 W55MH32 UDP示例
第九章 W55MH32 HTTP Server示例
第十五章 W55MH32 SNMP示例
第十八章 W55MH32 FTP_Server示例
第三十章 W55MH32 HTTP_Server&NetBIOS示例
第八章 W55MH32 HTTP Client示例
評論