查看: 1166|回复: 0

Riotboard GPIO库

[复制链接]
  • TA的每日心情
    郁闷
    2016-8-18 12:54
  • 签到天数: 4 天

    连续签到: 1 天

    [LV.2]偶尔看看I

    发表于 2015-9-11 14:57:31 | 显示全部楼层 |阅读模式
    分享到:
    拿到板子后,想自己做点东西时却发现官方并没有给提供GPIO库,不像树莓派那样有各种软件库的支持。看来只能自己动手了。以下是详细步骤:
    1、下载i.MX6处理器的参考手册

    51MB的体积加5789页的芯片手册,醉了。。。
    2、看手册



    首先通过板子的原理图可知这个板子有11个剩余的GPIO可供DIY,分别是:GPIO4_16、GPIO4_17、GPIO4_18、GPIO4_19、GPIO4_26、GPIO4_27、GPIO4_31、GPIO5_05、GPIO5_06、GPIO5_07、GPIO5_08。
    在使用i.MX6的GPIO前首先要配置IOMUXC寄存器,将需要的管脚配置成GPIO之后才可以把它当GPIO用。

    通过查询手册可知GPIO4_IO16这个脚的IOMUXC寄存器地址为0x20E009C。通过配置IOMUXC寄存器的前4位为0101(0x5)来将这个管脚配置为GPIO。
    以此类推,得到了这些寄存器:
    #define IOMUXC_GPIO4_16 0x20E009C#define IOMUXC_GPIO4_17 0x20E00A0#define IOMUXC_GPIO4_18 0x20E00A4#define IOMUXC_GPIO4_19 0x20E00A8#define IOMUXC_GPIO4_26 0x20E00FC#define IOMUXC_GPIO4_27 0x20E0100#define IOMUXC_GPIO4_31 0x20E00B8#define IOMUXC_GPIO5_05 0x20E00BC#define IOMUXC_GPIO5_06 0x20E00C0#define IOMUXC_GPIO5_07 0x20E00C4#define IOMUXC_GPIO5_08 0x20E00C8接着看手册:GPIO_GDIR functions as direction control when the IOMUXC is in GPIO mode. Each
    bit specifies the direction of a one-bit signal. The mapping of each DIR bit to a
    corresponding SoC signal is determined by the SoC's pin assignment and the IOMUX
    table. For more details consult the IOMUXC chapter.
    由此可知将IOMUXC寄存器配置成GPIO模式后,通过GPIO_GDIR寄存器就可以控制GPIO的输入输出方向了。

    经过简单的搜索就找到了这个寄存器地址,还有GPIO4_DR数据寄存器。
    #define GPIO4_DR          0x20A8000#define GPIO4_GDIR        0x20A8004#define GPIO5_DR          0x20AC000#define GPIO5_GDIR        0x20AC004这样,就集齐了简单控制GPIO输入输出的寄存器,可以来挑战BOSS了。
    3、关于mmap系统调用
        大家都知道用户态的程序都是在内存保护模式下使用内存,无法直接访问物理内存。同时用户程序使用的地址,也并不是物理地址,而是逻辑地址。至于这些逻辑地址对应的物理内存在哪里,用户进程本身并不知道。通过用户程序若想访问物理内存,有一种简单的方法,就是通过mmap系统调用将物理地址映射到用户空间,这样就可以像玩单片机一样操作GPIO了,不多说了,上代码:[gpio.c]
    #include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <sys/types.h>#include <fcntl.h>#include <sys/mman.h>#include "gpio.h"#define MAP_SIZE 4096UL#define MAP_MASK (MAP_SIZE - 1)unsigned long reg_read(off_t addr){        int memfd;        void *map_base, *virt_addr;        unsigned long val;        if((memfd = open("/dev/mem", O_RDWR | O_SYNC)) == -1)                exit(1);        map_base = mmap(0,MAP_SIZE,PROT_READ | PROT_WRITE,MAP_SHARED,memfd,addr & ~MAP_MASK);        if(map_base == (void *) -1)            exit(1);        virt_addr = map_base + (addr & MAP_MASK);        val=*((unsigned long *) virt_addr);        if(munmap(map_base, MAP_SIZE) == -1)                exit(1);        close(memfd);        return val;}void reg_write(unsigned long addr,unsigned long dat){        int memfd;        void *map_base, *virt_addr;        if((memfd = open("/dev/mem", O_RDWR | O_SYNC)) == -1)                exit(1);        map_base = mmap(0,MAP_SIZE,PROT_READ | PROT_WRITE,MAP_SHARED,memfd,addr & ~MAP_MASK);        if(map_base == (void *) -1)                exit(1);        virt_addr = map_base + (addr & MAP_MASK);        *((unsigned long *) virt_addr) = dat;        close(memfd);}void gpio_init(){        /* Configure IOMUX to select GPIO mode */        reg_write(IOMUXC_GPIO4_16,IOMUXC_GPIO);    reg_write(IOMUXC_GPIO4_17,IOMUXC_GPIO);    reg_write(IOMUXC_GPIO4_18,IOMUXC_GPIO);    reg_write(IOMUXC_GPIO4_19,IOMUXC_GPIO);        reg_write(IOMUXC_GPIO4_26,IOMUXC_GPIO);        reg_write(IOMUXC_GPIO4_27,IOMUXC_GPIO);        reg_write(IOMUXC_GPIO4_31,IOMUXC_GPIO);        reg_write(IOMUXC_GPIO5_05,IOMUXC_GPIO);        reg_write(IOMUXC_GPIO5_06,IOMUXC_GPIO);        reg_write(IOMUXC_GPIO5_07,IOMUXC_GPIO);        reg_write(IOMUXC_GPIO5_08,IOMUXC_GPIO);}void gpio_dir(int gpio,int dir){        unsigned long gdir;        unsigned char port;                gpio-=96;        if(gpio>31){                gpio-=32;                port=5;                gdir=reg_read(GPIO5_GDIR);        }else{                port=4;                gdir=reg_read(GPIO4_GDIR);        }                if(dir){                if(port==4)                        reg_write(GPIO4_GDIR,gdir|(1<<gpio));                else                        reg_write(GPIO5_GDIR,gdir|(1<<gpio));        }else{                if(port==4)                        reg_write(GPIO4_GDIR,gdir&(~(1<<gpio)));                else                        reg_write(GPIO5_GDIR,gdir&(~(1<<gpio)));        }}void gpio_set(int gpio,int value){        unsigned long dr;        unsigned char port;                gpio-=96;        if(gpio>31){                gpio-=32;                port=5;                dr=reg_read(GPIO5_DR);        }else{                port=4;                dr=reg_read(GPIO4_DR);        }                if(value){                if(port==4)                        reg_write(GPIO4_DR,dr|(1<<gpio));                else                        reg_write(GPIO5_DR,dr|(1<<gpio));        }else{                if(port==4)                        reg_write(GPIO4_DR,dr&(~(1<<gpio)));                else                        reg_write(GPIO5_DR,dr&(~(1<<gpio)));        }}                int gpio_get(int gpio){        unsigned long dr;                gpio-=96;        if(gpio>31){                gpio-=32;                dr=reg_read(GPIO5_DR);        }else{                dr=reg_read(GPIO4_DR);        }        if(dr&(1<<gpio))                return 1;        else                return 0;}头文件:[gpio.h]#ifndef __GPIO_H__#define __GPIO_H__#define GPIO4_DR      0x20A8000#define GPIO4_GDIR    0x20A8004#define GPIO5_DR      0x20AC000#define GPIO5_GDIR    0x20AC004#define IOMUXC          0x20E0000#define IOMUXC_GPIO4_16 0x20E009C#define IOMUXC_GPIO4_17 0x20E00A0#define IOMUXC_GPIO4_18 0x20E00A4#define IOMUXC_GPIO4_19 0x20E00A8#define IOMUXC_GPIO4_26 0x20E00FC#define IOMUXC_GPIO4_27 0x20E0100#define IOMUXC_GPIO4_31 0x20E00B8#define IOMUXC_GPIO5_05 0x20E00BC#define IOMUXC_GPIO5_06 0x20E00C0#define IOMUXC_GPIO5_07 0x20E00C4#define IOMUXC_GPIO5_08 0x20E00C8#define IOMUXC_GPIO     0x5#define GPIO4_16 112#define GPIO4_17 113#define GPIO4_18 114#define GPIO4_19 115#define GPIO4_26 122#define GPIO4_27 123#define GPIO4_31 127#define GPIO5_05 133#define GPIO5_06 134#define GPIO5_07 135#define GPIO5_08 136void gpio_init();void gpio_dir(int gpio,int dir);void gpio_set(int gpio,int value);int gpio_get(int gpio);#endif4、测试例程
    gpio_init();           //初始化GPIOgpio_dir(GPIO4_16,1);  //配置GPIO为输出gpio_set(GPIO4_16,1);   //配置GPIO输出高电平gpio_dir(GPIO4_17,0);   //配置GPIO为输入gpio_get(GPIO4_17);     //读取GPIO电平5、总结
    貌似也没啥好总结的了,就这样吧,祝大家玩的开心。
    回复

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /5 下一条

    手机版|小黑屋|与非网

    GMT+8, 2024-12-19 15:16 , Processed in 0.125632 second(s), 17 queries , MemCache On.

    ICP经营许可证 苏B2-20140176  苏ICP备14012660号-2   苏州灵动帧格网络科技有限公司 版权所有.

    苏公网安备 32059002001037号

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.