您尚未登录。

楼主 # 2022-05-20 11:08:30

SwordofMorning
会员
注册时间: 2022-05-20
已发帖子: 6
积分: 11

【F1C100S】如何使用mmap控制GPIO?

我是一个嵌入式小白,前几天看了一位大佬的代码完成了基础的IO。源码是从PE4 PE5 PE6输出,我现在想通过PE2来输出信号,请问要怎么修改呢?可以请您具体讲一下例如&0X00000FFF之类的操作具体是什么含义吗?同时我要怎么完成信号输入呢?

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

#define GPIO_REG_BASE   0x01C20800      //GPIO物理基地址 (小页4kb)
#define MAP_SIZE        0x400 //MMU页大小
#define GPIO_BASE_OFFSET (GPIO_REG_BASE & 0X00000FFF) //GPIO基地址偏移计算
#define GPIO_PAGE_OFFSET (GPIO_REG_BASE & 0XFFFFF000) //获得页偏移

#define rPE_CFG0 0X90  //PE_CFG0寄存器地址偏移
#define rPE_DAT 0XA0    //PE_DAT寄存器地址偏移
#define rPE_PULL0 0XAC  //PE_PULL0寄存器地址偏移

int GPIOE_456_ON(unsigned char *MAP_BASE);//点亮PE4,PE5,PE6 这3盏LED
int  GPIOE_456_OFF(unsigned char *MAP_BASE);//关闭PE4,PE5,PE6 这3盏LED

int main(int argc, char **argv)
{
 static int dev_fd;
 unsigned char *map_base;
/*参数验证*/
    if(argc!=2 || (strcmp(argv[1],"on") && strcmp(argv[1],"off"))){
     printf("argv_error!please input 'on' or 'off'!\n");
       exit (0);
    }

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

map_base = (unsigned char *)mmap(NULL, 0x400,PROT_READ | PROT_WRITE, MAP_SHARED,dev_fd, GPIO_PAGE_OFFSET); //把物理地址映射到虚拟地址
if(*map_base)  printf("mmap_fail!\n"); //是否映射成功

if(!strcmp(argv[1],"on")) GPIOE_456_ON(map_base); //点亮PE4,PE5,PE6 这3盏LED
if(!strcmp(argv[1],"off")) GPIOE_456_OFF(map_base);//关闭PE4,PE5,PE6 这3盏LED
  //usleep(1000000);
    if(dev_fd) close(dev_fd);
    munmap(map_base,MAP_SIZE);//解除映射关系
    return 0;
}


//GPIOE_456_ON
int  GPIOE_456_ON(unsigned char *MAP_BASE)
{
unsigned int PE_CFG0,PE_DAT;
PE_CFG0=*(volatile unsigned int *)(MAP_BASE+GPIO_BASE_OFFSET+rPE_CFG0);
PE_DAT=*(volatile unsigned int *)(MAP_BASE+GPIO_BASE_OFFSET+rPE_DAT);
*(volatile unsigned int *)(MAP_BASE+GPIO_BASE_OFFSET+rPE_CFG0)=((PE_CFG0 & 0XF000FFFF)|0X01110000);
*(volatile unsigned int *)(MAP_BASE+GPIO_BASE_OFFSET+rPE_DAT)=((PE_DAT & 0XFFFFFF8F)|0X00000070);
}
//GPIOE_456_OFF
int  GPIOE_456_OFF(unsigned char *MAP_BASE)
{
unsigned int PE_CFG0,PE_DAT;
PE_CFG0=*(volatile unsigned int *)(MAP_BASE+GPIO_BASE_OFFSET+rPE_CFG0);
PE_DAT=*(volatile unsigned int *)(MAP_BASE+GPIO_BASE_OFFSET+rPE_DAT);
*(volatile unsigned int *)(MAP_BASE+GPIO_BASE_OFFSET+rPE_CFG0)=((PE_CFG0 & 0XF000FFFF)|0X01110000);
*(volatile unsigned int *)(MAP_BASE+GPIO_BASE_OFFSET+rPE_DAT)=((PE_DAT & 0XFFFFFF8F));
}

离线

#1 2022-05-20 16:46:10

dtsayhi
会员
注册时间: 2022-02-11
已发帖子: 23
积分: 8

Re: 【F1C100S】如何使用mmap控制GPIO?

mmap映射GPIO 基地址 。映射地址加偏移地址来配置GPIO寄存器 。先配置模式。然后再配置电平就行

离线

楼主 #2 2022-05-20 17:45:38

SwordofMorning
会员
注册时间: 2022-05-20
已发帖子: 6
积分: 11

Re: 【F1C100S】如何使用mmap控制GPIO?

已解决。

离线

#3 2022-10-17 11:31:39

yuess133
会员
注册时间: 2020-12-10
已发帖子: 18
积分: 13.5

Re: 【F1C100S】如何使用mmap控制GPIO?

SwordofMorning 说:

已解决。

怎么解决的?
映射的起始地址是0x01C20000
GPIO_PAGE_OFFSET (GPIO_REG_BASE & 0XFFFFF000)

gpio的基地址是GPIO_REG_BASE   0x01C20800,
那申请的大小至少要0x800以上,才可以操作到gpio.

上面的只有0x400,应该是控制不到gpio 吧

最近编辑记录 yuess133 (2022-10-17 11:42:10)

离线

页脚

工信部备案:粤ICP备20025096号 Powered by FluxBB

感谢为中文互联网持续输出优质内容的各位老铁们。 QQ: 516333132, 微信(wechat): whycan_cn (哇酷网/挖坑网/填坑网) service@whycan.cn