前面我們已經對敏矽微電子的基于cortex m0內核的ME32F030R8T6的基本功能做了介紹,然后詳細講解了開發環境MDK的安裝,pack包的安裝,工程的建立及程序的仿真,緊接著講解了ME32F030R8T6的時鐘系統。
如果說前面都是基礎知識介紹和理論講解,那么從本篇開始,我們不但會有理論介紹,還會結合敏矽微電子提供的ME32F030R8T6開發板進行實例驗證,讓大家看到實例運行的結果。
1、敏矽微電子Cortex-M0學習筆記04-GPIO詳解及實例
首先我們對ME32F030R8T6芯片的I/O端口做一個大致的了解。
1.1. ME32F030R8T6的GPIO 概述
ME32F030R8T6提供多達 57個 GPIO 管腳。主要的特點有:
? 數字管腳可以用軟件定義為輸入或輸出
? 管腳讀寫可以被屏蔽
? 多個管腳的置位、清零位用一條指令實現
? 管腳的輸出取反
? 每一個管腳可作為外部中斷信號
? 可編程的中斷觸發條件及中斷優先級
? 所有GPIO管腳在復位后被配置成帶上拉電阻的輸入管腳
MCU的端口除了靈活易用的特點之外,其外設功能也十分強大。管腳功能由IO控制寄存器配置,除電源管腳,其余管腳均可復用。
系統復位后,管腳功能將被設置成默認值。
GPIO可以復用的功能如下:LED/LCD 驅動、觸摸按鍵、ADC、定時器6輸出、定時器7輸出、PWM輸出、UART0、UART1、SPI、I2C。
在使用端口復用功能時,通過 I/O 配置寄存器IOCON對端口進行功能設置,每個引腳對應的復用功能,請參照官方數據手冊的詳細說明。
1.2. ME32F030R8T6的GPIO 寄存器詳解
對于使用過單片機開發產品的人來說,功能繁多、名稱各異的寄存器應該是最重要也是最令人頭疼的地方,但是沒辦法,想要開發出功能穩定、性能可靠的產品,就必須來硬著頭皮查看各個寄存器的功能和配置方法。
當然,對于ME32F030R8T6來說,官方推出了庫函數,利用這些庫函數可以不必關心具體的寄存器就能編寫出合適的程序。但是對于想要深入了解的話,還是要看看寄存器的。
1.2.1. GPIO功能配置寄存器
MCU有一系列的GPIO 控制寄存器來實現對I/O口的靈活控制。
首先我們對 I/O 配置寄存器IOCON做一個介紹,因為它決定著I/O端口的功能選擇和電氣特性。所以需要拿出來單獨進行介紹,該寄存器的每一位的功能如下:
①、管腳功能:
IOCON 寄存器中的 FUNC 位可設為 GPIO (FUNC = 000) 或外設功能。如果將管腳配置為 GPIO 管腳,則 DIR 寄存器決定管腳是配置為輸入還是輸出。對于任何外設功能,會根據管腳的功能自動控制管腳方向。GPIO 的 DIR 寄存器此時對外設功能無效。
②、管腳模式:
IOCON 寄存器的 MODE 位允許為每個管腳使能或禁止片內上拉電阻。默認情況下,所有管腳的上拉電阻都被使能。
③、管腳驅動
對于每個正常驅動管腳,可以選擇兩種電流的輸出驅動,即低電流模式和高電流模式。用戶可以根據自己的實際需求進行選擇。
④、開漏模式
所有數字 I/O 管腳都可為開漏模式。但是請注意,該模式并不是真正的開漏模式。輸入上拉至不能超過VDD。
⑤、模式功能
I/O 管腳可以配置為模擬功能,作為模擬信號的輸出和輸入管腳,例如復用為AD口的時候,可以作為檢測電壓的模擬信號輸入口。
⑤、電壓轉換速率模式
在作用AD轉換口的時候,可以設置端口轉換速率為快速模式或慢速模式,默認為快速模式。相對于快速模式,慢速模式轉滿時間會變長,隨之電流功耗也增大,但時精度會更加精確,根據應用場景和自身需求,選擇適合的模式。
1.2.2. GPIO控制寄存器總覽
MCU所有的GPIO被分布到4個端口: PA,、PB、PC、PD。每個端口都擁有自己獨立的控制寄存器去管理 GPIO 的功能。下面的表列出了所有的寄存器以供參考。接下來會對每個寄存器做出詳解。
1.2.3. GPIO屏蔽寄存器
GPIO屏蔽寄存器可屏蔽下列寄存器的讀和寫操作:PIN、OUT、SET、CLR和 NOT,相當于給這些寄存器上了個“鎖”,只有當MASK寄存器相應的BIT位被置 0,被屏蔽的寄存器才能進行讀和寫操作。該寄存器上電后默認為0,即不進行GPIO屏蔽。當配置1啟動屏蔽功能后,對處于輸出功能的端口進行任何寫操作都無效,不會改變其當前的輸出狀態。對處于輸入功能的端口進行讀操作,無論此時端口處于何種電平,都會返回0.
1.2.4. GPIO管腳值寄存器
對配置為數字功能的端口,對該寄存器進行讀操作將返回管腳的當前邏輯值,不管該管腳是配置為輸入還是輸出,也不管它是配置為 GPIO 還是任何其它適用的備用數字功能,都可以直接進行讀取。但也有例外,在以下兩種情況中, PIN 寄存器中讀出的管腳值無效:①、如果選擇了管腳的模擬功能(如適用),則不能讀取管腳狀態,例如將管腳選作 ADC 輸入會斷開管腳的數字功能。②、該引腳被GPIO屏蔽寄存器MASK給屏蔽了。
1.2.5. GPIO管腳輸出寄存器
在沒有被GPIO屏蔽寄存器MASK屏蔽的情況下,向該寄存器寫0或1將在相應端口管腳產生低電平或高電平。但是對于所有其他配置(輸入、非GPIO功能),OUT 寄存器位的值對管腳輸出電平無效。讀取該寄存器將返回 GPIO 輸出寄存器的內容,不管數字管腳配置和方向如何。
通過SET、CLR和NOT寄存器可以對OUT 寄存器執行寫操作,允許按位對單個端口管腳進行置位、清除、取反操作。以此來控制OUT 寄存器的輸出內容。
1.2.6. GPIO管腳輸出置位寄存器
在沒有被GPIO屏蔽寄存器MASK屏蔽,端口DIR為輸出方向且端口功能為數字GPIO功能的情況下,寫1會將相應端口管腳設為高電平。寫0對GPIO輸出電平無效。另外該寄存器為只寫寄存器,對其進行讀操作是無效的。
1.2.7. GPIO管腳輸出清除寄存器
在沒有被GPIO屏蔽寄存器MASK屏蔽,端口DIR為輸出方向且端口功能為數字GPIO功能的情況下,寫1會將相應端口管腳設為低電平。寫0對GPIO輸出電平無效。另外該寄存器為只寫寄存器,對其進行讀操作是無效的。
1.2.8. GPIO管腳輸出取反寄存器
在沒有被GPIO屏蔽寄存器MASK屏蔽,端口DIR為輸出方向且端口功能為數字GPIO功能的情況下,寫1會將相應端口的輸出狀態進行反轉。寫0對GPIO輸出電平無效。另外該寄存器為只寫寄存器,對其進行讀操作是無效的。
1.2.9. GPIO數據方向寄存器
在使用數字GPIO前,首先要確定的就是端口的數據方向。向該寄存器寫1會將端口設置為輸出模式,寫0設置為輸入模式。上電后端口默認為輸入狀態。
1.2.10. GPIO中斷感應寄存器
在文章開頭的介紹中,我們就說過MCU的每一個管腳是可以作為外部中斷信號。因此會有一系列與之對應的中斷管理寄存器,來對每個端口的中斷進行管理。這就是接下來要介紹的中斷寄存器。在使用端口中斷前,需要明確需要觸發中斷的條件。向中斷感應寄存器ISENSEx寫入1,端口中斷的觸發方式為電平中斷。向寄存器寫入0,端口中斷的觸發方式為沿中斷觸發,具體需要什么樣的沿來觸發,這個還需要下面的中斷配置寄存器來設置。
1.2.11. GPIO中斷配置寄存器
緊接上文,在明確使用端口觸發方式為沿中斷觸發后,我們通過中斷配置寄存器IBEx來選擇沿觸發條件。向寄存器寫入1,管腳的上升沿和下降沿都觸發中斷。向寄存器寫入0,管腳只能由上升沿或下降沿中的一種來觸發中斷,具體由哪種來觸發,需要下面的中斷事件寄存器IEVx來決定。
1.2.12. GPIO中斷事件寄存器
當中斷配置寄存器IBEx值為0時,中斷事件寄存器就決定著中斷觸發的條件,向寄存器寫1,上升沿觸發中斷。寫入0,則下降沿產生中斷。
1.2.13. GPIO中斷屏蔽寄存器
在實際的開發過程中,使用到中斷功能的端口畢竟是少數,因此MCU在上電后就默認屏蔽了端口的中斷功能。如果要開啟端口的中斷功能,向對應的寄存器位寫1即可。
1.2.14. GPIO原始中斷狀態寄存器
該寄存器的位讀出為高時反映了對應管腳上的原始(屏蔽之前)中斷狀態,表示在觸發 IE 之前所有的要求都滿足。位讀出為0時表示對應的輸入管腳還未啟動中斷。該寄存器為只讀。
1.2.15. GPIO中斷狀態寄存器
該寄存器中的位讀為高反映了輸入觸發中斷的狀態。讀出為低則表示對應的輸入管腳沒有中斷產生,或者中斷被屏蔽。讀出為高則表示對應的輸入管腳有中斷產生。該寄存器為只讀。
1.2.16. GPIO中斷清除寄存器
在中斷發生后,程序會進入中斷服務子程序。在中斷服務子程序中處理完中斷程序后,需要向中斷清除寄存器CLRx寫1來清除中斷標志。
1.3. ME32F030R8T6的GPIO 庫函數函數
為了便于開發者快速上手,敏矽微電子官方例程中提供了gpio.c文件,其中包含了設置端口方向、讀取端口狀態、配置端口中斷等函數,供開發者直接使用。
1、設置GPIO為輸入方向
voidGPIO_ConfigPinsAsInput(PA_Type*port,uint16_tpins) { port->DIR =~pins; return; }
2、設置GPIO位輸出方向
voidGPIO_ConfigPinsAsOutput(PA_Type*port,uint16_tpins) { port->DIR|=pins; return; }
3、設置GPIO輸出高
voidGPIO_SetPin(PA_Type*port,uint16_tpin) { port->SET|=pin; return; }
4、設置GPIO輸出低
voidGPIO_ResetPin(PA_Type*port,uint16_tpin) { port->CLR|=pin; return; }
5、設置GPIO輸出反轉
voidGPIO_InvertOutPin(PA_Type*port,uint16_tpin) { port->NOT|=pin; return; }
6、讀取GPIO某個引腳的輸入狀態
uint8_tGPIO_GetPinState(PA_Type*port,uint16_tpin) { if(port->PIN pin) return1; else return0; }
7、讀取GPIO整個引腳的輸入狀態
uint16_tGPIO_GetPortState(PA_Type*port) { return(uint16_t)port->PIN; }
8、屏蔽GPIO引腳
voidGPIO_SetPortMask(PA_Type*port,uint16_tpins) { port->MASK|=pins; return; }
9、使能GPIO引腳
voidGPIO_SetPortMask(PA_Type*port,uint16_tpins) { port->MASK|=pins; return; }
10、配置GPIO引腳的中斷功能
voidGPIO_EnableInt(PA_Type*port,uint16_tpin,uint8_ttriggeredge) { port->IS =~pin; port->IE|=pin; switch(triggeredge) { caseRISE_EDGE: port->IBE =~pin; port->IEV|=pin; break; caseFALL_EDGE: port->IBE =~pin; port->IEV =~pin; break; caseBOTH_EDGE: port->IBE|=pin; break; default: break; } return; }
11、清除GPIO引腳的中斷標志
voidGPIO_ClrInt(PA_Type*port,uint16_tpins) { port->IC=pins; return; }
1.4. ME32F030R8T6的GPIO 開發實例
介紹完GPIO的原理和函數,接下來就用最經典的LED小燈試驗來進行示例。
本例使用敏矽微電子專門為ME32F030R8T6提供的庫函數編寫程序。
實例程序的代碼如下:
intmain(void { WDT->MOD=0;//關閉看門狗 PB_9_INIT(PB_9_GPIO);//PB9(LED)設置為GPIO功能 GPIO_ConfigPinsAsOutput(PB,IO_PIN9);//PB9(LED)設置為輸出方向 while(1) { GPIO_InvertOutPin(PB,IO_PIN9);//PB9(LED)端口輸出反轉 SYS_DelaymS(500);//延時500ms } }
程序下載成功后,先在端口反轉這句話處打上一個斷點,然后全速運行程序(快捷鍵F5)。隨后程序會停在斷點處,
此時先暫停觀察下LED小燈的狀態,發現紅圈標注的小燈并沒有被點亮。
運行結果1
接下來單步運行程序,觀察執行完端口反轉這段程序后的狀態。這時我們發現小燈已經被點亮了。
繼續單步運行,當再次執行端口反轉這段程序后,端口輸出就會反轉,接下來小燈就會熄滅。最后取消程序中的所有斷點,讓程序全速運行起來,小燈便開始周期性的閃爍。
來源:敏矽MCU
-
寄存器
+關注
關注
31文章
5336瀏覽量
120230 -
開發板
+關注
關注
25文章
5032瀏覽量
97375 -
Cortex-M0
+關注
關注
4文章
124瀏覽量
38673 -
GPIO
+關注
關注
16文章
1204瀏覽量
52052
發布評論請先 登錄
相關推薦
評論