單芯片解決方案,開啟全新體驗(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,滿足存儲與數(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 提供了兩種選擇:QFN68和QFN100。
W55MH32Q采用QFN68封裝版本,尺寸為8x8mm,它擁有36個(gè)GPIO、3個(gè)ADC、12通道DMA、17個(gè)定時(shí)器、2個(gè)I2C、3個(gè)串口、2個(gè)SPI接口(其中1個(gè)帶I2S接口復(fù)用)、1個(gè)CAN以及1個(gè)USB2.0。在保持與同系列其他版本一致的核心性能基礎(chǔ)上,僅減少了部分GPIO以及SDIO接口,其他參數(shù)保持一致,性價(jià)比優(yōu)勢顯著,尤其適合網(wǎng)關(guān)模組等對空間布局要求較高的場景。緊湊的尺寸和精簡化外設(shè)配置,使其能夠在有限空間內(nèi)實(shí)現(xiàn)高效的網(wǎng)絡(luò)連接與數(shù)據(jù)交互,成為物聯(lián)網(wǎng)網(wǎng)關(guān)、邊緣計(jì)算節(jié)點(diǎn)等緊湊型設(shè)備的理想選擇。 同系列還有QFN100封裝的W55MH32L版本,該版本擁有更豐富的外設(shè)資源,適用于需要多接口擴(kuò)展的復(fù)雜工控場景,軟件使用方法一致。更多信息和資料請進(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ā),基于W55MH32Q這顆芯片,WIZnet精心打造了配套開發(fā)板。開發(fā)板集成WIZ-Link芯片,借助一根USB C口數(shù)據(jù)線,就能輕松實(shí)現(xiàn)調(diào)試、下載以及串口打印日志等功能。開發(fā)板將所有外設(shè)全部引出,拓展功能也大幅提升,便于開發(fā)者全面評估芯片性能。
若您想獲取芯片和開發(fā)板的更多詳細(xì)信息,包括產(chǎn)品特性、技術(shù)參數(shù)以及價(jià)格等,歡迎訪問官方網(wǎng)頁:http://www.w5500.com/,我們期待與您共同探索W55MH32的無限可能。

第五章 GPIO示例
功夫不負(fù)有心人,相信學(xué)習(xí)至此大家已經(jīng)掌握了基礎(chǔ)內(nèi)容介紹的知識。我們希望通過前面的章節(jié)你已經(jīng)掌握了W55MH32開發(fā)的工具和方法。下面我們將和大家一起來學(xué)習(xí)W55MH32 的一些基礎(chǔ)外設(shè),這些外設(shè)實(shí)際項(xiàng)目中經(jīng)常會用到,希望大家認(rèn)真學(xué)習(xí)和掌握,以便將來更好、更快的完成實(shí)際項(xiàng)目開發(fā)。
后面我們將采取一章一實(shí)例的方式,介紹 W55MH32 常用外設(shè)的使用,通過本篇的學(xué)習(xí),我們將帶領(lǐng)大家進(jìn)入W55MH32 的精彩世界。
本章將通過一個(gè)經(jīng)典的跑馬燈程序,帶大家開啟 W55MH32之旅。通過本章的學(xué)習(xí),我們將了解到 W55MH32的 IO 口作為輸出使用的方法。
本章分為如下 4 個(gè)小節(jié):
1 W55MH32 GPIO 簡介
2 寄存器描述
3 程序設(shè)計(jì)
4 下載驗(yàn)證
1 W55MH32 GPIO 簡介
每個(gè) GPI/O 端口有兩個(gè) 32 位配置寄存器(GPIOx_CRL,GPIOx_CRH),兩個(gè) 32 位數(shù)據(jù)寄存器(GPIOx_IDR 和 GPIOx_ODR),一個(gè) 32 位置位/復(fù)位寄存(GPIOx_BSRR),一個(gè) 16 位復(fù)位寄存器GPIOx_BRR)和一個(gè) 32 位鎖定寄存器(GPIOx_LCKR)。根據(jù)數(shù)據(jù)手冊中列出的每個(gè) I/O 端口的特定硬件特征,GPIO 端口的每個(gè)位可以由軟件分別配置成多種模式。
-------- 輸入浮空
-------- 輸入上拉
-------- 輸入下拉
-------- 模擬輸入
-------- 開漏輸出
-------- 推挽式輸出
-------- 推挽式復(fù)用功能
-------- 開漏復(fù)用功能
每個(gè) I/O 端口位可以自由編程,然而必須按照 32 位字訪問 I/O 端口寄存器(不允許半字或字節(jié)訪問)。GPIOx_BSRR 和 GPIOx_BRR 寄存器允許對任何 GPIO 寄存器進(jìn)行讀/更改的獨(dú)立訪問;這樣,在讀和更改訪問之間產(chǎn)生 IRQ 時(shí)不會發(fā)生危險(xiǎn)。
下圖給出了一個(gè) I/O 端口位的基本結(jié)構(gòu)。

GPIO 的基本結(jié)構(gòu)圖
如上圖所示,可以看到右邊只有 I/O 引腳,這個(gè) I/O 引腳就是我們可以看到的芯片實(shí)物的引腳,其他部分都是 GPIO 的內(nèi)部結(jié)構(gòu)。
① 保護(hù)二極管
保護(hù)二極管共有兩個(gè),用于保護(hù)引腳外部過高或過低的電壓輸入。當(dāng)引腳輸入電壓高于VDD 時(shí),上面的二極管導(dǎo)通,當(dāng)引腳輸入電壓低于 VSS 時(shí),下面的二極管導(dǎo)通,從而使輸入芯片內(nèi)部的電壓處于比較穩(wěn)定的值。雖然有二極管的保護(hù),但這樣的保護(hù)卻很有限,大電壓大電流的接入很容易燒壞芯片。所以在實(shí)際的設(shè)計(jì)中我們要考慮設(shè)計(jì)引腳的保護(hù)電路。
② 上拉、下拉電阻
它們阻值大概在 30~50K 歐之間,可以通過上、下兩個(gè)對應(yīng)的開關(guān)控制,這兩個(gè)開關(guān)由寄存器控制。當(dāng)引腳外部的器件沒有干擾引腳的電壓時(shí),即沒有外部的上、下拉電壓,引腳的電平由引腳內(nèi)部上、下拉決定,開啟內(nèi)部上拉電阻工作,引腳電平為高,開啟內(nèi)部下拉電阻工作,則引腳電平為低。同樣,如果內(nèi)部上、下拉電阻都不開啟,這種情況就是我們所說的浮空模式。浮空模式下,引腳的電平是不可確定的。引腳的電平可以由外部的上、下拉電平?jīng)Q定。需要注意的是,W55MH32 的內(nèi)部上拉是一種“弱上拉”,這樣的上拉電流很弱,如果有要求大電流還是得外部上拉。
③ 施密特觸發(fā)器
對于標(biāo)準(zhǔn)施密特觸發(fā)器,當(dāng)輸入電壓高于正向閾值電壓,輸出為高;當(dāng)輸入電壓低于負(fù)向閾值電壓,輸出為低;當(dāng)輸入在正負(fù)向閾值電壓之間,輸出不改變,也就是說輸出由高電準(zhǔn)位翻轉(zhuǎn)為低電準(zhǔn)位,或是由低電準(zhǔn)位翻轉(zhuǎn)為高電準(zhǔn)位,對應(yīng)的閾值電壓是不同的。只有當(dāng)輸入電壓發(fā)生足夠的變化時(shí),輸出才會變化,因此將這種元件命名為觸發(fā)器。這種雙閾值動作被稱為遲滯現(xiàn)象,表明施密特觸發(fā)器有記憶性。從本質(zhì)上來說,施密特觸發(fā)器是一種雙穩(wěn)態(tài)多諧振蕩器。施密特觸發(fā)器可作為波形整形電路,能將模擬信號波形整形為數(shù)字電路能夠處理的方波波形,而且由于施密特觸發(fā)器具有滯回特性,所以可用于抗干擾,以及在閉回路正回授/負(fù)回授配置中用于實(shí)現(xiàn)多諧振蕩器。下面看看比較器跟施密特觸發(fā)器的作用的比較,就清楚的知道施密特觸發(fā)器對外部輸入信號具有一定抗干擾能力,如圖所示。

