龙芯GPIO控制详解:嵌入式硬件篇


文章目录

  • 前言
  • 1. 头文件引入
  • 作用
  • 2. 导出GPIO引脚 export_gpio
  • 功能
  • 示例
  • 注意
  • 3. 设置GPIO方向 set_gpio_direction
  • 功能
  • 示例
  • 4. 设置GPIO值 set_gpio_value
  • 功能
  • 示例
  • 5. 初始化函数 gpio_init
  • 功能
  • 6.龙芯2K1000适配说明
  • 6.1 GPIO编号映射
  • 6.2 性能优化建议
  • 优点
  • 错误处理
  • 6.3 权限问题
  • 解决方案
  • 6.4内存映射(高级优化)
  • 6.5示例扩展:按键与LED控制
  • 7.总结
  • 适用场景
  • 优势
  • 局限性
  • 改进方向

  • 前言

    本文简单介绍了龙芯2k1000中的GPIO控制。


    1. 头文件引入

    #include <stdio.h>    // 标准输入输出函数(如snprintf)
    #include <stdlib.h>   // 系统调用函数(如system)
    #include <time.h>     // 时间相关函数
    #include <unistd.h>   // POSIX操作系统API(如文件操作)
    #include <fcntl.h>    // 文件控制选项(如open的flags)
    #include <sys/mman.h> // 内存映射相关函数
    #include "GPIO.h"     // 自定义GPIO相关声明(可能包含常量或宏)
    

    作用

    作用:引入必要的库和头文件,支持文件操作、字符串格式化等功能。

    2. 导出GPIO引脚 export_gpio

    void export_gpio(int gpio) {
        char command[100];
        snprintf(command, sizeof(command), "echo %d > /sys/class/gpio/export", gpio);
        system(command);
    }
    

    功能

    功能:通过写入/sys/class/gpio/export文件导出GPIO引脚。

    示例

    示例:echo 1 > /sys/class/gpio/export 导出GPIO1

    注意

    若GPIO已导出,此操作会失败。
    需添加错误检查(如检查文件是否存在)。

    3. 设置GPIO方向 set_gpio_direction

    void set_gpio_direction(int gpio, const char* direction) {
        char command[100];
        snprintf(command, sizeof(command), "echo \"%s\" > /sys/class/gpio/gpio%d/direction", direction, gpio);
        system(command);
    }
    

    功能

    功能:设置GPIO为输入(“in”)或输出(“out”)

    示例

    示例:echo “out” > /sys/class/gpio/gpio1/direction 设置GPIO1为输出。

    4. 设置GPIO值 set_gpio_value

    void set_gpio_value(int gpio, int value) {
        char command[100];
        snprintf(command, sizeof(command), "echo \"%d\" > /sys/class/gpio/gpio%d/value", value, gpio);
        system(command);
    }
    

    功能

    功能:设置输出引脚的电平(0为低,1为高)。

    示例

    示例:echo 1 > /sys/class/gpio/gpio1/value 设置GPIO1为高电平。

    5. 初始化函数 gpio_init

    void gpio_init(int gpio, const char* direction, int value) {
        export_gpio(gpio);
        set_gpio_direction(gpio, direction);
        set_gpio_value(gpio, value);
    }
    

    功能

    功能:整合导出方向设置初始值设置的流程。

    6.龙芯2K1000适配说明

    6.1 GPIO编号映射

    龙芯2K1000的GPIO可能按组(Bank)编号,需查阅手册确认物理引脚与逻辑编号的对应关系

    示例:GPIO1可能对应硬件引脚PZ.1,需参考《龙芯2K1000硬件手册》。

    6.2 性能优化建议

    直接文件操作代替system:
    void export_gpio(int gpio) {
        int fd = open("/sys/class/gpio/export", O_WRONLY);
        if (fd < 0) { /* 错误处理 */ }
        char buf[10];
        snprintf(buf, sizeof(buf), "%d", gpio);
        write(fd, buf, strlen(buf));
        close(fd);
    }
    

    优点

    优点:避免启动Shell进程,提升效率。

    错误处理

    错误处理:检查文件操作返回值,处理GPIO未导出或权限问题。

    6.3 权限问题

    操作/sys/class/gpio需要root权限。

    解决方案

    使用sudo运行程序。
    配置udev规则,允许普通用户访问GPIO设备。

    6.4内存映射(高级优化)

    对于高频操作(如PWM),可通过内存映射直接操作GPIO寄存器:

    volatile uint32_t *gpio_base;
    int fd = open("/dev/mem", O_RDWR);
    gpio_base = mmap(NULL, PAGE_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, GPIO_BASE_ADDR);
    // 直接读写寄存器:gpio_base[REG_OFFSET] |= (1 << PIN);
    需查阅龙芯2K1000的GPIO寄存器基地址和偏移量。
    

    6.5示例扩展:按键与LED控制

    int main() {
        // 初始化GPIO1(LED)为输出,初始关闭
        gpio_init(1, "out", 0);
        // 初始化GPIO2(按键)为输入
        gpio_init(2, "in", 0);
    
        while(1) {
            // 读取按键状态(需实现read_gpio_value)
            int key = read_gpio_value(2);
            // 控制LED
            set_gpio_value(1, key);
            usleep(10000); // 10ms防抖
        }
        return 0;
    }
    

    7.总结

    适用场景

    适用场景:简单GPIO控制(如LED、继电器)。

    优势

    优势:代码简洁,依赖少,易于移植。

    局限性

    局限性:system调用效率低,缺少错误处理。

    改进方向

    改进方向:直接文件操作、内存映射寄存器、完善错误处理。


    作者:Ronin-Lotus

    物联沃分享整理
    物联沃-IOTWORD物联网 » 龙芯GPIO控制详解:嵌入式硬件篇

    发表回复