首页 > 系统相关 >内存映射直接操作GPIO

内存映射直接操作GPIO

时间:2022-12-26 15:58:02浏览次数:41  
标签:映射 PC int pc 内存 gpio GPIO reg define

起因

音乐打铃系统希望通过GPIO来显示一些系统状态,本来是件很简单的事情,orangePi zero2本来已经移植好了wiringpi库,库的编译也很简单,使用操作都没什么可说的,demo代码很快跑通,功能实现.集成系统也比较简单,唯一感觉有一点不好的就是,需要链接的库有点多.运行,出问题了,研究了半天,问题好象出在我代码有用I2C总线操作eeprom的,估计是wiringPi初始化的时候影响到了I2C总线,我就点几个LED,调用这么大个库本来就不高兴,还要链接那么多东西,最后还出问题了,真不爽.

变通

通过mmap直接操作寄存器来控制GPIO应该不是太难的事.linux把所有物理内存都以文件形式导出到用户空间, /dev/mem 就是物理内存空间的映射,打开文件后,能过mmap映射到内存地址,再通过芯片的datasheet找到配置寄存器的地址和数据寄存器的地址,简单配置一下为输出模式,通过数据寄存器就可以操作GPIO了,很简单的代码,对别的模块也没有影响.

#define LED_HTTP 6  
#define LED_PLAY 5  
#define LED_TIMER 8 

#include <fcntl.h>
#include <sys/mman.h>
#include <time.h>
#include <unistd.h>

#define GPIO_BASE   0x0300B000
#define PC_CFG0     2*0x0024+0x00
#define PC_CFG1     2*0x0024+0x04
#define PC_CFG2     2*0x0024+0x08
#define PC_CFG3     2*0x0024+0x0C

#define PC_DAT     2*0x0024+0x10
#define PC_DRV0    2*0x0024+0x14
#define PC_DRV1    2*0x0024+0x18


static volatile unsigned int * pc_cfg0_reg;
static volatile unsigned int * pc_cfg1_reg;
static volatile unsigned int * pc_data_reg;

void gpio_set_mode_out()
{
    //PCN            76543210
    *pc_cfg0_reg = 0x111fffff; 
    //PCN            fedcba98      
    *pc_cfg1_reg = 0xffffff11; 
}

int gpio_init()
{
    static int dev_fd;
    dev_fd = open("/dev/mem", O_RDWR );
    if (dev_fd < 0){
        printf("open(/dev/mem) failed.\n");
        return 0;
    }

    unsigned char *gpio_base;
    gpio_base = (unsigned char *)mmap(NULL, 4096,PROT_READ|PROT_WRITE, MAP_SHARED,dev_fd, GPIO_BASE); 
    if(!gpio_base)  
        printf("gpio_base mmap_fail!\n"); //是否映射成功

    pc_cfg0_reg = (volatile unsigned int * ) (gpio_base + PC_CFG0);
    pc_cfg1_reg = (volatile unsigned int * ) (gpio_base + PC_CFG1);
    //pc_cfg2_reg = (volatile unsigned int * ) (gpio_base + PC_CFG2);
    //pc_cfg3_reg = (volatile unsigned int * ) (gpio_base + PC_CFG3);

    pc_data_reg = (volatile unsigned int * ) (gpio_base + PC_DAT);

    *pc_cfg0_reg = 0xffffffff;
    *pc_cfg1_reg = 0xffffffff;

    *pc_data_reg = 0x0000ffff;

    gpio_set_mode_out();

    //gpio_led_onoff(5,0);
    //gpio_led_onoff(6,0);
    gpio_led_onoff(8,0);

    close(dev_fd);
    return 0;
}
int gpio_led_onoff(int pin,int v)
{
    if(v==1){
        *pc_data_reg |= 0x01<<pin;
    }
    else{
        *pc_data_reg &= ~(0x01<<pin);
    }
}

标签:映射,PC,int,pc,内存,gpio,GPIO,reg,define
From: https://www.cnblogs.com/bitant/p/gpio.html

相关文章