查看: 119|回复: 0

[技术] 【赚周年币】技术贴Week1-Day5——找GPIO寄存器 

[复制链接]

42

主题

1

好友

1869

积分

进士

Rank: 5Rank: 5

  • TA的每日心情
    难过
    昨天 21:34
  • 签到天数: 260 天

    连续签到: 11 天

    [LV.8]以坛为家I

    发表于 2017-1-2 20:17:52 |显示全部楼层
    1.png


    手把手教你找GPIO寄存器 IODIR 定义  
    手把手教你找寄存器定义
    一直就很纳闷,没有一个 向 c8051f410.h的头文件定义特殊功能寄存器,找不见定义,使用起来就无从下手 ,心里总是不舒坦 ;
        从网上看了一些帖子,都说就是在头文件里(我也是这么认为的,肯定要有定义的,不然无法调用)  
    StartUp{        ………..        ……….
    GEL_MapAdd(0x3400u,2,0x0400u,1,1);        /* GPIO 1KW */         ………..          }
    这段映射 0x3400u 为 GPIO空间,其实只是表示这段 i/o空间可读可写;

    下面是我一步一步地追踪,这些都是要用到的宏定义;

    #define PREG16(addr) (*(volatile ioport Uint16*)(addr))

    从一个 ioport Uint16*类型的 地址中取出 地址内容,就是IODIR寄存器的值了

    #define _GPIO_IODIR_ADDR                                    (0x3400u)  //定义了IO地址常量
    #define _GPIO_IODIR                               PREG16(_GPIO_IODIR_ADDR)  //得到寄存器的地址
    #define _IODIR                              _GPIO_IODIR   定义了  _IODIR 常量  
    #define GPIO_ADDR(Reg)                    _GPIO_##Reg##_ADDR 两个变量合并 #define _PREG_SET(PregAddr, Val)         PREG16(PregAddr) = (Uint16)Val #define   GPIO_RSET(Reg,Val)   _PREG_SET(GPIO_ADDR(##Reg),Val)

    从这个宏定义开始
      1:GPIO_RSET(IODIR,1)
       这句很明显了,把IODIR寄存器的值置 1     

    2:_PREG_SET(GPIO_ADDR(##IODIR),1)   利用这两个宏
        #define   GPIO_RSET(Reg,Val)   _PREG_SET(GPIO_ADDR(##Reg),Val)       #define GPIO_ADDR(Reg)                    _GPIO_##Reg##_ADDR         分解的到
             a:GPIO_ADDR(IODIR)                    _GPIO_##Reg##_ADDR              _GPIO_ IODIR _ADDR  
             b:_PREG_SET(_GPIO_ IODIR _ADDR,1)      

    3:接下来
             #define _PREG_SET(PregAddr, Val)         PREG16(PregAddr) = (Uint16)Val      
              PREG16(_GPIO_ IODIR _ADDR)  =1;   

         4::#define PREG16(addr) (*(volatile ioport Uint16*)(addr)) *  
              *(_GPIO_ IODIR _ADDR) = 1;      

    5:  这句就简单了 *(0x3400u) = 1;

    究竟 IODIR 是在哪里定义的呢?
       开始我也很迷惑,仔细想想后,惶然大悟,快乐!!
         问题出在,这些都是宏语句,执行编译前,就已经把 GPIO_RSET(IODIR,1) 翻译成*(0x3400u) = 1;
           编译器不认识IODIR ,而 IODIR在直到
      #define GPIO_ADDR(Reg)                    

    _GPIO_##Reg##_ADDR 两个变量合并   

    前就是个字符串,连个常量都算不上(不知道这么说确切不,完全是因为它在语句的位置,赋予了它意义)
        跟单片机 类比  SFR   IODIR  = 0X3400;



    已有 2 人评分 收起 理由
    EEboard爱板网 + 15 3周发帖养成记 奖励
    loveeeboard + 10

    总评分:  + 25   查看全部评分

    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    关闭

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

    手机版|爱板网 |网站地图  

    GMT+8, 2017-5-24 06:36 , Processed in 0.098755 second(s), 12 queries , Memcache On.

    苏公网安备 32059002001056号

    Powered by Discuz!

    回顶部