比較器的(A)和施密特觸發(fā)器(B)作用比較
④ P-MOS 管和 N-MOS 管
這個(gè)結(jié)構(gòu)控制 GPIO 的開漏輸出和推挽輸出兩種模式。開漏輸出:輸出端相當(dāng)于三極管的集電極,要得到高電平狀態(tài)需要上拉電阻才行。推挽輸出:這兩只對稱的 MOS 管每次只有一只導(dǎo)通,所以導(dǎo)通損耗小、效率高。輸出既可以向負(fù)載灌電流,也可以從負(fù)載拉電流。推拉式輸出既能提高電路的負(fù)載能力,又能提高開關(guān)速度。上面我們對 GPIO 的基本結(jié)構(gòu)圖中的關(guān)鍵器件做了介紹,下面分別介紹 GPIO 八種工作模式對應(yīng)結(jié)構(gòu)圖的工作情況。
1、輸入浮空
輸入浮空模式:上拉/下拉電阻為斷開狀態(tài),施密特觸發(fā)器打開,輸出被禁止。輸入浮空模式下,IO 口的電平完全是由外部電路決定。如果 IO 引腳沒有連接其他的設(shè)備,那么檢測其輸入電平是不確定的。該模式可以用于按鍵檢測等情景。

輸入浮空模式
2、輸入上拉
輸入上拉模式:上拉電阻導(dǎo)通,施密特觸發(fā)器打開,輸出被禁止。在需要外部上拉電阻的時(shí)候,可以使用內(nèi)部上拉電阻,這樣可以節(jié)省一個(gè)外部電阻,但是內(nèi)部上拉電阻的阻值較大,所以只是“弱上拉”,不適合做電流型驅(qū)動。

