天天看點

AT91SAM9260下GPIO的使用

《ARM Linux開發-warewin 2G/3G無線傳輸(DTU)和路由器—筆記》

GPIO通用型輸入輸出(General Purpose I/O)的簡稱,或總線擴充器,利用工業标準I2C、SMBus或SPI接口簡化了I/O口的擴充。當微控制器或晶片組沒有足夠的I/O端口,或當系統需要采用遠端串行通信或控制時,GPIO産品能夠提供額外的控制和監視功能。

以AT91SAM9260平台為例,使用GPIO進行以下步驟:

1、核心中添加驅動

把寫好的驅動檔案gpio9261.c和gpio9261.h件拷貝到linux 核心/linux-2.6.36/drivers/char/目錄下,更改此目錄中的Makefile和Kconfig檔案:

(1)在Makefile檔案中适當位置添加一行 

obj-$(CONFIG_AT9261_GPIO) += gpio9261.o

(2)在Kconfig檔案适當位置添加

config AT9261_GPIO

tristate "AT91SAM9261 User GPIO/LED support"

depends on ARCH_AT91

(3)# make menuconfig 配置核心 

選中此項character devices->

AT91SAM9261 User GPIO/LED support

(4)驅動檔案中控制管腳方向的函數如下:

static int gpio_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, int arg)

{

int *pionum = &arg;  

switch(cmd) 

{

case GPIO_DIR_INPUT: //設定管腳方向為輸入

  at91_set_GPIO_periph(*pionum, 0);   

  gpio_direction_input(*pionum);      

  break;

case GPIO_DIR_OUTPUT_HIGH: //設定管腳方向為輸出并置為高電平

   at91_set_GPIO_periph(*pionum, 0); 

   gpio_direction_output(*pionum, 1); 

   break;

case GPIO_DIR_OUTPUT_LOW:  設定管腳方向為輸出并置為低電平

    at91_set_GPIO_periph(*pionum, 0); 

    gpio_direction_output(*pionum, 0);  

    break;

 case GPIO_SET_HIGH:

     at91_set_gpio_value(*pionum, 1);     //置管腳為高電平   

     break;

 case GPIO_SET_LOW: //置管腳為低電平

       at91_set_gpio_value(*pionum, 0);            

       break;

  case GPIO_GET: //讀出該管腳電平狀态

       return at91_get_gpio_value(*pionum);        

       break;

  default:

       return -1;

  }  

return 0;

2、重新編譯核心 

把編譯生成的核心下載下傳到裝置上,系統運作後在終端運作:

# cd /dev

# ls

/dev目錄下會看到生成的/dev/gpio裝置節點,如下圖所示:

圖3.6 GPIO裝置結點圖

3、應用程式中使用GPIO

根據CPU的的情況選擇可用的管腳,避開複用的管腳、以免使用有沖突。應用程式中應包含管腳定義的檔案:#include <mach/at91_pio.h>。

應用程式中使用GPIO前需要先打開GPIO裝置/dev/gpio,然後便可使用ioctl()函數操作管腳,使用完閉後要關閉GPIO裝置。如以下程式:

#define CG_MODULE_POWER AT91_PIN_PB30

#define CG_BOARD_POWER AT91_PIN_PA0

#define CG_LINK_LED AT91_PIN_PC10 

#define CG_ACT_LED AT91_PIN_PC6 

#define CG_PWR_LED AT91_PIN_PC5

Void start_gpio(void){

int fd;

fd = open("/dev/gpio", 0);

if (fd < 0)

{

perror("Failed to open gpio");

}

ioctl(fd, GPIO_DIR_OUTPUT_HIGH,CG_PWR_LED);

ioctl(fd, GPIO_DIR_OUTPUT_LOW,CG_ACT_LED);

ioctl(fd, GPIO_DIR_OUTPUT_LOW,CG_LINK_LED);

ioctl(fd, GPIO_DIR_OUTPUT_HIGH,CG_MODULE_POWER);

ioctl(fd, GPIO_DIR_OUTPUT_LOW,CG_BOARD_POWER);

close(fd); 

}

繼續閱讀