Linux C编程笔记——GPIO输入

Linux C编程学习,基于正点原子阿尔法开发板。此处新学习了两个函数:sleep,秒级休眠函数;isdigit,用于判断该字符是否是数字;


#include "stdio.h"      //标准I/O库和printf函数需使用
#include "string.h"     //strcmp函数需使用
#include <unistd.h>     //access函数和sleep需使用
#include <ctype.h>      //isdigit函数需使用


char direction[100] = "";
char value[100] = "";
char active_low_addr[100] = "";
char edge[100] = "";

__uint8_t write_export(char *gpioX);//写入export文件,入口参数为GPIO编号
__uint8_t write_unexport(char *gpioX);//写入unexport文件,入口参数为GPIO编号
__uint8_t set_out(__uint8_t level);//设置输出电平
__uint8_t writt_str_file(char *file_addr, char *write_date);//向指定文件写入指定内容
__uint8_t read_file_date(char *file_addr, __uint8_t read_len, char *read_date);//向指定文件读取指定长度内容并保存到指定位置

/*
*需要给main函数传参时的写法
*argc:参数数量
*argv[]:参数储存数组
*/
int main(int argc, char *argv[])
{
    __uint8_t i = 0;
    char gpioX_addr[100] = "";

    printf("    传入参数个数=%d\n",argc);
    for(i=0; i<argc; i++)
    {
        printf("    参数%d的内容为:%s\n",i,argv[i]);
    }

    if ((argc == 2)||(argc == 3))
    {
        for(i=0;i<strlen(argv[1]);i++)//循环判断输入的I/O编号是否为纯数字
        {
            if (isdigit(argv[1][i]) == 0)
            {
                printf("    输入的I/O编号错误\n");
                return 1;
            }
        }
   
        
        /*为接下下来要使用的几个文件设置地址*/
        sprintf(gpioX_addr, "/sys/class/gpio/gpio%s",argv[1]);
        sprintf(direction, "/sys/class/gpio/gpio%s/direction",argv[1]);
        sprintf(value, "/sys/class/gpio/gpio%s/value",argv[1]);
        sprintf(active_low_addr, "/sys/class/gpio/gpio%s/active_low",argv[1]);
        sprintf(edge, "/sys/class/gpio/gpio%s/edge",argv[1]);

        printf("    %s\n", gpioX_addr);
        printf("    %s\n", direction);
        printf("    %s\n", value);
        printf("    %s\n", active_low_addr);
        printf("    %s\n", edge);

        if (access(gpioX_addr, F_OK) == -1)
        {
            printf("gpio%s文件夹不存在\n",argv[1]);
            if(write_export(argv[1]) == 1)//传入IO编号
                return 1;
        }

        if(argc == 3) 
        {
            if ( (strcmp(argv[2], "on") == 0)||(strcmp(argv[2], "1") == 0) )//传入的是on或者1
            {
                printf("    设置输出1\n");
                if(1 == set_out(1))
                {
                    printf("    设置输出1失败\n");
                    write_unexport(argv[1]);
                    return 1;
                }
                
            }
            else if ( (strcmp(argv[2], "off") == 0)||(strcmp(argv[2], "0") == 0) )//传入的是off或者0
            {
                printf("    设置输出0\n");
                if(1 == set_out(0))
                {
                    printf("    设置输出0失败\n");
                    write_unexport(argv[1]);
                    return 1;
                }
            }
        }
        else if (argc == 2)
        {
           if (1 == writt_str_file(direction, "in"))
           {
                printf("    write direction -> in failed\n");
                return 1;
           }
            
           if (1 == writt_str_file(edge, "none"))
           {
                printf("    write edge -> none failed\n");
                return 1;
           }

            if (1 == writt_str_file(active_low_addr, "0"))
           {
                printf("    write active_low -> 0 failed\n");
                return 1;
           }     
            
            char io_vlaue[2] = "";
            
            while(1)
            {
                io_vlaue[0] = 0;
                io_vlaue[1] = 0;
                if (1 == read_file_date(value, 1, io_vlaue))
                {
                    printf("    read IO failed\n");
                } 
                else
                {
                    printf("    IO level = %s\n", io_vlaue);
                } 

                sleep(1);  //延时2S          
            }
        }
    }
    // write_unexport(argv[1]);

    return 0;
}


__uint8_t write_export(char *gpioX)
{
    FILE *file1 =  NULL ;
    int ret1 = 0;
    __uint8_t error = 0;

    /* 
    *以只写的方式打开export文件,
    *如果参数 path 指定的文件存在,将文件长度截断为 0;
    *如果指定文件不存在则创建该文件。
    */
    file1 = fopen("/sys/class/gpio/export", "w");
    if (file1 == NULL)
    {
        perror("open export failed");

        error = 1;
    }

    ret1 = fwrite(gpioX, 1, strlen(gpioX), file1);//向export文件写入指定的IO编号
    if(ret1 != strlen(gpioX))
    {
        printf("    write export error \n");

        fclose(file1);
        error = 1;
    }

    fclose(file1);//关闭expoet文件

    return error;
}