輸入上拉模式
3、輸入下拉
輸入下拉模式:下拉電阻導(dǎo)通,施密特觸發(fā)器打開,輸出被禁止。在需要外部下拉電阻的時(shí)候,可以使用內(nèi)部下拉電阻,這樣可以節(jié)省一個(gè)外部電阻,但是內(nèi)部下拉電阻的阻值較大,所以不適合做電流型驅(qū)動。

輸入下拉模式
4、模擬功能
模擬功能:上下拉電阻斷開,施密特觸發(fā)器關(guān)閉,雙 MOS 管也關(guān)閉。其他外設(shè)可以通過模擬通道輸入輸出。該模式下需要用到芯片內(nèi)部的模擬電路單元單元,用于 ADC、DAC、MCO 這類操作模擬信號的外設(shè)。

模擬功能
5、開漏輸出
開漏輸出模式:W55MH32 的開漏輸出模式是數(shù)字電路輸出的一種,從結(jié)果上看它只能輸出低電平 Vss 或者高阻態(tài),常用于 IIC 通訊(IIC_SDA)或其它需要進(jìn)行電平轉(zhuǎn)換的場景。

開漏輸出模式
6、推挽輸出
推挽輸出模式:W55MH32的推挽輸出模式,從結(jié)果上看它會輸出低電平 VSS或者高電平VDD推挽輸出跟開漏輸出不同的是,推挽輸出模式 P-MOS 管和 N-MOS 管都用上。
如果輸出數(shù)據(jù)寄存器①的值為 0,經(jīng)過“輸出控制”取反操作后,輸出邏輯 1 到 P-MOS 管的柵極,這時(shí) P-MOS 管就會截止,同時(shí)也會輸出邏輯 1 到 N-MOS 管的柵極,這時(shí) N-MOS 管就會導(dǎo)通,使得 IO 引腳接到 VSS,即輸出低電平。如果輸出數(shù)據(jù)寄存器的值為 1 ,經(jīng)過“輸出控制”取反操作后,輸出邏輯 0 到 N-MOS 管的柵極,這時(shí) N-MOS 管就會截止,同時(shí)也會輸出邏輯 0 到 P-MOS 管的柵極,這時(shí) P-MOS 管就會導(dǎo)通,使得 IO 引腳接到 VDD,即輸出高電平。
由上述可知,推挽輸出模式下,P-MOS 管和 N-MOS 管同一時(shí)間只能有一個(gè)管是導(dǎo)通的。當(dāng) IO 引腳在做高低電平切換時(shí),兩個(gè)管子輪流導(dǎo)通,一個(gè)負(fù)責(zé)灌電流,一個(gè)負(fù)責(zé)拉電流,使其負(fù)載能力和開關(guān)速度都有較大的提高。
另外在推挽輸出模式下,施密特觸發(fā)器也是打開的,我們可以讀取 IO 口的電平狀態(tài)。由于推挽輸出模式下輸出高電平時(shí),是直接連接VDD,所以驅(qū)動能力較強(qiáng),可以做電流型驅(qū)動,驅(qū)動電流最大可達(dá) 25mA,但是芯片的總電流有限,所以并不建議這樣用,最好還是使用芯片外部的電源。

