(Embedded)Linux I/O相關閱讀筆記-S3C2410X GPIO
(Embedded)Linux I/O相關閱讀筆記-S3C2410X GPIO
S3C2410X GPIO 介紹
GPACON-GPHCON 在S3C2410X 中,大多數的引腳都複用,所以必須對每個引腳進行配置。埠控制寄存器(GPnCON)定義了每個引腳的功能。
GPADAT-GPHDAT 如果埠被配置成了輸出埠,可以向GPnDAT的相應位元寫資料。如果埠被配置成了輸入埠,可以從GPnDAT的相應位元讀出資料。
GPBUP-GPHUP 埠上拉寄存器控制了每個埠組的上拉電阻的允許/禁止。如果某一位為0,相應的上拉電阻被允許;如果是1,相應的上拉電阻被禁止。
如果埠的上拉電阻被允許,無論在哪種狀態(INPUT、OUTPUT、DATAn、EINTn等)下,上拉電阻都起作用
埠A寄存器(GPACON/GPADAT)
寄存器 地址 讀/寫 描述 複位值
GPACON 0x56000000 R/W 埠A配置寄存器 0x7fffff
GPADAT 0x56000004 R/W 埠A資料寄存器 未定義
(1)GPACON[22:0]中的某一位置位,設置與該位相對應的引腳為輸出口,清零某位可以設置相應的引腳為功能埠
GPACON 位 描述
GPA22 [22] 0 = Output 1 = nFCE
。。。 。。 。。。
GPA1 [1] 0 = Output 1 = ADDR16
GPA0 [0] 0 = Output 1 = ADDR0
(2)GPADAT寄存器
GPADAT 位 描述
GPA[22:0] [22:0] 當埠被配置成輸出時,引腳狀態和相應的位元狀態一致;當埠被配置成功能腳時,讀出的值不一定
S3C2410X GPIO LED控制
電路連接
LED_1~LED_4分別與GFP7~GPF4相連
通過GFP7~GPF4引腳的高低電平來控制發光二極體的亮與滅。
當這幾個引腳輸出高電平的時候發光二極體熄滅,
當這幾個引腳輸出低電平的時候發光二極體點亮。
寄存器設置
為了實現控制LED的目的,需要通過配置GPFCON寄存器將GPF4、GPF5、GPF6、GPF7設置為輸出屬性。如:配置GPFCON[9:8]兩位為“01”,可實現將GPF4設置為輸出屬性。
通過設置GFPDAT寄存器實現點亮與熄滅LED。如:配置GPFDAT[4]為“0”,可實現點亮LED4。配置GPFDAT[4]為“1”,可實現關閉LED4。
對於本例來說,GPFUP可以不用設置。
程式的編寫
1、相關寄存器定義 ( S3C2410X datasheet.pdf P275)
#define rGPFCON (*(volatile unsigned *)0x56000050) //埠F的控制寄存器
#define rGPFDAT (*(volatile unsigned *)0x56000054) //埠F的資料寄存器
#define rGPFUP (*(volatile unsigned *)0x56000058) //埠F的上拉控制寄存器
2、埠初始化
void port_init(void)
{
//=== PORT F GROUP ( S3C2410X datasheet.pdf P275 一個PIN要用兩個BIT來控制因為有超過兩個狀態)
//埠: GPF7 GPF6 GPF5 GPF4 GPF3 GPF2 GPF1 GPF0
//信號: LED_1 LED_2 LED_3 LED_4 PS2_INT CPLD_INT1 KEY_INT BUT_INT1
//設置屬性: Output Output Output Output EINT3 EINT2 EINT1 EINT0
//二進位值: 01 01 01 01 10 10 10 10
rGPFCON = 0x55aa;//0101010110101010
rGPFUP = 0xff; // GPF所有埠都不加上拉電阻
}
3、開啟LED
void led_on(void)
{
int i,nOut;
nOut=0xF0;
rGPFDAT=nOut & 0x70; //點亮LED1
for(i=0;i<100000;i++);
rGPFDAT=nOut & 0x30; //點亮LED1 LED2
for(i=0;i<100000;i++);
rGPFDAT=nOut & 0x10; //點亮LED1 LED2 LED3
for(i=0;i<100000;i++);
rGPFDAT=nOut & 0x00; //點亮LED1 LED2 LED3 LED4
for(i=0;i<100000;i++);
}
4、關閉LED
void led_off(void)
{
int i,nOut;
nOut=0;
rGPFDAT = 0;
for(i=0;i<100000;i++);
rGPFDAT = nOut | 0x80; //關閉LED1
for(i=0;i<100000;i++);
rGPFDAT |= nOut | 0x40; //關閉LED2
for(i=0;i<100000;i++);
rGPFDAT |= nOut | 0x20; //關閉LED3
for(i=0;i<100000;i++);
rGPFDAT |= nOut | 0x10; //關閉LED4
for(i=0;i<100000;i++);
}
PS 該ARM在LINUX BASE下時會有對應的函數提供作暫存器存取