设为首页收藏本站
查看: 12768|回复: 0

ARM Linux下GPIO应用程序例程

[复制链接]

231

主题

64

回帖

2145

积分

管理员

积分
2145
玉米糊 发表于 2014-9-1 11:43:31 | 显示全部楼层 |阅读模式

源码压缩包
gpio.tar.gz (6.46 KB, 下载次数: 11734)
包含源码、Makefile文件、镜像文件(使用arm-none-linux-gnueabi-gcc编译)

源码
[mw_shl_code=c,true]/********************************************************************
*                 copyright (C) 2014 all rights reserved
*                         @file: gpio.c
*                   @Created: 2014-8-6 15:00
*                      @Author: conway chen
*           @Description: test gpios interrupt
*          @Modify Date: 2014-8-6 15:00
*********************************************************************/
#include<stdio.h>
#include <stdlib.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<unistd.h>
#include<errno.h>
#include<string.h>
#include <poll.h>

#define SYSFS_GPIO_DIR "/sys/class/gpio"
#define GPIO_LED 41
#define MAX_BUF 60
#define POLL_TIMEOUT (3 * 1000) /* 3 seconds */
#define OUT 1
#define IN 0

/**
* brief: export the GPIO to user space
* @Param: gpio: the GPIO number
*/
int gpio_export(unsigned int gpio)
{
        int fd ,len;
        char buf[MAX_BUF];

        fd = open(SYSFS_GPIO_DIR "/export" ,O_WRONLY);
        if (fd < 0) {
                perror("gpio/export");
                return fd;
        }
        len = snprintf(buf ,sizeof(buf) ,"%d" ,gpio);
        write(fd ,buf ,len);
        close(fd);
        return 0;
}

/**
* brief: unexport the GPIO to user space
* @Param: gpio: the GPIO number
*/  
int gpio_unexport(unsigned int gpio)
{
        int fd ,len;
        char buf[MAX_BUF];

        fd = open(SYSFS_GPIO_DIR "/unexport" ,O_WRONLY);
        if (fd < 0) {
                perror("gpio/unexport");
                return fd;
        }
        len = snprintf(buf ,sizeof(buf) ,"%d" ,gpio);
        write(fd ,buf ,len);
        close(fd);
        return 0;
}

/**
* brief: configure GPIO for input or output
* @Param: gpio: the GPIO number
* @Param: out_flag: the flag of output or input.It's value can be 1 or 0.  
*/
int gpio_set_dir(unsigned int gpio ,int out_flag)
{
        int fd ,len;
        char buf[MAX_BUF];

        len = snprintf(buf, sizeof(buf), SYSFS_GPIO_DIR "/gpio%d/direction", gpio);
        fd = open(buf ,O_WRONLY);
        if (fd < 0) {
                perror(buf);
                return fd;
        }
        if (out_flag)
                write(fd ,"out" ,4);
        else
                write(fd ,"in" ,3);
        close(fd);
        return 0;
}

/**
* brief: Set the value of GPIO
* @Param: gpio: the GPIO number
* @Param: value: the value of GPIO. Supports values of 0 and 1.
*/  
int gpio_set_value(unsigned int gpio, unsigned int value)  
{  
    int fd, len;  
    char buf[MAX_BUF];  
   
    len = snprintf(buf, sizeof(buf), SYSFS_GPIO_DIR "/gpio%d/value", gpio);      
    fd = open(buf, O_WRONLY);
        if (fd < 0) {  
        perror("gpio/set-value");  
        return fd;  
    }  
   
    if (value)  
        write(fd, "1", 2);  
    else  
        write(fd, "0", 2);  
   
    close(fd);  
    return 0;  
}

/**
* brief: get the value of GPIO
* @Param: gpio: the GPIO number
* @Param: value: pointer to the value of GPIO
*/
int gpio_get_value(unsigned int gpio, unsigned int *value)
{
        int fd, len;
        char ch;
        char buf[MAX_BUF];

        len = snprintf(buf ,sizeof(buf), SYSFS_GPIO_DIR "/gpio%d/value" ,gpio);
        fd = open(buf ,O_RDONLY);
        if (fd < 0) {
                perror("gpio_get_value");
                return fd;
        }
        read(fd ,&ch ,1);
        if (ch == '1')
                *value = 1;
        else if(ch == '0')
                        *value = 0;
        close(fd);
        return 0;
}

/**
* brief: set the edge that trigger interrupt
* @Param: gpio: the GPIO number
* @Param: edge:  edge that trigger interrupt
*/
int gpio_set_edge(unsigned int gpio ,char *edge)
{
        int fd ,len;
        char buf[MAX_BUF];

        len = snprintf(buf ,sizeof(buf) ,SYSFS_GPIO_DIR "/gpio%d/edge" ,gpio);
        fd = open(buf ,O_WRONLY);
        if (fd < 0) {
                perror("gpio_set_edge");
                return fd;
        }
        write(fd ,edge ,strlen(edge) + 1);
        close(fd);
        return 0;
}

/**
* brief: open gpio device and return the file descriptor
* @Param: gpio: the GPIO number
*/  
int gpio_fd_open(unsigned int gpio)  
{  
    int fd, len;  
    char buf[MAX_BUF];  
  
    len = snprintf(buf, sizeof(buf), SYSFS_GPIO_DIR "/gpio%d/value", gpio);  
   
    fd = open(buf, O_RDONLY | O_NONBLOCK );  
    if (fd < 0) {  
        perror("gpio/fd_open");  
    }  
    return fd;  
}  
  