推挽輸出模式
7、開漏式復(fù)用功能
開漏式復(fù)用功能:一個(gè) IO 口可以是通用的 IO 口功能,還可以是其它外設(shè)的特殊功能引腳,這就是 IO 口的復(fù)用功能,如圖所示。一個(gè) IO 口可以是多個(gè)外設(shè)的功能引腳,我們需要選擇其中一個(gè)外設(shè)的功能引腳。當(dāng)選擇復(fù)用功能時(shí),引腳的狀態(tài)是由對應(yīng)的外設(shè)控制,而不是輸出數(shù)據(jù)寄存器。除了復(fù)用功能外,其它的結(jié)構(gòu)分析請參考開漏輸出模式。
另外在開漏式復(fù)用功能模式下,施密特觸發(fā)器也是打開的,我們可以通過輸入數(shù)據(jù)寄存器讀取 IO 口的電平狀態(tài),同時(shí)外設(shè)也可以讀取 IO 口的信息。

開漏式復(fù)用功能
8、推挽式復(fù)用功能
推挽式復(fù)用功能:復(fù)用功能介紹請查看開漏式復(fù)用功能,結(jié)構(gòu)分析請參考推挽輸出模式,這里不再贅述。

推挽式復(fù)用功能
2 GPIO 寄存器描述
2.1 端口配置低寄存器(GPIOx_CRL)(x=A..G)

2.2 端口配置高寄存器(GPIOx_CRH)(x=A..G)

2.3 端口輸入數(shù)據(jù)寄存器(GPIOx_IDR)(x=A..G)

2.4 端口輸出數(shù)據(jù)寄存器(GPIOx_ODR)(x=A..G)


2.5 端口位設(shè)置/清除寄存器(GPIOx_BSRR)(x=A..G)

2.6 端口位清除寄存器(GPIOx_BRR)(x=A..G)

2.7 端口配置鎖定寄存器(GPIOx_LCKR)(x=A..G)
當(dāng)執(zhí)行正確的寫序列設(shè)置了位 16(LCKK)時(shí),該寄存器用來鎖定端口位的配置。位[15:0]用于鎖定GPIO 端口的配置。在規(guī)定的寫入操作期間,不能改變 LCKP[15:0]。當(dāng)對相應(yīng)的端口位執(zhí)行了LOCK 序列后,在下次系統(tǒng)復(fù)位之前將不能再更改端口位的配置。
每個(gè)鎖定位鎖定控制寄存器(CRL,CRH)中相應(yīng)的 4 個(gè)位。