__uint8_t write_unexport(char *gpioX)
{
    FILE *file1 =  NULL ;
    int ret1 = 0;
    __uint8_t error = 0;

    /* 
    *以只写的方式打开unexport文件,
    *如果参数 path 指定的文件存在,将文件长度截断为 0;
    *如果指定文件不存在则创建该文件。
    */
    file1 = fopen("/sys/class/gpio/unexport", "w");
    if (file1 == NULL)
    {
        perror("open unexport failed");

        error = 1;
    }

    ret1 = fwrite(gpioX, 1, strlen(gpioX), file1);//向export文件写入指定的IO编号
    if(ret1 != strlen(gpioX))
    {
        printf("    write unexport error \n");

        fclose(file1);
        error = 1;
    }

    fclose(file1);//关闭expoet文件

    return error;
}



__uint8_t set_out(__uint8_t level)
{
    FILE *file2 =  NULL ;
    int ret2 = 0;
    FILE *file3 =  NULL ;
    int ret3 = 0;
    FILE *file4 =  NULL ;
    int ret4 = 0;
    char active_low_value[1] = "";

    file2 = fopen(direction, "r+");//以可读可写的方式打开direction文件
    if (file2 == NULL)
    {
        perror("    open direction failed");
        return 1;
    }   

    ret2 = fwrite("out", 1, strlen("out"), file2);//设置为输出模式
    if(ret2 != strlen("out"))
    {
        printf("    write direction error \n");

        fclose(file2);
        return 1;
    }   
    fclose(file2);

    /*判断active_low的值,如果为0,那1为高;如果为1,那1为低*/
    file3 = fopen(active_low_addr, "r+");//以可读可写的方式打开value文件
    if (file3 == NULL)
    {
        perror("    open active_low failed");
        return 1;
    }   
    ret3 = fread(active_low_value, 1, 1, file3); //读一个字节
    if (ret3 != 1)
    {
        if (ferror(file3)  != 0)
            printf("    read active_low error!\n");
        
        fclose(file3);
        return 1;       
    }
    fclose(file3);

    /*判断读出的值是否是'0'或'1',如果不是就是有问题*/
    if ( (active_low_value[0] < '0') && (active_low_value[0] > '1') )
    {
        printf("    the value of active_low error!\n");
        return 1;
    }
    

    file4 = fopen(value, "r+");//以可读可写的方式打开value文件
    if (file4 == NULL)
    {
        perror("    open value failed");
        return 1;
    }

    if (level == 0)//输出低电平
    {
        if (active_low_value[0] == '0')
        {
            ret4 = fwrite("0", 1, 1, file4);
            if (ret4 != 1)
            {
                printf("out 0 write 0 failed\n");
                fclose(file4);
                return 1;
            }
        }
        else
        {
            ret4 = fwrite("1", 1, 1, file4);
            if (ret4 != 1)
            {
                printf("out 0 write 1 failed\n");
                fclose(file4);
                return 1;
            }
        }
    }
    else if (level ==1)
    {
        if (active_low_value[0] == '0')
        {
            ret4 = fwrite("1", 1, 1, file4);
            if (ret4 != 1)
            {
                printf("out 1 write 1 failed\n");
                fclose(file4);
                return 1;
            }
        }
        else
        {
            ret4 = fwrite("0", 1, 1, file4);
            if (ret4 != 1)
            {
                printf("out 1 write 0 failed\n");
                fclose(file4);
                return 1;
            }
        }        
    }

    return 0;
}

__uint8_t writt_str_file(char *file_addr, char *write_date)
{
    FILE *file =  NULL ;
    int ret = 0;    
    
    file = fopen(file_addr, "w");//以只写的方式打开指定文件
    if (file == NULL)
    {
        perror("    open file failed");
        return 1;
    }   

    ret = fwrite(write_date, 1, strlen(write_date), file);//设置为输出模式
    if(ret != strlen(write_date))
    {
        printf("    write %s error \n", write_date);

        fclose(file);
        return 1;
    }   
    fclose(file);

    return 0;
}

__uint8_t read_file_date(char *file_addr, __uint8_t read_len, char *read_date)
{
    FILE *file =  NULL ;
    int ret = 0;  

    file = fopen(file_addr, "r");//以只读的方式打开指定文件
    if (file == NULL)
    {
        perror("    open file failed");
        return 1;
    }   

    ret = fread(read_date, 1, read_len, file); //读指定长度
    if (ret != read_len)
    {
        if (ferror(file)  != 0)//判断是否发生错误
        {
            printf("    read active_low error!\n");
            fclose(file);
            return 1; 
        }
        else if (feof(file) != 0)//判断是否到达文件末尾
        {
            printf("    read %s at the end of file!\n", file_addr);
            fclose(file);
            return 0; 
        }
        else//没有发生错误,也没有到达文件末尾,但是读取的字节数小于设定的字节数
        {
            printf("    read %s don't  konw what happened!\n", file_addr);
            return 1;
        }
    }
    fclose(file);

    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值