/**
* brief: close gpio device
* @Param: fd: the file descriptor of gpio
*/
int gpio_fd_close(int fd)  
{  
    return close(fd);  
}  
  
/**
* @brief: main function
* @Param: argc: number of parameters
* @Param: argv: parameters list
*/  
int main(int argc, char **argv)  
{  
    struct pollfd *fdset;  
    int nfds = 1;  
    int gpio_fd, timeout, rc;  
    char *buf[MAX_BUF];  
    unsigned int gpio;  
    int len;
    char *cmd;
    unsigned int value;
      
          fdset = (struct pollfd*)malloc(sizeof(struct pollfd));  
  
    if (argc < 3) {  
        printf("Usage: %s <gpio-pin> <direction> [value]\n\n", argv[0]);        
        exit(-1);  
    }
    cmd = argv[2];
    gpio = atoi(argv[1]);
        gpio_export(gpio);
        
    if (strcmp(cmd, "interrupt") == 0) {
            printf("\n**************************GPIO interrupt***************************\n");
                  
                gpio_set_dir(gpio, IN);  
                gpio_set_edge(gpio, "rising");  
                gpio_fd = gpio_fd_open(gpio);
               
                /* GPIO_LED configure */
                //gpio_export(GPIO_LED);  
                //gpio_set_dir(GPIO_LED, OUT);
               
                timeout = POLL_TIMEOUT;  
           
                while (1) {  
                    memset((void*)fdset, 0, sizeof(fdset));
                    fdset->fd = gpio_fd;  
                    fdset->events = POLLPRI;  
         
                    rc = poll(fdset, nfds, timeout);        
         
                    if (rc < 0) {  
                        printf("\npoll() failed!\n");  
                        return -1;  
                    }  
                    
                    if (rc == 0) {  
                        printf(".");
                        /* LED off */
                        //gpio_set_value(GPIO_LED, 1);  
                    }  
                          
                    if (fdset->revents & POLLPRI) {  
                        len = read(fdset->fd, buf, MAX_BUF);  
                        printf("\nGPIO %d interrupt occurred\n", gpio);
                        /* when GPIO interrupt occurred, LED turn on */
                        //gpio_set_value(GPIO_LED, 0);  
                    }
                    fflush(stdout);   
                }
               
                gpio_fd_close(gpio_fd);
                           
    } else if (strcmp(cmd, "out") == 0) {
            
                gpio_set_dir(gpio, OUT);
                        
                  if (argc = 4) {
                          gpio_set_value(gpio, atoi(argv[3]));
                          printf("gpio%d is set to %d\n", gpio, atoi(argv[3]));        
                  }
          } else if (strcmp(cmd, "in") == 0) {
                  
                  gpio_set_dir(gpio, IN);
                  printf("\n");
                  
                  while (1) {
                          gpio_get_value(gpio, &value);
                          printf("\rvalue:%d", value);
                  }
                  
          } else if (strcmp(cmd, "unexport") == 0) {
                  gpio_unexport(gpio);        
          }
         
          else {
                  printf("Usage: %s <gpio-pin> <direction> [value]\n\n", argv[0]);        
        exit(-1);        
          }                    
     
    return 0;  
}
[/mw_shl_code]


测试
IM28X
执行以下命令配置开发板上的PD14引脚为中断功能,并给该引脚一个下降沿触发 ,程序检测到下降沿后将打印出相关信息。
[mw_shl_code=bash,true]root@freescale ~$ ./gpio 99 interrupt

****************************GPIO interrupt*****************************

GPIO 99 interrupt occurred
.......
GPIO 99 interrupt occurred[/mw_shl_code]

执行以下命令将gpio口配置为输出功能并设置对应值:
[mw_shl_code=bash,true]root@freescale ~$ ./gpio 99 out 0
gpio99 is set to 0
root@freescale ~$ ./gpio 99 out 1
gpio99 is set to 1[/mw_shl_code]

执行以下命令将gpio口配置为输入功能并获取输入值:
[mw_shl_code=bash,true]root@freescale ~$ ./gpio 99 in

value:1[/mw_shl_code]

执行以下命令导出gpio口:
[mw_shl_code=bash,true]root@freescale ~$ ./gpio 99 unexport[/mw_shl_code]



AM335X
执行以下命令配置开发板上的gpio3_5引脚为中断功能,并给该引脚一个下降沿触发 ,程序检测到下降沿后将打印出相关信息。
[mw_shl_code=bash,true]root@MYD-AM335X:~# ./gpio 101 interrupt

****************************GPIO interrupt*****************************

GPIO 101 interrupt occurred
....
GPIO 101 interrupt occurred[/mw_shl_code]

执行以下命令将gpio口配置为输出功能并设置对应值:
[mw_shl_code=bash,true]root@MYD-AM335X:~# ./gpio 101 out 0
gpio101 is set to 0
root@MYD-AM335X:~# ./gpio 101 out 1
gpio101 is set to 1[/mw_shl_code]

执行以下命令将gpio口配置为输入功能并获取输入值:
[mw_shl_code=bash,true]root@MYD-AM335X:~# ./gpio 101 in   

value:0[/mw_shl_code]

执行以下命令导出gpio口:
[mw_shl_code=bash,true]root@MYD-AM335X:~# ./gpio 101 unexport[/mw_shl_code]




回复

使用道具 举报

您需要登录后才可以回帖 登录

本版积分规则

Archiver|手机版|小黑屋|米尔科技论坛   

GMT+8, 2024-5-6 00:00 , Processed in 0.133433 second(s), 35 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表