單芯片解決方案,開啟全新體驗(yàn)——W55MH32 高性能以太網(wǎng)單片機(jī)
W55MH32是WIZnet重磅推出的高性能以太網(wǎng)單片機(jī),它為用戶帶來前所未有的集成化體驗(yàn)。這顆芯片將強(qiáng)大的組件集于一身,具體來說,一顆W55MH32內(nèi)置高性能Arm? Cortex-M3核心,其主頻最高可達(dá)216MHz;配備1024KB FLASH與96KB SRAM,滿足存儲(chǔ)與數(shù)據(jù)處理需求;集成TOE引擎,包含WIZnet全硬件TCP/IP協(xié)議棧、內(nèi)置MAC以及PHY,擁有獨(dú)立的32KB以太網(wǎng)收發(fā)緩存,可供8個(gè)獨(dú)立硬件socket使用。如此配置,真正實(shí)現(xiàn)了All-in-One解決方案,為開發(fā)者提供極大便利。
在封裝規(guī)格上,W55MH32 提供了兩種選擇:QFN100和QFN68。
W55MH32L采用QFN100封裝版本,尺寸為12x12mm,其資源豐富,專為各種復(fù)雜工控場(chǎng)景設(shè)計(jì)。它擁有66個(gè)GPIO、3個(gè)ADC、12通道DMA、17個(gè)定時(shí)器、2個(gè)I2C、5個(gè)串口、2個(gè)SPI接口(其中1個(gè)帶I2S接口復(fù)用)、1個(gè)CAN、1個(gè)USB2.0以及1個(gè)SDIO接口。如此豐富的外設(shè)資源,能夠輕松應(yīng)對(duì)工業(yè)控制中多樣化的連接需求,無論是與各類傳感器、執(zhí)行器的通信,還是對(duì)復(fù)雜工業(yè)協(xié)議的支持,都能游刃有余,成為復(fù)雜工控領(lǐng)域的理想選擇。 同系列還有QFN68封裝的W55MH32Q版本,該版本體積更小,僅為8x8mm,成本低,適合集成度高的網(wǎng)關(guān)模組等場(chǎng)景,軟件使用方法一致。更多信息和資料請(qǐng)進(jìn)入http://www.w5500.com/網(wǎng)站或者私信獲取。
此外,本W(wǎng)55MH32支持硬件加密算法單元,WIZnet還推出TOE+SSL應(yīng)用,涵蓋TCP SSL、HTTP SSL以及 MQTT SSL等,為網(wǎng)絡(luò)通信安全再添保障。
為助力開發(fā)者快速上手與深入開發(fā),基于W55MH32L這顆芯片,WIZnet精心打造了配套開發(fā)板。開發(fā)板集成WIZ-Link芯片,借助一根USB C口數(shù)據(jù)線,就能輕松實(shí)現(xiàn)調(diào)試、下載以及串口打印日志等功能。開發(fā)板將所有外設(shè)全部引出,拓展功能也大幅提升,便于開發(fā)者全面評(píng)估芯片性能。
若您想獲取芯片和開發(fā)板的更多詳細(xì)信息,包括產(chǎn)品特性、技術(shù)參數(shù)以及價(jià)格等,歡迎訪問官方網(wǎng)頁:http://www.w5500.com/,我們期待與您共同探索W55MH32的無限可能。
第五章 GPIO輸出——使用固件庫點(diǎn)亮LED
本章參考資料:《W55MH32-參考手冊(cè)》GPIO和RCC章節(jié)、庫幫助文檔。
利用庫建立好的工程模板,就可以方便地使用標(biāo)準(zhǔn)庫編寫應(yīng)用程序了,可以說從這一章我們真正開始邁入固件庫開發(fā)的大門。LED燈的控制使用到GPIO外設(shè)的基本輸出功能。
5.1 硬件設(shè)計(jì)
在本教程中W55MH32芯片與LED燈的連接見圖LED硬件原理圖 :
此電路為參考電路,這個(gè)LED燈的陰極都是連接到W55MH32的GPIO引腳,只要我們控制GPIO引腳的電平輸出狀態(tài),即可控制LED燈的亮滅。若您使用的實(shí)驗(yàn)板LED燈的連接方式或引腳不一樣, 只需根據(jù)我們的工程修改引腳即可,程序的控制原理相同。
5.2 軟件設(shè)計(jì)
5.2.1 編程要點(diǎn)
2.初始化GPIO目標(biāo)引腳為推挽輸出模式;
3.編寫簡單測(cè)試程序,控制GPIO引腳輸出高、低電平。
5.2.2 代碼分析
1. 頭文件與宏定義
#include #include #include #include "delay.h" #include "w55mh32.h" #define GPIO_GROUP_TEST GPIOB // 使用GPIOB #define GPIO_MODE_TEST GPIO_Mode_Out_PP // 推挽輸出模式 #define GPIO_SPEED_TEST GPIO_Speed_50MHz // 50MHz速度 #define GPIO_PIN1_TEST GPIO_Pin_0 // 引腳0 #define GPIO_PIN2_TEST GPIO_Pin_2 // 引腳2 #define GPIO_PIN3_TEST GPIO_Pin_3 // 引腳3 USART_TypeDef *USART_TEST = USART1; // 使用USART1
頭文件:包含標(biāo)準(zhǔn)庫和自定義頭文件(如延時(shí)和芯片相關(guān)庫)。
宏定義:
GPIO_GROUP_TEST:指定使用 GPIOB。
GPIO_MODE_TEST:設(shè)置為推挽輸出(GPIO_Mode_Out_PP),用于驅(qū)動(dòng)外部設(shè)備(如 LED)。
GPIO_PIN1_TEST/Pin2/Pin3:定義三個(gè)輸出引腳(PB0、PB2、PB3)。
串口配置:使用 USART1 進(jìn)行通信。
2. 函數(shù)聲明
void UART_Configuration(uint32_t bound); // 串口配置函數(shù) void GPIO_Configuration(void); // GPIO配置函數(shù)
3. main 函數(shù)(主邏輯)
int main(void) { RCC_ClocksTypeDef clocks; delay_init(); // 初始化延時(shí) UART_Configuration(115200); // 配置串口(波特率115200) RCC_GetClocksFreq(&clocks); // 獲取系統(tǒng)時(shí)鐘頻率 // 打印系統(tǒng)時(shí)鐘信息 printf("SYSCLK: %3.1fMhz, HCLK: %3.1fMhz, PCLK1: %3.1fMhz, PCLK2: %3.1fMhz, ADCCLK: %3.1fMhzn", (float)clocks.SYSCLK_Frequency / 1000000, ...); printf("GPIO IO Out Tset.n"); // 打印測(cè)試信息 GPIO_Configuration(); // 配置GPIO為輸出 // 無限循環(huán):流水燈效果 while (1) { // 依次點(diǎn)亮PB0 → PB2 → PB3 GPIO_SetBits(GPIOB, GPIO_Pin_0); delay_ms(200); GPIO_SetBits(GPIOB, GPIO_Pin_2); delay_ms(200); GPIO_SetBits(GPIOB, GPIO_Pin_3); delay_ms(200); // 依次熄滅PB0 → PB2 → PB3 GPIO_ResetBits(GPIOB, GPIO_Pin_0); delay_ms(200); GPIO_ResetBits(GPIOB, GPIO_Pin_2); delay_ms(200); GPIO_ResetBits(GPIOB, GPIO_Pin_3); delay_ms(200); } }
初始化:延時(shí)、串口、時(shí)鐘頻率獲取。
串口輸出:打印系統(tǒng)時(shí)鐘信息和測(cè)試提示。
GPIO 配置:設(shè)置 GPIOB 的三個(gè)引腳為輸出。
流水燈邏輯:
GPIO_SetBits:置高電平(熄滅 LED)。
GPIO_ResetBits:置低電平(點(diǎn)亮 LED)。
delay_ms(200):每個(gè)動(dòng)作間隔 200ms,形成循環(huán)閃爍。
4. GPIO_Configuration 函數(shù)(GPIO 初始化)
void GPIO_Configuration(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); // 使能GPIOB時(shí)鐘 // 配置PB0、PB2、PB3為推挽輸出 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_2 | GPIO_Pin_3; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_Init(GPIOB, &GPIO_InitStructure); // 初始化GPIOB }
時(shí)鐘使能:啟用 GPIOB 的時(shí)鐘。
引腳配置:
引腳:PB0、PB2、PB3(通過位或運(yùn)算同時(shí)配置)。
模式:推挽輸出(GPIO_Mode_Out_PP),適合驅(qū)動(dòng) LED 等外設(shè)。
速度:50MHz(滿足高頻操作需求)。
5. UART_Configuration 函數(shù)(串口初始化)
void UART_Configuration(uint32_t bound) { GPIO_InitTypeDef GPIO_InitStructure; USART_InitTypeDef USART_InitStructure; // 使能USART1和GPIOA時(shí)鐘(PA9/TX, PA10/RX) RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE); // 配置TX引腳(PA9):復(fù)用推挽輸出 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); // 配置RX引腳(PA10):浮空輸入 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(GPIOA, &GPIO_InitStructure); // 配置USART1參數(shù) USART_InitStructure.USART_BaudRate = bound; // 波特率 USART_InitStructure.USART_WordLength = USART_WordLength_8b; // 8位數(shù)據(jù) USART_InitStructure.USART_StopBits = USART_StopBits_1; // 1位停止位 USART_InitStructure.USART_Parity = USART_Parity_No; // 無校驗(yàn) USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx; // 收發(fā)模式 USART_Init(USART1, &USART_InitStructure); USART_Cmd(USART1, ENABLE); // 使能USART1 }
引腳配置:
PA9(TX):復(fù)用推挽輸出(用于發(fā)送數(shù)據(jù))。
PA10(RX):浮空輸入(用于接收數(shù)據(jù))。
串口參數(shù):115200 波特率、8 位數(shù)據(jù)、1 位停止位、無校驗(yàn)。
6. 串口輸出函數(shù)(SER_PutChar 和 fputc)
int SER_PutChar(int ch) { while (!USART_GetFlagStatus(USART_TEST, USART_FLAG_TC)); // 等待發(fā)送完成 USART_SendData(USART_TEST, (uint8_t)ch); // 發(fā)送字符 return ch; } int fputc(int c, FILE *f) { if (c == 'n') SER_PutChar('r'); // 換行時(shí)添加回車(適配終端) return SER_PutChar(c); // 重定向printf到串口 }
SER_PutChar:通過 USART 發(fā)送單個(gè)字符,等待發(fā)送完成標(biāo)志(USART_FLAG_TC)。
fputc:重定向 C 庫的printf函數(shù)到串口,支持換行符(n)自動(dòng)添加回車(r)。
5.2.3 下載驗(yàn)證
把編譯好的程序下載到開發(fā)板并復(fù)位,可看到LED亮滅交互。
5.3 W55MH32標(biāo)準(zhǔn)庫補(bǔ)充知識(shí)
5.3.1 SystemInit函數(shù)去哪了?
這個(gè)函數(shù)在W55MH32標(biāo)準(zhǔn)庫的“system_w55mh32.c”文件中定義了,而我們的工程已經(jīng)包含該文件。標(biāo)準(zhǔn)庫中的SystemInit函數(shù)把芯片的系統(tǒng)時(shí)鐘設(shè)置成了72MHz, 即此時(shí)AHB時(shí)鐘頻率為72MHz,APB2為72MHz,APB1為36MHz。當(dāng)W55MH32芯片上電后,執(zhí)行啟動(dòng)文件中的指令后,會(huì)調(diào)用該函數(shù),設(shè)置系統(tǒng)時(shí)鐘為以上狀態(tài)。
5.3.2 斷言
5.3.2.1 斷言的作用
在 W55MH32 開發(fā)過程中,開發(fā)者編寫的代碼需要對(duì)各種參數(shù)和狀態(tài)進(jìn)行檢查。斷言提供了一種簡單有效的方式,用于在代碼中插入檢查點(diǎn),驗(yàn)證某些條件是否滿足。如果條件不滿足,斷言會(huì)觸發(fā)錯(cuò)誤,幫助開發(fā)者快速定位和解決問題。具體見代碼清單:GPIO輸出-1 :
代碼清單:GPIO輸出-1 GPIO_Init函數(shù)的斷言部分
void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct) { uint32_t pinpos = 0x00, pos = 0x00 , currentpin = 0x00; /* Check the parameters */ assert_param(IS_GPIO_ALL_PERIPH(GPIOx)); assert_param(IS_GPIO_MODE(GPIO_InitStruct->GPIO_Mode)); assert_param(IS_GPIO_PIN(GPIO_InitStruct->GPIO_Pin)); /* ------- 以下內(nèi)容省略,跟前面我們定義的函數(shù)內(nèi)容相同----- */
基本上每個(gè)庫函數(shù)的開頭都會(huì)有這樣類似的內(nèi)容,這里的“assert_param”實(shí)際是一個(gè)宏,在庫函數(shù)中它用于檢查輸入?yún)?shù)是否符合要求, 若不符合要求則執(zhí)行某個(gè)函數(shù)輸出警告,“assert_param”的定義見代碼清單:GPIO輸出-2 :
代碼清單:GPIO輸出-2 w55mh32_conf.h文件中關(guān)于斷言的定義
#ifdef USE_FULL_ASSERT /** * @brief assert_param 宏用于函數(shù)的輸入?yún)?shù)檢查 * @param expr:若expr值為假,則調(diào)用assert_failed函數(shù) * 報(bào)告文件名及錯(cuò)誤行號(hào) * 若expr值為真,則不執(zhí)行操作 */ #define assert_param(expr) ((expr) ? (void)0 : assert_failed((uint8_t *)__FILE__, __LINE__)) /* 錯(cuò)誤輸出函數(shù) ------------------------------------------------------- */ void assert_failed(uint8_t* file, uint32_t line); #else #define assert_param(expr) ((void)0) #endif
這段代碼的意思是,假如我們不定義“USE_FULL_ASSERT”宏,那么“assert_param”就是一個(gè)空的宏(#else與#endif之間的語句生效),沒有任何操作。 從而所有庫函數(shù)中的assert_param實(shí)際上都無意義,我們就當(dāng)看不見好了。
假如我們定義了“USE_FULL_ASSERT”宏,那么“assert_param”就是一個(gè)有操作的語句(#if與#else之間的語句生效), 該宏對(duì)參數(shù)expr使用C語言中的問號(hào)表達(dá)式進(jìn)行判斷,若expr值為真,則無操作(void 0),若表達(dá)式的值為假, 則調(diào)用“assert_failed”函數(shù),且該函數(shù)的輸入?yún)?shù)為“__FILE__”及“__LINE__”, 這兩個(gè)參數(shù)分別代表 “assert_param”宏被調(diào)用時(shí)所在的“文件名”及“行號(hào)”。
但庫文件只對(duì)“assert_failed”寫了函數(shù)聲明,沒有寫函數(shù)定義,實(shí)際用時(shí)需要用戶來定義, 我們一般會(huì)用printf函數(shù)來輸出這些信息,見代碼清單:GPIO輸出-3 :
代碼清單:GPIO輸出-3 assert_failed 輸出錯(cuò)誤信息
void assert_failed(uint8_t * file, uint32_t line) { printf(“rn 輸入?yún)?shù)錯(cuò)誤,錯(cuò)誤文件名=%s,行號(hào)=%s”,file,line); }
那么為什么函數(shù)輸入?yún)?shù)不對(duì)的時(shí)候,assert_param宏中的expr參數(shù)值會(huì)是假呢?這要回到GPIO_Init函數(shù),看它對(duì)assert_param宏的調(diào)用, 它被調(diào)用時(shí)分別以“IS_GPIO_ALL_PERIPH(GPIOx)”、“IS_GPIO_PIN(GPIO_InitStruct->GPIO_Pin)”等作為輸入?yún)?shù),也就是說被調(diào)用時(shí), expr實(shí)際上是一條針對(duì)輸入?yún)?shù)的判斷表達(dá)式。例如“IS_GPIO_PIN”的宏定義:
#define IS_GPIO_PIN(PIN) ((PIN) != (uint32_t)0x00)
若它的輸入?yún)?shù) PIN 值為0,則表達(dá)式的值為假,PIN非0時(shí)表達(dá)式的值為真。 我們知道用于選擇GPIO引腳號(hào)的宏“GPIO_Pin_x”的值至少有一個(gè)數(shù)據(jù)位為1, 這樣的輸入?yún)?shù)才有意義,若GPIO_InitStruct->GPIO_Pin的值為0,輸入?yún)?shù)就無效了。配合“IS_GPIO_PIN”這句表達(dá)式, “assert_param”就實(shí)現(xiàn)了檢查輸入?yún)?shù)的功能。對(duì)assert_param宏的其它調(diào)用方式類似,大家可以自己看庫源碼來研究一下。
5.3.3 Doxygen注釋規(guī)范
在W55MH32標(biāo)準(zhǔn)庫以及我們自己編寫的文件中,可以看到一些比較特別的注釋,類似代碼清單:GPIO輸出-4:
代碼清單:GPIO輸出-4 Doxygen注釋規(guī)范
/** * @brief 初始化控制LED的IO * @param 無 * @retval 無 */
這是一種名為“Doxygen”的注釋規(guī)范,如果在工程文件中按照這種規(guī)范去注釋,可以使用Doxygen軟件自動(dòng)根據(jù)注釋生成幫助文檔。 我們所說非常重要的庫幫助文檔
5.3.4 防止頭文件重復(fù)包含
在W55MH32標(biāo)準(zhǔn)庫的所有頭文件以及我們自己編寫的.h頭文件中,可看到類似代碼清單:GPIO輸出-5的宏定義。 它的功能是防止頭文件被重復(fù)包含,避免引起編譯錯(cuò)誤。
代碼清單:GPIO輸出-5 防止頭文件重復(fù)包含的宏
#ifndef __LED_H #define __LED_H /*此處省略頭文件的具體內(nèi)容*/ #endif /* end of __LED_H */
在頭文件的開頭,使用“#ifndef”關(guān)鍵字,判斷標(biāo)號(hào)“__LED_H”是否被定義,若沒有被定義,則從“#ifndef”至“#endif”關(guān)鍵字之間的內(nèi)容都有效, 也就是說,這個(gè)頭文件若被其它文件“#include”,它就會(huì)被包含到其該文件中了,且頭文件中緊接著使用“#define”關(guān)鍵字定義上面判斷的標(biāo)號(hào)“__LED_H”。 當(dāng)這個(gè)頭文件被同一個(gè)文件第二次“#include”包含的時(shí)候, 由于有了第一次包含中的“#define __LED_H”定義,這時(shí)再判斷“#ifndef__LED_H”, 判斷的結(jié)果就是假了,從“#ifndef”至“#endif”之間的內(nèi)容都無效,從而防止了同一個(gè)頭文件被包含多次,編譯時(shí)就不會(huì)出現(xiàn)“redefine(重復(fù)定義)”的錯(cuò)誤了。
一般來說,我們不會(huì)直接在C的源文件寫兩個(gè)“#include”來包含同一個(gè)頭文件,但可能因?yàn)轭^文件內(nèi)部的包含導(dǎo)致重復(fù),這種代碼主要是避免這樣的問題。
WIZnet 是一家無晶圓廠半導(dǎo)體公司,成立于 1998 年。產(chǎn)品包括互聯(lián)網(wǎng)處理器 iMCU?,它采用 TOE(TCP/IP 卸載引擎)技術(shù),基于獨(dú)特的專利全硬連線 TCP/IP。iMCU? 面向各種應(yīng)用中的嵌入式互聯(lián)網(wǎng)設(shè)備。
WIZnet 在全球擁有 70 多家分銷商,在香港、韓國、美國設(shè)有辦事處,提供技術(shù)支持和產(chǎn)品營銷。
香港辦事處管理的區(qū)域包括:澳大利亞、印度、土耳其、亞洲(韓國和日本除外)。
審核編輯 黃宇
-
led
+關(guān)注
關(guān)注
242文章
23663瀏覽量
670135 -
GPIO
+關(guān)注
關(guān)注
16文章
1258瀏覽量
53462
發(fā)布評(píng)論請(qǐng)先 登錄
德賽西威第五代智能座艙G10PH硬件平臺(tái)首發(fā)點(diǎn)亮
HTR3310 10路LED驅(qū)動(dòng)器和GPIO控制器中文手冊(cè)
HTR3316 16路LED驅(qū)動(dòng)器和GPIO控制器中文手冊(cè)
汽車電路初識(shí)
《DNESP32S3使用指南-IDF版_V1.6》第十章 LED實(shí)驗(yàn)
《DNESP32S3使用指南-IDF版_V1.6》第五章 搭建開發(fā)環(huán)境
HAL庫的函數(shù)調(diào)用示例
向新、向質(zhì)、向未來!2024第五屆全球Mini/Micro LED顯示技術(shù)周圓滿閉幕!
迅為電子RK3588S開發(fā)板第五章 Debian系統(tǒng)功能測(cè)試

重慶市第五人民醫(yī)院引領(lǐng)醫(yī)療電能質(zhì)量革命,點(diǎn)亮“健康”新篇章

GPIO靜電放電防護(hù)方案

《DNK210使用指南 -CanMV版 V1.0》第五章 編譯CanMV固件
【北京迅為】《stm32mp157開發(fā)板嵌入式linux開發(fā)指南》第五章 Ubuntu使用apt-get下載

評(píng)論