EFM32-筆記-IO操作
2.向GPIO_Px_DOUTSET的對應位上寫1,就可以將該位設定為高電平。
3.向GPIO_Px_DOUTCLR的對應位上寫1,就可以將該位設定為低電平。
4.向GPIO_Px_DOUTTGL的對應位上寫1,就可以將該位的電平反轉。
對GPIO_Px_DOUT進行讀取,就可以獲取各個位的電平資訊,因此可以使用GPIO->P[4].DOUT^=0x000C;來反轉PE2和PE3兩個IO的電平,不過還是建議用方法4來反轉電平,因為速度更快;而對GPIO_Px_DOUTSET、GPIO_Px_DOUTCLR、GPIO_Px_DOUTTGL讀取,始終讀到的都是0。
GPIO_Px_DIN暫存器。無論該IO口被設定為輸入還是輸出,讀取DIN暫存器,都可以得到該IO口當前的電平狀態。系統之使用DIN暫存器的前16位,因為每一個Px只有16個IO口。
GPIO_Px_MODEL, GPIO_Px_MODEH, GPIO_Px_CTRL,GPIO_Px_PINLOCKN,GPIO_EXTIPSELL,GPIO_EXTIPSELH,GPIO_INSENSE andGPIO_ROUTE這些暫存器都可以鎖定,只需要向GPIO_LOCK暫存器寫入不等於0xA534的數。如果向GPIO_LOCK寫入0xA534,將會解鎖。
對於每一組的每一個IO口的這些這些暫存器,都可以單獨的鎖定,只需要將GPIO_Px_PINLOCKN(16位配置有效)相應的位寫0即可。在系統啟動的時候,這些位都被置1,也就是每一組的GPIO_Px_PINLOCKN均為0xffff。
另外對GPIO操作之前,要首先使能它的時鐘。GPIO使用的HFPERCLK,它本身在reset的時候預設為使能狀態的(也可以在後期關閉,以進一步節省能耗)。還要在HFPERCLKEN0的相關位進行設定,使得GPIO能夠使用HFPERCLK,也就是他的第13位,具體為0x2000的位置。然後就可以對GPIO進行各方面的操作。在操作完成之後,如果確定不再使用GPIO的功能可以清空該位,如果在某些特殊的應用裡面,確定不使用例如AD、DA、timer、uart等常見功能的話,可以進一步關閉HFPERCLK(HFPERCLKDIV暫存器的第8位清零),以節省更多的電量。
對這些CMU暫存器進行操作的時候,使用語句形如:CMU->HFPERCLKEN0 =0x2000;
[疑問]在對GPIO控制之前,需要首先設定相應的時鐘,即前面要加入CMU_ClockEnable(cmuClock_HFPER,true);CMU_ClockEnable(cmuClock_GPIO,true);這兩行。實際上只新增第二行即可。這讓我感到迷茫。對於IO操作的時候,難道IO口還要加入時鐘的支援(雖然資料手冊上說:高頻外設時鐘有HFCLK分頻得到,用來驅動高頻外設,如GPIO、ADC等)。難道GPIO電平的設定以及反轉都需要該時鐘的支援?
經過試驗檢視確實是這樣的,在沒有加入CMU_ClockEnable(cmuClock_GPIO,true);這句話時,對IO口所有的操作都沒有發生作用,即使主程式已經執行了對IO口的操作,IO口的那些暫存器(MODEL等)都沒有發生改變,甚至是PINLOCKN都處在0的狀態(鎖定)。這說明外部高頻時鐘沒有起作用的時候,IO根本就沒有進行初始化。
然後我試驗了這樣的操作,也就是先對IO口進行操作,然後在開啟外部高頻時鐘,發現時鐘被開啟後,IO口進行了初始化(PINLOCKN已經變成了0xffff),但是原來對IO口進行的所有的操作語句都沒有起作用。這說明所有對GPIO進行的操作都必須在外部高頻時鐘下進行。