按照之前的测评计划,还差一篇人机交互相关功能测评(按键、显示屏、触摸等),因为触摸和显示屏的功能是原厂直接做好了的,并且在之前的GTK相关文章中也使用了显示屏和触摸,那么我就写一下按键吧,其本质也就是GPIO输入。
之前写过一篇关于 GPIO输出的,就是点灯,今天来做一下GPIO INPUT的试验。
因为之前点灯时已经发现开发板上的用户按键已经被占用,那我就使用一下CN8这一大堆的GPIO
通过文档可以查询到全部引脚的说明,如下图所示
使用在点灯中用过的gpioinfo指令,和表格对应,看那个GPIO没有被使用。我这边随便找了一个PB1,对应就是gpiochip1的line 1
接下来就是基于之前的点灯代码,改成GPIO input的代码,代码如下
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <linux/gpio.h>
int main(int argc, char **argv)
{
struct gpiohandle_request req;
struct gpiohandle_data data;
char chrdev_name[20];
int fd, ret;
strcpy(chrdev_name, "/dev/gpiochip1");
/* 打开GPIO设备 */
fd = open(chrdev_name, 0);
if (fd == -1)
{
ret = -errno;
fprintf(stderr, "Failed to open %s\n", chrdev_name);
return ret;
}
/* 设置使用的几号GPIO,和输入输出模式等 */
req.lineoffsets[0] = 1;//1号,与之前的gpiochip1组合,即表示PB1
req.flags = GPIOHANDLE_REQUEST_INPUT;//输入模式
req.lines = 1; // 只请求一个线路的句柄
req.consumer_label[0] = '\0'; // 不需要为读取设置任何标签或默认值
/* 获取GPIO的输入句柄 */
ret = ioctl(fd, GPIO_GET_LINEHANDLE_IOCTL, &req);
/* 如果获取失败 */
if (ret == -1)
{
ret = -errno;
fprintf(stderr, "Failed to issue GET LINEHANDLE IOCTL (%d)\n",
ret);
}
/* 已经获取到/获取失败句柄,关闭文件描述符 */
if (close(fd) == -1)
{
perror("Failed to close GPIO character device file");
}
/* 定时1s查询GPIO状态并打印 */
while(1)
{
/* 获取GPIO状态 */
ret = ioctl(req.fd, GPIOHANDLE_GET_LINE_VALUES_IOCTL, &data);
/* 如果获取失败 */
if (ret == -1)
{
ret = -errno;
fprintf(stderr, "Failed to issue %s (%d)\n",
"GPIOHANDLE_GET_LINE_VALUES_IOCTL", ret);
}
else
{
/* 打印获取到的GPIO电平 */
printf("value: %d\n", data.values[0]); // 打印读取到的GPIO值(0或1)
}
/* delay 1S */
sleep(1);
}
/* 释放GPIO句柄文件描述符 */
ret = close(req.fd);
if (ret == -1)
{
perror("Failed to close GPIO LINEHANDLE device file");
ret = -errno;
}
return ret;
}
配套的makefile文件如下
PROG = gpioInput
SRCS = gpioInput.c
OBJS = $(SRCS:.c=.o)
CLEANFILES = $(PROG)
# Add / change option in CFLAGS if needed
# CFLAGS += <new option>
$(PROG): $(OBJS)
$(CC) $(CFLAGS) -o $(PROG) $(OBJS)
.c.o:
$(CC) $(CFLAGS) -c $< -o $@
all: $(PROG)
clean:
rm -f $(CLEANFILES) $(patsubst %.c,%.o, $(SRCS)) *~
这个代码实现的功能就是,初始化PB1为输入模式,然后每隔1S打印GPIO的电平状态
如何编译代码和运行,我就不赘述了,和之前的操作一致
使用杜邦线给GPIO一个低电平(连接GND)或一个高电平(连接3.3V),即可在打印中看到GPIO读取的电平状态,代码运行效果如下
WeChat_20240114213318