單芯片解決方案,開啟全新體驗——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 Server示例
本篇文章我們將詳細介紹如何在W55MH32芯片上面實現HTTP Server功能,并通過實戰例程,為大家講解如何通過瀏覽器修改W55MH32的網絡地址信息。
該例程用到的其他網絡協議,例如DHCP,請參考相關章節。有關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 Server應用場景
W55MH32使用HTTP Server模式可以進行以下幾種應用:
設備配置和管理:通過瀏覽器訪問W55MH32提供的WEB界面,實現網絡配置,系統參數調整,固件升級等操作。
實時監控和數據展示:通過瀏覽器訪問W55MH32提供的WEB頁面,實時監控傳感器數據,狀態信息,以及查看工作日志等。
遠程控制:通過瀏覽器訪問W55MH32提供的WEB頁面進行遠程控制設備,如開關等。
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 Web頁面的基本構成
HTML(超文本標記語言)
、、。
作用:定義網頁的結構和內容。
內容:
結構標簽:如
內容標簽:如
、
、、。
表單標簽:如 、、。
CSS(層疊樣式表)
作用:控制網頁的樣式和布局。
內容:
字體設置:如 font-family、font-size。
顏色設置:如 color、background-color。
布局設計:如 margin、padding、display、flex。
響應式設計:如媒體查詢(@media)。
JavaScript(腳本語言)
作用:增加網頁的交互性和動態功能。
應用:
表單驗證。
動畫效果。
與服務器交互(如通過 AJAX請求)。
處理用戶事件(如點擊、懸停)。
Meta信息
中。
作用:提供頁面的元數據,通常包含在
內容:
網頁標題:
字符集:。
SEO信息:如 。
設備適配:如 。
示例:
!DOCTYPE html?> Simple Page/title?> body { font-family: Arial, sans-serif; text-align: center; padding: 20px; } button { padding: 10px 20px; cursor: pointer; } /style?> /head?>Hello, Web!/h1?> Click the button for a surprise./p?> Click Me/button?> /body?> /html?>
8 Web頁面交互
Web頁面實現HTTP請求的方式:
HTTP請求頁面
描述:客戶端通過 HTTP協議向服務器發送請求,服務器處理后返回響應。
特點:
最基礎的交互方式。
包括常見的 HTTP方法:GET、POST、PUT、DELETE等。
示例:
GET請求:瀏覽器訪問網頁,獲取靜態資源(HTML、CSS、JavaScript等)。
POST請求:提交表單數據。
表單提交
描述:通過 HTML表單向服務器提交數據。
特點:
表單數據會被編碼后隨請求發送。
可使用 GET或 POST方法。
示例:
Submit/button?> /form?>
AJAX(Asynchronous JavaScript and XML)
描述:使用 JavaScript在后臺與服務器通信,更新部分頁面內容而無需刷新整個頁面。
特點:
提高用戶體驗,減少頁面加載時間。
現代開發中多用 JSON代替 XML。
示例:
fetch('/api/data', { method: 'GET' }) .then(response => response.json()) .then(data => console.log(data));
Web服務器響應處理
直接響應
定義:服務器直接處理請求,返回靜態資源或簡單的動態內容,而不調用外部腳本或程序。
特點
高效:直接處理請求,無需額外調用外部程序,適合靜態內容。
適用場景:
靜態資源(HTML、CSS、JavaScript、圖像等)的分發。
輕量級動態內容生成。
工作流程
客戶端發送 HTTP請求。
服務器解析請求 URL,查找相應的資源(如文件路徑)。
直接讀取資源內容并返回給客戶端,附加適當的 HTTP響應頭。
CGI響應
定義:服務器通過 CGI(Common Gateway Interface)調用外部程序或腳本,處理客戶端請求并生成動態響應內容。
特點
靈活性:可以動態生成內容,支持復雜邏輯。
適用場景:
動態內容生成(如用戶登錄、數據查詢)。
與數據庫交互或其他后臺服務的復雜邏輯處理。
工作流程
客戶端發送 HTTP請求。
服務器解析請求并將請求數據(如 URL參數或表單數據)傳遞給 CGI程序。
CGI程序處理請求,生成響應內容并返回給服務器。
服務器將 CGI程序生成的內容包裝為 HTTP響應發送給客戶端。
9實現過程
接下來,我們看看如何通過瀏覽器修改W55MH32的網絡配置。
注意:測試實例需要PC端和W55MH32處于同一網段。
首先需要編寫網頁內容,這里我們寫了一個網頁配置頁面的內容以及提交后等待重啟頁面的內容,如下所示:
#define index_page "n" "n" " W55MH32 Configuration Page/title?>n" " n" " body { font-family: Arial, sans-serif; margin: 20px; padding: 20px; background-color: #f4f4f9; }n" " h1 { text-align: center; color: #333; }n" " form { max-width: 400px; margin: auto; background: #ffffff; padding: 20px; border-radius: 8px; box-shadow: 0 0 10px rgba(0, 0, 0, 0.1); }n" " label { display: block; margin-bottom: 8px; font-weight: bold; }n" " input[type=text], input[type=submit] { width: 400px; padding: 8px; margin-bottom: 12px; border: 1px solid #ccc; border-radius: 4px; }n" " input[type=submit] { background-color: #4CAF50; color: white; border: none; cursor: pointer; }n" " input[type=submit]:hover { background-color: #45a049; }n" " input[readonly] { background-color: #e9ecef; color: #6c757d; border: 1px solid #ced4da; cursor: not-allowed; }n" " .error { color: red; font-size: 12px; margin-top: -10px; margin-bottom: 10px; }n" " input::placeholder { color: #aaa; font-style: italic; }n" " /style?>n" " n" " function validateForm(event) {n" " const ipPattern = /^(\d{1,3}\.){3}\d{1,3}$/;n" " let isValid = true;n" " document.querySelectorAll('.error').forEach(e => e.textContent = '');n" " const fields = ['ip', 'subnet', 'gateway', 'dns'];n" " fields.forEach(field => {n" " const input = document.forms[0][field];n" " if (input.value.trim() === '') {n" " input.placeholder = 'e.g., 192.168.1.1';n" " document.getElementById(field + '-error').textContent = 'This field is required.';n" " isValid = false;n" " } else if (!ipPattern.test(input.value)) {n" " document.getElementById(field + '-error').textContent = 'Invalid IP address format.';n" " isValid = false;n" " }n" " });n" " if (!isValid) {n" " event.preventDefault();n" " }n" " }n" " /script?>n" "/head?>n" "n" " W55MH32 Configuration Page/h1?>n" " n" " MAC Address: /label?> n" " IP Address: /label?>
n" " Subnet Mask: /label?>
n" " Default Gateway: /label?>
n" " DNS Server: /label?>
n" " n" " /form?>n" "/body?>n" "/html?>n"
這里,我們提交網絡地址信息的方式為POST,提交的地址為config.cgi:
#define CONFIG_SUCCESS_PAGE "!DOCTYPE html?>n" "n" "n" " n" " n" " Configuration Modification Succeeded/title?>n" " n" " body {n" " font-family: Arial, sans-serif;n" " text-align: center;n" " padding-top: 100px;n" " background-color: #f0f0f0; n" " }n" " h1 {n" " color: green;n" " animation: fadeInOut 2s infinite;n" " }n" " #countdown {n" " font-size: 24px;n" " margin-top: 20px;n" " opacity: 0; n" " animation: fadeIn 1s forwards;n" " animation-delay: 1s; n" " }n" " @keyframes fadeIn {n" " from {n" " opacity: 0;n" " }n" " to {n" " opacity: 1;n" " }n" " }n" " /style?>n" "/head?>n" "n" " Configuration Modification Succeeded!/h1?>n" " Will redirect in 10 seconds. Please wait.../p?>n" "n" " let seconds = 10;n" " const countdownElement = document.getElementById('countdown');n" " const countdownInterval = setInterval(() => {n" " seconds--;n" " countdownElement.textContent = `Will redirect in ${seconds} seconds. Please wait...`;n" " if (seconds === 0) {n" " clearInterval(countdownInterval);n" " window.location.href = 'http://%d.%d.%d.%d/';n" " }n" " }, 1000);n" "/script?>n" "/body?>n" "/html?>"
步驟一:從EEPROM中讀取網絡地址信息并配置
check_eeprom_network_info(&default_net_info); network_init(ethernet_buf, &default_net_info);
check_eeprom_network_info()函數的作用是檢查EEPROM中是否有網絡地址信息,如果有則賦值給default_net_info結構體。函數內容如下:
uint8_t check_eeprom_network_info(wiz_NetInfo *net_info) { wiz_NetInfo eeprom_net_info = {0}; /*-----------------------------------------------------------------------------------*/ if (ee_CheckDevice(EEPROM_DEV_ADDR) == 1) { /* No EEPROM detected */ printf("No serial EEPROM detected!rn"); return 0; } ee_ReadBytes((uint8_t *)&eeprom_net_info, 0, sizeof(eeprom_net_info)); if (eeprom_net_info.mac[0] == 0x00 && eeprom_net_info.mac[1] == 0x08 && eeprom_net_info.mac[2] == 0xdc) { memcpy(net_info, &eeprom_net_info, sizeof(wiz_NetInfo)); return 1; } return 0; }
步驟二:注冊網頁內容及HTTP Server初始化
printf("Please enter% d.% d.% d.% d in your browser to access the %s HTTP serverrn", net_info.ip[0], net_info.ip[1], net_info.ip[2], net_info.ip[3], _WIZCHIP_ID_); sprintf(mac, "%02X:%02X:%02X:%02X:%02X:%02X", net_info.mac[0], net_info.mac[1], net_info.mac[2], net_info.mac[3], net_info.mac[4], net_info.mac[5]); sprintf(ip, "%d.%d.%d.%d", net_info.ip[0], net_info.ip[1], net_info.ip[2], net_info.ip[3]); sprintf(sn, "%d.%d.%d.%d", net_info.sn[0], net_info.sn[1], net_info.sn[2], net_info.sn[3]); sprintf(gw, "%d.%d.%d.%d", net_info.gw[0], net_info.gw[1], net_info.gw[2], net_info.gw[3]); sprintf(dns, "%d.%d.%d.%d", net_info.dns[0], net_info.dns[1], net_info.dns[2], net_info.dns[3]); sprintf(page, (char *)index_page, mac, ip, sn, gw, dns); reg_httpServer_webContent((uint8_t *)"index.html", (uint8_t *)page); // Build HTTP server web pages httpServer_init(http_tx_ethernet_buf, http_rx_ethernet_buf, 1, socknumlist); // Initializing the HTTP server
reg_httpServer_webContent()函數的作用是注冊web內容,這里可以是頁面,也可以是JavaScript代碼。
httpServer_init的作用是初始化HTTP Server參數,四個參數分別是HTTP發送緩存、HTTP接收緩存、使用的SOCKET數量以及對應的SOCKET列表。
步驟三:注冊HTTP超時中斷程序
/** * @brief 1ms timer IRQ Handler * @param none * @return none */ void TIM3_IRQHandler(void) { static uint32_t tim3_1ms_count = 0; if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET) { tim3_1ms_count++; if (tim3_1ms_count >= 1000) { DHCP_time_handler(); httpServer_time_handler(); tim3_1ms_count = 0; } TIM_ClearITPendingBit(TIM3, TIM_IT_Update); } }
步驟四:運行HTTP Server程序
while (1) { httpServer_run(SOCKET_ID); }
httpServer_run()函數的邏輯跟TCP Server基本一致,也是運行了一個狀態機,根據SOCKET不同狀態,執行相應的HTTP Server部分的處理,內容如下:
void httpServer_run(uint8_t seqnum) { uint8_t s; // socket number uint16_t len; uint32_t gettime = 0; #ifdef _HTTPSERVER_DEBUG_ uint8_t destip[4] = { 0, }; uint16_t destport = 0; #endif http_request = (st_http_request *)pHTTP_RX; // Structure of HTTP Request parsed_http_request = (st_http_request *)pHTTP_TX; // Get the H/W socket number s = getHTTPSocketNum(seqnum); /* HTTP Service Start */ switch (getSn_SR(s)) { case SOCK_ESTABLISHED: // Interrupt clear if (getSn_IR(s) & Sn_IR_CON) { setSn_IR(s, Sn_IR_CON); } // HTTP Process states switch (HTTPSock_Status[seqnum].sock_status) { case STATE_HTTP_IDLE: if ((len = getSn_RX_RSR(s)) > 0) { if (len > DATA_BUF_SIZE) len = DATA_BUF_SIZE; len = recv(s, (uint8_t *)http_request, len); *(((uint8_t *)http_request) + len) = ''; parse_http_request(parsed_http_request, (uint8_t *)http_request); #ifdef _HTTPSERVER_DEBUG_ getSn_DIPR(s, destip); destport = getSn_DPORT(s); printf("rn"); printf("> HTTPSocket[%d] : HTTP Request received ", s); printf("from %d.%d.%d.%d : %drn", destip[0], destip[1], destip[2], destip[3], destport); #endif #ifdef _HTTPSERVER_DEBUG_ printf("> HTTPSocket[%d] : [State] STATE_HTTP_REQ_DONErn", s); #endif // HTTP 'response' handler; includes send_http_response_header / body function http_process_handler(s, parsed_http_request); gettime = get_httpServer_timecount(); // Check the TX socket buffer for End of HTTP response sends while (getSn_TX_FSR(s) != (getSn_TxMAX(s))) { if ((get_httpServer_timecount() - gettime) > 3) { #ifdef _HTTPSERVER_DEBUG_ printf("> HTTPSocket[%d] : [State] STATE_HTTP_REQ_DONE: TX Buffer clear timeoutrn", s); #endif break; } } if (HTTPSock_Status[seqnum].file_len > 0) HTTPSock_Status[seqnum].sock_status = STATE_HTTP_RES_INPROC; else HTTPSock_Status[seqnum].sock_status = STATE_HTTP_RES_DONE; // Send the 'HTTP response' end } break; case STATE_HTTP_RES_INPROC: /* Repeat: Send the remain parts of HTTP responses */ #ifdef _HTTPSERVER_DEBUG_ printf("> HTTPSocket[%d] : [State] STATE_HTTP_RES_INPROCrn", s); #endif // Repeatedly send remaining data to client send_http_response_body(s, 0, http_response, 0, 0); if (HTTPSock_Status[seqnum].file_len == 0) HTTPSock_Status[seqnum].sock_status = STATE_HTTP_RES_DONE; break; case STATE_HTTP_RES_DONE: #ifdef _HTTPSERVER_DEBUG_ printf("> HTTPSocket[%d] : [State] STATE_HTTP_RES_DONErn", s); #endif // Socket file info structure re-initialize HTTPSock_Status[seqnum].file_len = 0; HTTPSock_Status[seqnum].file_offset = 0; HTTPSock_Status[seqnum].file_start = 0; HTTPSock_Status[seqnum].sock_status = STATE_HTTP_IDLE; //#ifdef _USE_SDCARD_ // f_close(&fs); //#endif #ifdef _USE_WATCHDOG_ HTTPServer_WDT_Reset(); #endif http_disconnect(s); break; default: break; } break; case SOCK_CLOSE_WAIT: #ifdef _HTTPSERVER_DEBUG_ printf("> HTTPSocket[%d] : ClOSE_WAITrn", s); // if a peer requests to close the current connection #endif disconnect(s); break; case SOCK_CLOSED: if (reboot_flag) { NVIC_SystemReset(); } #ifdef _HTTPSERVER_DEBUG_ printf("> HTTPSocket[%d] : CLOSEDrn", s); #endif if (socket(s, Sn_MR_TCP, HTTP_SERVER_PORT, 0x00) == s) /* Reinitialize the socket */ { #ifdef _HTTPSERVER_DEBUG_ printf("> HTTPSocket[%d] : OPENrn", s); #endif } break; case SOCK_INIT: listen(s); break; case SOCK_LISTEN: break; default: break; } // end of switch #ifdef _USE_WATCHDOG_ HTTPServer_WDT_Reset(); #endif }
步驟五:請求內容處理
POST方式的CGI請求處理,在httpUtil.c文件的predefined_set_cgi_processor()函數中處理。
GET方式的CGI請求處理,在httpUtil.c文件的predefined_get_cgi_processor()函數中處理。
uint8_t predefined_set_cgi_processor(uint8_t *uri_name, uint8_t *uri, uint8_t *buf, uint16_t *len) { if (strcmp((const char *)uri_name, "config.cgi") == 0) { uint8_t *param; wiz_NetInfo new_net_info = {0}; wizchip_getnetinfo(&new_net_info); param = get_http_param_value((char *)uri, "ip"); //獲取IP地址 parse_ip((char *)param, new_net_info.ip); //更新IP地址 param = get_http_param_value((char *)uri, "subnet"); //獲取子網掩碼 parse_ip((char *)param, new_net_info.sn); //更新子網掩碼 param = get_http_param_value((char *)uri, "gateway"); //獲取默認網關 parse_ip((char *)param, new_net_info.gw); //更新默認網關 param = get_http_param_value((char *)uri, "dns"); //獲取DNS地址 parse_ip((char *)param, new_net_info.dns); //更新DNS地址
步驟六:重啟設備
在httpServer_run()函數中,當SOCKET處于SOCK_CLOSED狀態時(即上次請求已經處理完畢),再進行復位操作,避免出現客戶端請求后,W55MH32未響應就重啟導致客戶端請求超時的情況。
case SOCK_CLOSED: if (reboot_flag) { NVIC_SystemReset(); }
10運行結果
燒錄例程運行后,首先進行了PHY鏈路檢測,然后是通過DHCP獲取網絡地址并打印網絡地址信息,最后HTTP Server程序開始監聽客戶端的請求并處理響應,如下圖所示:
接著我們打開瀏覽器,輸入W55MH32的IP地址進行訪問。
然后我們將IP地址改為192.168.1.33,DNS服務器地址改為114.114.114.114,并點擊Submit按鈕。
等待W55MH32重啟后,瀏覽器會自動跳轉至新地址。
11總結
本文介紹了在 W55MH32芯片上實現 HTTP Server功能,并通過瀏覽器修改其網絡地址信息的方法。闡述了 HTTP協議的概念、特點、應用場景、工作流程、請求方法、響應內容,以及 Web頁面構成和交互方式。展示了在W55MH32上實現的過程。
下一篇將講解在該芯片上實現 SNTP授時功能,介紹從 SNTP服務器獲取準確時間的原理和實現步驟。敬請期待!
WIZnet是一家無晶圓廠半導體公司,成立于 1998年。產品包括互聯網處理器 iMCU?,它采用 TOE(TCP/IP卸載引擎)技術,基于獨特的專利全硬連線 TCP/IP。iMCU?面向各種應用中的嵌入式互聯網設備。
WIZnet在全球擁有 70多家分銷商,在香港、韓國、美國設有辦事處,提供技術支持和產品營銷。
香港辦事處管理的區域包括:澳大利亞、印度、土耳其、亞洲(韓國和日本除外)。
審核編輯 黃宇
-
嵌入式
+關注
關注
5153文章
19708瀏覽量
318051
發布評論請先 登錄
第三十章 W55MH32 HTTP_Server&NetBIOS示例

第二十九章 W55MH32 Modbus_TCP_Server示例

第二十六章 W55MH32?上位機搜索和配置示例

第十八章 W55MH32 FTP_Server示例

第十七章 W55MH32 ARP示例

第十六章 W55MH32 PING示例

第十五章 W55MH32 SNMP示例

第十四章 W55MH32 TFTP示例

第十二章 W55MH32 NetBIOS示例

第十章 W55MH32 SNTP示例

第六章 W55MH32 UDP?Multicast示例

第五章 W55MH32 UDP示例

第三章 W55MH32 TCP Client示例

第二章 W55MH32 DHCP示例

W55MH32高性能以太網單片機教程 第九章 窗口看門狗(WWDG)

評論