ARM40-A5应用程序——GPIO输出高低电平
2017.03.19
一、在 shell 中控制一个IO的高低电平
(1) echo 138 > /sys/class/gpio/export // 138对应的是E10,输入这个命令后,即出现/sys/class/gpio/pioE10
(2) echo out > /sys/class/gpio/pioE10/direction // 设置E10为 out
(3) echo 1 > /sys/class/gpio/pioE10/value // 设置E10为高电平,此时万用表可测得E10的确为高电平
(4) echo 0 > /sys/class/gpio/pioE10/value // 设置E10为低电平,此时万用表可测得E10的确为低电平
(5) echo 138 > /sys/class/gpio/unexport // 不再使用时,需要unexport
在 imx6板上,gpioP_N对应的引脚编号为 nr = (P-1)*32 + N。例如 gpio6_8对应168 = (6-1)*32+8,上面的五条命令稍有不同:
(1) echo 168 > /sys/class/gpio/export // 168对应的是gpio6_8,输入这个命令后,即出现/sys/class/gpio/gpio168
(2) echo out > /sys/class/gpio/gpio168/direction
(3) echo 1 > /sys/class/gpio/gpio168/value
(4) echo 0 > /sys/class/gpio/gpio168/value
(5) echo 168 > /sys/class/gpio/unexport
二、GPIO输出高低电平的C语言源码
文件名为 test_pioE10.c,代码见本文附录(1)。该代码的核心就是第一节中的5句命令。
三、交叉编译
arm-none-linux-gnueabi-gcc -o test_pioE10 test_pioE10.c -static
四、执行程序
将交叉编译得到的 test_pioE10 文件拷贝到ARM40-A5板中,执行程序:
./test_pioE10
用示波器即可观察到E10这个IO上出现高低电平的变化。
五、 较多GPIO的C语言源码
文件名为 test_gpio.c,代码见本文附录(2)。
将交叉编译得到的 test_gpio 文件拷贝到ARM40-A5板中,执行程序:
./test_gpio E10
用示波器即可观察到E10这个IO上出现高低电平的变化。
参考文章:
http://blog.youkuaiyun.com/luyejie8888/article/details/38172705
BeagleBone Black板第四课:简单LED控制实验
http://blog.youkuaiyun.com/luyejie8888/article/details/38361525
BeagleBone Black板第五课:Shell脚本编程实验
https://developer.ridgerun.com/wiki/index.php/How_to_use_GPIO_signals
How_to_use_GPIO_signals
http://blog.youkuaiyun.com/drivermonkey/article/details/20132241?utm_source=tuicool
LinuxGPIO驱动使用其实很简单
荟聚计划:共商 共建 共享 Grant
附:
(1)test_pioE10.c 的代码
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
static inline int write_str(const char* dest, const char *str);
int main(int argc, char **argv)
{
int count = 5;
if(write_str("/sys/class/gpio/export", "138")) return(-1);
if(write_str("/sys/class/gpio/pioE10/direction","out")) return(-1);
while(count--) {
write_str("/sys/class/gpio/pioE10/value","1");
sleep(2);
write_str("/sys/class/gpio/pioE10/value","0");
sleep(2);
}
if(write_str("/sys/class/gpio/unexport", "138")) return(-1);
printf("finish!\n");
return 0;
}
static inline int write_str(const char* dest, const char *str)
{
int fd;
if((fd = open(dest, O_WRONLY)) < 0) {
perror(str);
return(fd);
}
write(fd, str, strlen(str)+1); // Include null '\0'
close(fd);
return(0);
}
(2)test_gpio.c 的代码
/*
* 注:
* 随意指定io可能会报错,例如:
* PC31已为蜂鸣器BUZZ,如果在本程序中也包含进来,运行程序的时候会报:
* sh: write error: Device or resource busy
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#define MAX_BUF 64
//只有gpio_name_list中的io才会被接受
static char* gpio_name_list[] = {
"B19","B20","B21","B22","B23","B24","B25","B26","B27","B28","B29", //51,52,...61
"C22","C23","C24","C25","C26","C27","C28", //86,87,...92
"D5","D6","D7","D8","D16","D17","D18","D19","D20","D21","D22","D23","D28","D30", //101,102,...126
"E3","E5","E10","E15","E16","E17","E18","E19","E20","E23","E24","E25","E26","E31", //131,133,...159
NULL
};
int gpio_name_match(char* gpio_name);
static inline int write_str(const char* dest, const char *str);
int gpio_output_open(const char* gpio_name);
int gpio_io_close(const char* gpio_name);
int main(int argc, char **argv)
{
int count = 5;
int fd;
if(2 != argc) { // 命令为 ./test_gpio E10, 如果不是两个参数,则报错
printf("ERR: need 1 arg.\n ");
printf("eg: ./test_gpio %s\n", argv[1]);
return -1;
}
if(0 != gpio_name_match(argv[1])) {
printf("err: argv[1]=%s isn't allowed\n",argv[1]);
return -1;
}
if((fd = gpio_output_open(argv[1])) < 0) // eg: open /sys/class/gpio/pioE10/value
return -1;
while(count--) {
write(fd, "1", sizeof("1"));
sleep(2);
write(fd, "0", sizeof("0"));
sleep(2);
}
close(fd);
gpio_io_close(argv[1]);
printf("finish!\n");
return 0;
}
// eg: str=E10, return 0;
// eg: str=E111, return -1;
int gpio_name_match(char* gpio_name)
{
int i;
for(i=0; gpio_name_list[i]!=NULL; i++) {
if(0 == strcmp(gpio_name_list[i], gpio_name))
return 0;
}
return -1; //在字符串数组中未找到,则返回-1
}
static inline int write_str(const char* dest, const char *str)
{
int fd;
if((fd = open(dest, O_WRONLY)) < 0) {
perror(str);
return(fd);
}
write(fd, str, strlen(str)+1); // Include null '\0'
close(fd);
return(0);
}
int gpio_output_open(const char* gpio_name)
{
int fd;
int gpio_id;
char gpio_id_str[4];
char buf[64];
gpio_id = ((gpio_name[0]-'A') << 5) + atoi(gpio_name+1); //eg: gpio_name="E10", gpio_id=138
snprintf(gpio_id_str, sizeof(gpio_id_str), "%d", gpio_id); //eg: gpio_id_str="138"
if(write_str("/sys/class/gpio/export", gpio_id_str)) return(-1);
snprintf(buf, sizeof(buf), "/sys/class/gpio/pio%s/direction", gpio_name);
if(write_str(buf,"out")) goto err;
snprintf(buf, sizeof(buf), "/sys/class/gpio/pio%s/value", gpio_name);
if((fd = open(buf, O_WRONLY)) < 0) goto err;
return fd;
err:
write_str("/sys/class/gpio/unexport", gpio_id_str);
return(-1);
}
int gpio_io_close(const char* gpio_name)
{
int gpio_id;
char gpio_id_str[4];
gpio_id = ((gpio_name[0]-'A') << 5) + atoi(gpio_name+1); //eg: gpio_name="E3", gpio_id=131
snprintf(gpio_id_str, sizeof(gpio_id_str), "%d", gpio_id); //eg: gpio_id_str="131"
if(write_str("/sys/class/gpio/unexport", gpio_id_str))
return(-1);
return 0;
}