LPC1114通用輸入/輸出端口(GPIO)續(xù)
首先看DIR寄存器,其偏移地址為0x8000,屬性為可讀可寫,它負責GPIO引腳的方向,即引腳是用做輸入還是輸出,由該寄存器的設置來決定。雖然DIR寄存器也是32位結構,但由于LPC1114每組只有12個引腳,所以只用了其中的低12位。當位為0 時做輸入,為1時做輸出,12位與12個引腳一一對應,每位設置對應一個引腳。在默認狀態(tài)下DIR的值為全0,所以在默認狀態(tài)下所有的引腳為輸入狀態(tài)。要改變引腳狀態(tài),可通過寫DIR寄存器對應的位來實現(xiàn)。例如,要把端口0的第1、3、5腳設為輸入,其它全為輸出,執(zhí)行語句“LPC_GPIO0->DIR = 0xFD5;”就可以了。
本文引用地址:http://m.butianyuan.cn/article/201611/316323.htm接下來看IS寄存器,其偏移地址為0x8004,屬性為可讀可寫,它負責GPIO引腳外部中斷的觸發(fā)方式,即引腳響應中斷是電平觸發(fā)還是邊沿觸發(fā),由該寄存器的設置來決定。IS寄存器也只用了32位中的低12位,當位為0 時選擇邊沿觸發(fā),為1時選擇電平觸發(fā),12位與12個引腳一一對應,每位設置對應一個引腳。在默認狀態(tài)下IS的值為全0,所以在默認狀態(tài)下所有的引腳在外部中斷時是邊沿觸發(fā)方式。要改變引腳中斷的觸發(fā)方式,可通過寫IS寄存器對應的位來實現(xiàn)。例如,要把端口1的第11腳設為電平觸發(fā),執(zhí)行語句“LPC_GPIO1->IS |= 0x800;”就可以了。另外,在選擇觸發(fā)方式時要注意,若選擇了電平觸發(fā),必須要考慮是否會在觸發(fā)電平保持期間引發(fā)多次外部中斷響應。一般情況下,選擇邊沿觸發(fā)方式就不會存在這個問題。
接著看IEV寄存器,其偏移地址為0x800C,屬性為可讀可寫,它負責配合上面的IS寄存器來確定具體的觸發(fā)方式。即:若IS配置為邊沿觸發(fā)方式,則IEV負責選擇是上跳沿還是下跳沿;若IS配置為電平觸發(fā)方式,則IVE負責選擇是高電平觸發(fā)還是低電平觸發(fā)。IVE寄存器也只用了32位中的低12位,當位為0 時選擇下跳沿觸發(fā)或低電平觸發(fā)方式,為1時選擇上跳沿觸發(fā)或高電平觸發(fā)方式,12位與12個引腳一一對應,每位設置對應一個引腳。在默認狀態(tài)下IEV的值為全0,所以在默認狀態(tài)下所有的引腳在外部中斷時是下跳沿觸發(fā)或低電平觸發(fā)方式。要改變引腳中斷的具體觸發(fā)方式,可通過寫IEV寄存器對應的位來實現(xiàn)。例如,要把端口2的第5腳設為高電平觸發(fā),執(zhí)行兩句語句“LPC_GPIO1->IS |= 0x020;LPC_GPIO1->IVE |=0x020;”就可以了。另外要強調一點,IEV寄存器必須和IS寄存器配合使用。一般來說,應先配置IS,再配置IVE。
接下來是IBE寄存器,其偏移地址為0x8008,屬性為可讀可寫,它負責GPIO在外部中斷時,用來選擇是否使用雙邊沿觸發(fā)方式。在某些特殊應用的地方(比如需要同時捕獲脈沖的上跳沿和下跳沿時),需要在程序中頻繁轉換觸發(fā)方式,而在LPC1114中由于有IBE寄存器,所以操作就簡單多了,只要通過設置IBE寄存器來使能對應引腳的雙沿觸發(fā)方式就可以了。IBE寄存器也只用了32位中的低12位,當位為0 時關閉雙沿觸發(fā),此時的觸發(fā)方式由IEV寄存器決定。為1時開啟雙沿觸發(fā),12位與12個引腳一一對應,每位設置對應一個引腳。在默認狀態(tài)下IBE的值為全0,所以在默認狀態(tài)下所有的引腳在外部中斷時雙沿觸發(fā)方式處于關閉狀態(tài)。要使能雙邊沿觸發(fā)方式,可通過寫IBE寄存器對應的位來實現(xiàn)。例如,要把端口3的第1腳設為雙沿觸發(fā)方式,執(zhí)行兩句語句“LPC_GPIO2->IS &= ~0x002;LPC_GPIO2->IBE |=0x002;”就可以了。另外有一點需要強調一下,如果某引腳被IBE設置為雙邊沿觸發(fā),則其對應的IEV設置就不起作用了。還有就是IBE寄存器也必須和IS寄存器配合使用,一般來說,應先配置IS,再配置IBE。
下一個是IE寄存器,其偏移地址為0x8010,屬性為可讀可寫,它負責使能GPIO引腳的外部中斷功能。該寄存器也只用了32位中的低12位,當位為0 時中斷功能被屏蔽(即中斷不使能),為1時中斷功能未屏蔽(即中斷使能),12位與12個引腳一一對應,每位設置對應一個引腳。在默認狀態(tài)下IE的值為全0,所以在默認狀態(tài)下所有的引腳不使用外部中斷(中斷全部被屏蔽)。要使能某引腳的外部中斷功能,可通過寫IE寄存器對應的位來實現(xiàn)。例如,要開啟端口0的第1引腳中斷功能,執(zhí)行語句“LPC_GPIO0->IE = 0x002;”就可以了。
再下一個是RIS寄存器,其偏移地址為0x8014,屬性為只讀,它負責查詢哪個GPIO引腳上有中斷請求。該寄存器也只用了32位中的低12位,當位為0 時表明對應引腳上沒有外部中斷請求發(fā)生,為1時表明對應引腳上有外部中斷請求發(fā)生,12位與12個引腳一一對應,每位設置對應一個引腳。在復位時RIS的值為全0,表明所有的引腳復位時都沒有外部中斷請求發(fā)生。如果某個引腳上RIS對應的值為1,則表明該引腳上有符合條件的中斷請求發(fā)生,此時若對應的IE位也為1(即開啟該引腳的中斷功能),就會發(fā)生該引腳的中斷響應。但如果對應的IE位不為1,則不會響應中斷。
接下來是MIS寄存器,其偏移地址為0x8018,屬性為只讀,它和上面的RIS寄存器基本是一樣的,可以用于查詢是否有中斷響應。不同點在于,RIS是只要引腳上滿足中斷觸發(fā)條件它對應的位就被置1,但它不一定被響應,因為它有可能被屏蔽了(例如對應的IE位沒有被置1),因此RIS不能判定中斷是否響應了,而只能判定有符合條件的中斷請求發(fā)生;但在MIS寄存器中,若相應的位被置1了,則說明這個中斷一定被響應了,因此可以通過程序查詢MIS寄存器的方式來判斷是否有中斷被響應,是哪個引腳上的中斷被響應。其實MIS寄存器表征的就是屏蔽之后的中斷狀態(tài),它也只用了32位中的低12位,當位為0 時表明對應引腳上沒有外部中斷響應,為1時表明對應引腳上有外部中斷響應,12位與12個引腳一一對應,每位設置對應一個引腳。
最后一個是IC寄存器,其偏移地址為0x801C,屬性為只寫,它用來清除中斷邊沿檢測邏輯。它也只用了32位中的低12位,當位為0 時不起作用,即對外部中斷無任何影響,為1時表明對應引腳上的邊沿觸發(fā)端口位被清零,12位與12個引腳一一對應,每位設置對應一個引腳。之所以要設IC寄存器,是因為在中斷響應后(僅邊沿型觸發(fā)),在RIS和MIS寄存器中相應的位不會被自動清零,因此在中斷響應后需要在IC寄存器的相應位中寫1來進行清零,以保證后續(xù)中斷的正常觸發(fā)。
以上是GPIO中各寄存器功能的基本介紹,至于詳細的使用方法,會在后面中斷一章中做詳細討論,這里先不贅述了。
接下來討論一下GPIO端口引腳的配置。從第一章中已經知道,LPC1114引腳復用的很多,除了第0端口中的3、第2端口中的2~10和第3端口中的4、5引腳外,其余的引腳都具有第二功能。甚至包括復位端RESET都復用在了GPIO0_0引腳。為了實現(xiàn)引腳上各復用功能間的切換,在處理器內部專門設立了一個引腳配置寄存器IOCON。用戶可以通過IOCON來配置每一個I/O的下列功能特性:
{
__IO uint32_t PIO2_6; /*!< Offset: 0x000 (R/W) I/O configuration for pin PIO2_6 */
uint32_t RESERVED0[1];
__IO uint32_t PIO2_0; /*!< Offset: 0x008 (R/W) I/O configuration for pin PIO2_0/DTR/SSEL1 */
__IO uint32_t RESET_PIO0_0; /*!< Offset: 0x00C (R/W) I/O configuration for pin RESET/PIO0_0 */
__IO uint32_t PIO0_1; /*!< Offset: 0x010 (R/W) I/O configuration for pin PIO0_1/CLKOUT/CT32B0_MAT2 */
__IO uint32_t PIO1_8; /*!< Offset: 0x014 (R/W) I/O configuration for pin PIO1_8/CT16B1_CAP0 */
uint32_t RESERVED1[1];
__IO uint32_t PIO0_2; /*!< Offset: 0x01C (R/W) I/O configuration for pin PIO0_2/SSEL0/CT16B0_CAP0 */
__IO uint32_t PIO2_7; /*!< Offset: 0x020 (R/W) I/O configuration for pin PIO2_7 */
__IO uint32_t PIO2_8; /*!< Offset: 0x024 (R/W) I/O configuration for pin PIO2_8 */
__IO uint32_t PIO2_1; /*!< Offset: 0x028 (R/W) I/O configuration for pin PIO2_1/nDSR/SCK1 */
__IO uint32_t PIO0_3; /*!< Offset: 0x02C (R/W) I/O configuration for pin PIO0_3 */
__IO uint32_t PIO0_4; /*!< Offset: 0x030 (R/W) I/O configuration for pin PIO0_4/SCL */
__IO uint32_t PIO0_5; /*!< Offset: 0x034 (R/W) I/O configuration for pin PIO0_5/SDA */
__IO uint32_t PIO1_9; /*!< Offset: 0x038 (R/W) I/O configuration for pin PIO1_9/CT16B1_MAT0 */
__IO uint32_t PIO3_4; /*!< Offset: 0x03C (R/W) I/O configuration for pin PIO3_4 */
__IO uint32_t PIO2_4; /*!< Offset: 0x040 (R/W) I/O configuration for pin PIO2_4 */
__IO uint32_t PIO2_5; /*!< Offset: 0x044 (R/W) I/O configuration for pin PIO2_5 */
__IO uint32_t PIO3_5; /*!< Offset: 0x048 (R/W) I/O configuration for pin PIO3_5 */
__IO uint32_t PIO0_6; /*!< Offset: 0x04C (R/W) I/O configuration for pin PIO0_6/SCK0 */
__IO uint32_t PIO0_7; /*!< Offset: 0x050 (R/W) I/O configuration for pin PIO0_7/nCTS */
__IO uint32_t PIO2_9; /*!< Offset: 0x054 (R/W) I/O configuration for pin PIO2_9 */
__IO uint32_t PIO2_10; /*!< Offset: 0x058 (R/W) I/O configuration for pin PIO2_10 */
__IO uint32_t PIO2_2; /*!< Offset: 0x05C (R/W) I/O configuration for pin PIO2_2/DCD/MISO1 */
__IO uint32_t PIO0_8; /*!< Offset: 0x060 (R/W) I/O configuration for pin PIO0_8/MISO0/CT16B0_MAT0 */
__IO uint32_t PIO0_9; /*!< Offset: 0x064 (R/W) I/O configuration for pin PIO0_9/MOSI0/CT16B0_MAT1 */
__IO uint32_t SWCLK_PIO0_10; /*!< Offset: 0x068 (R/W) I/O configuration for pin SWCLK/PIO0_10/SCK0/CT16B0_MAT2 */
__IO uint32_t PIO1_10; /*!< Offset: 0x06C (R/W) I/O configuration for pin PIO1_10/AD6/CT16B1_MAT1 */
__IO uint32_t PIO2_11; /*!< Offset: 0x070 (R/W) I/O configuration for pin PIO2_11/SCK0 */
__IO uint32_t R_PIO0_11; /*!< Offset: 0x074 (R/W) I/O configuration for pin TDI/PIO0_11/AD0/CT32B0_MAT3 */
__IO uint32_t R_PIO1_0; /*!< Offset: 0x078 (R/W) I/O configuration for pin TMS/PIO1_0/AD1/CT32B1_CAP0 */
__IO uint32_t R_PIO1_1; /*!< Offset: 0x07C (R/W) I/O configuration for pin TDO/PIO1_1/AD2/CT32B1_MAT0 */
__IO uint32_t R_PIO1_2; /*!< Offset: 0x080 (R/W) I/O configuration for pin nTRST/PIO1_2/AD3/CT32B1_MAT1 */
__IO uint32_t PIO3_0; /*!< Offset: 0x084 (R/W) I/O configuration for pin PIO3_0/nDTR */
__IO uint32_t PIO3_1; /*!< Offset: 0x088 (R/W) I/O configuration for pin PIO3_1/nDSR */
__IO uint32_t PIO2_3; /*!< Offset: 0x08C (R/W) I/O configuration for pin PIO2_3/RI/MOSI1 */
__IO uint32_t SWDIO_PIO1_3; /*!< Offset: 0x090 (R/W) I/O configuration for pin SWDIO/PIO1_3/AD4/CT32B1_MAT2 */
__IO uint32_t PIO1_4; /*!< Offset: 0x094 (R/W) I/O configuration for pin PIO1_4/AD5/CT32B1_MAT3 */
__IO uint32_t PIO1_11; /*!< Offset: 0x098 (R/W) I/O configuration for pin PIO1_11/AD7 */
__IO uint32_t PIO3_2; /*!< Offset: 0x09C (R/W) I/O configuration for pin PIO3_2/nDCD */
__IO uint32_t PIO1_5; /*!< Offset: 0x0A0 (R/W) I/O configuration for pin PIO1_5/nRTS/CT32B0_CAP0 */
__IO uint32_t PIO1_6; /*!< Offset: 0x0A4 (R/W) I/O configuration for pin PIO1_6/RXD/CT32B0_MAT0 */
__IO uint32_t PIO1_7; /*!< Offset: 0x0A8 (R/W) I/O configuration for pin PIO1_7/TXD/CT32B0_MAT1 */
__IO uint32_t PIO3_3; /*!< Offset: 0x0AC (R/W) I/O configuration for pin PIO3_3/nRI */
__IO uint32_t SCK_LOC; /*!< Offset: 0x0B0 (R/W) SCK pin location select Register */
__IO uint32_t DSR_LOC; /*!< Offset: 0x0B4 (R/W) DSR pin location select Register */
__IO uint32_t DCD_LOC; /*!< Offset: 0x0B8 (R/W) DCD pin location select Register */
__IO uint32_t RI_LOC; /*!< Offset: 0x0BC (R/W) RI pin location Register */
} LPC_IOCON_TypeDef;
上述結構體定義在頭文件LPC11xx.h中。
每一個IOCON寄存器都是32位結構,但它最多只用了其中的低11位,因為根據各引腳功能不同,設置所占用的位數(shù)是不一樣的。為了方便討論,下表給出一個IOCON寄存器的一般位域定義描述,在實際用到引腳的不同設置時,請自行查詢數(shù)據手冊。
下面對引腳配置做幾點說明:
1.若引腳被配置為GPIO,則可用DIR寄存器來設置其方向(即輸入/輸出);若配置為非GPIO功能時,DIR設置無效。
2.若引腳被配置為GPIO,則默認為帶上拉的方式,但無論是上拉還是下拉,都是弱拉式的(片內40k電阻),若要強拉必須外接電阻。
3.滯后作用即為輸入緩沖,它只能在外部引腳電壓為2.5~3.6V時才能使用,當電壓低于2.5V時必須禁能。
4.選擇A/D轉換模式時,內部數(shù)字接收部分被斷開,以保證輸入電壓的精度,若只接收高低電平,必須設為數(shù)字模式,否則讀不到電平。
5.只有部分引腳有A/D模式和I2C模式(見FUNC表),其它引腳配置為此模式時無效,若引腳配置為A/D模式后,滯后和上/下拉配置無效。
6.所有引腳配置的IOCON在復位時,值為0xD0,表示默認時引腳為復用功能第0組,上拉電阻模式,禁能滯后特性,數(shù)字模式。
7.在使用程序配置時,要注意IOCON的第6位(保留位)必須寫1,因其復位值為1。
8.其它四個多于的特殊配置寄存器(SCK_LOC、DSR_LOC、DCD_LOC、RI_LOC)主要用來定位某引動功能的引腳,具體用法請參考手冊。
9.在配置IOCON之前必須把IOCON的時鐘(位于AHBCLKCTRL寄存器中的第16位)打開,否則配置不了,配置完成后再把時鐘關閉,以節(jié)約電能。
最后來看幾個例子:
一、要求把端口0的第0腳配置為GPIO口,方向為輸出,帶上拉,輸出值為0。
執(zhí)行:LPC_SYSCON->SYSAHBCLKCTRL |= (1<<16);
LPC_IOCON->RESET_PIO0_0 = 0xD1;
LPC_SYSCON->SYSAHBCLKCTRL &= ~(1<<16);
LPC_GPIO0->DIR |= 0x001;
LPC_GPIO0->MASKED_ACCESS[1] = 0x000;
二、要求把端口1的第1腳配置為A/D輸入口。
執(zhí)行:LPC_SYSCON->SYSAHBCLKCTRL |= (1<<16);
LPC_IOCON->R_PIO1_1= 0x42;
LPC_SYSCON->SYSAHBCLKCTRL &= ~(1<<16);
三、要求把端口1的第3腳配置為CT32B1_MAT2模式。
執(zhí)行:LPC_SYSCON->SYSAHBCLKCTRL |= (1<<16);
LPC_IOCON->SWDIO_PIO1_3= 0xD3;
LPC_SYSCON->SYSAHBCLKCTRL &= ~(1<<16);
評論