3 程序設(shè)計(jì)
3.1 GPIO_IOInput例程
此代碼為一個(gè)基于W55MH32的嵌入式程序,主要功能是對 GPIO 輸入進(jìn)行測試,同時(shí)配置 UART 串口通信用于輸出系統(tǒng)時(shí)鐘信息和按鍵按下的提示信息。
主函數(shù)main()
int main(void)
{
RCC_ClocksTypeDef clocks;
delay_init();
UART_Configuration(115200);
RCC_GetClocksFreq(&clocks);
printf("n");
printf("SYSCLK: %3.1fMhz, HCLK: %3.1fMhz, PCLK1: %3.1fMhz, PCLK2: %3.1fMhz, ADCCLK: %3.1fMhzn",
(float)clocks.SYSCLK_Frequency / 1000000, (float)clocks.HCLK_Frequency / 1000000,
(float)clocks.PCLK1_Frequency / 1000000, (float)clocks.PCLK2_Frequency / 1000000, (float)clocks.ADCCLK_Frequency / 1000000);
printf("GPIO IO Input Tset.n");
GPIO_Configuration();
while (1)
{
}
}
對延時(shí)函數(shù)進(jìn)行初始化。
把串口波特率配置為 115200。
獲取系統(tǒng)時(shí)鐘頻率并輸出。
配置 GPIO。
進(jìn)入無限循環(huán)。
GPIO 配置函數(shù)GPIO_Configuration()
void GPIO_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
EXTI_InitTypeDef EXTI_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_PIN1_TEST;
GPIO_InitStructure.GPIO_Speed = GPIO_SPEED_TEST;
GPIO_InitStructure.GPIO_Mode = GPIO_MODE_TEST;
GPIO_Init(GPIO_GROUP_TEST, &GPIO_InitStructure);
GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource1);
NVIC_InitStructure.NVIC_IRQChannel = EXTI1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
EXTI_InitStructure.EXTI_Line = EXTI_Line1;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
}
開啟 GPIOA 和 AFIO 的時(shí)鐘。
對 GPIO 引腳進(jìn)行初始化。
把 GPIO 引腳配置為外部中斷線。
對 NVIC(嵌套向量中斷控制器)進(jìn)行配置。
對外部中斷進(jìn)行配置,觸發(fā)方式為下降沿觸發(fā)。
UART 配置函數(shù)UART_Configuration()
void UART_Configuration(uint32_t bound)
{
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &GPIO_InitStructure);
USART_InitStructure.USART_BaudRate = bound;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_Init(USART_TEST, &USART_InitStructure);
USART_Cmd(USART_TEST, ENABLE);
}
開啟 USART1 和 GPIOA 的時(shí)鐘。
對 USART1 的發(fā)送和接收引腳進(jìn)行初始化。
對 USART1 進(jìn)行初始化,設(shè)置波特率、數(shù)據(jù)位、停止位等參數(shù)。
使能 USART1。
外部中斷處理函數(shù)EXTI1_IRQHandler()
void EXTI1_IRQHandler(void)
{
if (EXTI_GetITStatus(EXTI_Line1) == SET)
{
delay_ms(10);
if (GPIO_ReadOutputDataBit(GPIOA, GPIO_Pin_1) == Bit_SET)
{
printf("The key is pressedn");
}
}
EXTI_ClearITPendingBit(EXTI_Line1);
}
當(dāng)檢測到外部中斷觸發(fā)時(shí),進(jìn)行消抖處理。
若按鍵確實(shí)被按下,則通過串口輸出提示信息。
清除中斷標(biāo)志位。
3.2 GPIO_IOOut例程
初始化部分:delay_init():初始化延時(shí)函數(shù)。
UART_Configuration(115200):配置串口,波特率為 115200。
RCC_GetClocksFreq(&clocks):獲取系統(tǒng)時(shí)鐘頻率信息,并通過串口打印出來。
GPIO_Configuration():配置 GPIOB 的 PB0、PB2、PB3 為推挽輸出模式。
主循環(huán)部分:
以 200ms 為間隔依次將 PB0、PB2、PB3 置高電平,再依次將它們置低電平,循環(huán)執(zhí)行。
while (1)
{
GPIO_SetBits(GPIO_GROUP_TEST, GPIO_PIN1_TEST);
printf("LED1 ONn");
delay_ms(200);
GPIO_SetBits(GPIO_GROUP_TEST, GPIO_PIN2_TEST);
printf("LED2 ONn");
delay_ms(200);
GPIO_SetBits(GPIO_GROUP_TEST, GPIO_PIN3_TEST);
printf("LED3 ONn");
delay_ms(200);
GPIO_ResetBits(GPIO_GROUP_TEST, GPIO_PIN1_TEST);
printf("LED1 OFFn");
delay_ms(200);
GPIO_ResetBits(GPIO_GROUP_TEST, GPIO_PIN2_TEST);
printf("LED2 OFFn");
delay_ms(200);
GPIO_ResetBits(GPIO_GROUP_TEST, GPIO_PIN3_TEST);
printf("LED3 OFFn");
delay_ms(200);
}
}
4 下載驗(yàn)證
4.1 GPIO_IOInput例程

4.2 GPIO_IOOut例程

審核編輯 黃宇
-
寄存器
+關(guān)注
關(guān)注
31文章
5608瀏覽量
130003 -
GPIO
+關(guān)注
關(guān)注
16文章
1328瀏覽量
56231
發(fā)布評論請先 登錄
第五章 GPIO示例
評論