RK平台操作GPIO的两种方法

RK平台操作GPIO的两种方法

在嵌入式开发调试过程中,操作 GPIO 是一个至关重要的技能。通过操作 GPIO,我们可以控制外部设备,比如开关LED灯、开关模块电源、复位外设等。本文将分享两种在 RK 平台上通过 ADB 或者调试串口就能操作 GPIO 的方法。

直接操作寄存器

这种方式可以直接通过操作 CPU 的寄存器,精准控制每一个 GPIO 引脚的状态,简单直接。缺点就是需要查阅芯片手册,并且要求板子上有 IO 指令,IO 指令的使用方法可以看前面的文章。
下面以拉高 RK3399 的 GPIO2_D3 为例来说明:

  • 查GRF基址
    从 RK3399 的 TRM 手册 Address Mapping 章节获得 GRF 基址为:0xFF770000:
    GRF 基址
  • 查IOMUX偏移址
    IOMUX 管理每个 GPIO 口的功能复用,从 GRF Register Description 章节找到 GRF_GPIO2D_IOMUX 偏移地址为 0x0000E00C:
    IOMUX 偏移址
  • 设置 IOMUX 寄存器
    找到 IOMUX 寄存器的描述:
    IOMUX 寄存器
    可以看到 bit[7:6] 设置为 2’b00 的时候,该 GPIO 为 GPIO 功能,由于 bit[31:16] 为写允许
### 在 RK3568 平台上通过 Qt 实现 GPIO 中断功能 为了在 RK3568 上使用 Qt 实现 GPIO 中断功能,需要结合 Linux 下的 GPIO 驱动程序以及 Qt 应用框架来完成这一目标。以下是具体方法: #### 1. 设置 GPIO 引脚为输入模式并启用中断触发方式 首先,在应用程序启动初期配置好所需的硬件资源。这通常涉及到设置特定编号的 GPIO 引脚作为输入端口,并指定其响应哪种类型的电平变化(上升沿、下降沿或双边沿)。 ```c #include <fcntl.h> #include <unistd.h> #include <sys/ioctl.h> #define GPIO_PATH "/sys/class/gpio" #define EDGE "both" int setup_gpio_interrupt(int pin){ char buffer[64]; int fd; snprintf(buffer, sizeof(buffer), "%d", pin); // Export the GPIO to user space. fd = open(GPIO_PATH"/export", O_WRONLY); write(fd, buffer, strlen(buffer)); close(fd); // Set direction as input. snprintf(buffer, sizeof(buffer), GPIO_PATH"/gpio%d/direction", pin); fd = open(buffer, O_WRONLY); write(fd, "in", 2); close(fd); // Configure edge detection (rising or falling). snprintf(buffer, sizeof(buffer), GPIO_PATH"/gpio%d/edge", pin); fd = open(buffer, O_WRONLY); write(fd, EDGE, strlen(EDGE)); close(fd); return 0; } ``` 这段代码用于初始化给定编号 `pin` 的 GPIO 口,将其设为输入状态并向操作系统注册边沿触发事件[^2]。 #### 2. 创建文件描述符监听 GPIO 值的变化 接着创建一个专门用来监视该引脚状态改变情况的文件句柄。每当发生设定好的边缘条件时,内核会向对应的 `/sys/class/gpio/gpioX/value` 文件写入新的数值通知用户空间进程有更新到来。 ```cpp QString getGpioValuePath(int gpioPin) { QString path("/sys/class/gpio/gpio%1/value"); return path.arg(gpioPin); } QFile* createInterruptWatcher(int gpioPin) { auto filePath = getGpioValuePath(gpioPin).toUtf8().constData(); QFile *file = new QFile(filePath); file->open(QIODevice::ReadOnly | QIODevice::Text); return file; } ``` 此部分展示了如何利用 Qt 提供的类库打开上述路径下的文件对象以便后续读取数据流中的变动信息。 #### 3. 使用 Qt Slot 函数处理来自 GPIO 的信号 当检测到由外部因素引起的 IO 线路上电压波动后,应该及时作出反应。为此可以在 GUI 主窗口或其他组件内部定义槽函数(slot),并通过定时查询的方式轮询当前值的状态或者借助于更高效的异步 I/O 技术如 epoll 来捕获即时发生的变更动作。 ```cpp class MainWindow : public QMainWindow{ public slots: void handleGpioChange() { static QByteArray lastState; QByteArray currentState = m_file->readAll(); if(currentState != lastState){ qDebug()<<"GPIO state changed:"<<currentState.trimmed(); lastState = currentState; // Update UI elements based on GPIO status... } m_file->seek(0); // Reset position pointer back to start of file before next read operation. } private: QTimer *m_timer; QFile *m_file; }; ``` 在此示例中,`handleGpioChange()` 方法被设计成周期性执行的任务,负责比较前后两次获取的数据差异从而判断是否存在有效跳变现象;一旦确认则可以进一步采取措施比如刷新界面显示内容等操作。 ####
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值