ARM寄存器C操作探讨

来源:互联网 发布:nginx负载均衡 并发量 编辑:程序博客网 时间:2024/05/05 01:12

      乍从51过渡到ARM,很多人往往一时不能适应ARM的开发方式,其中一个困扰就是寄存器的访问,尤其是从屈指可数的51族寄存器一下子转到ARM纷繁复杂的寄存器,可能顿时会有种无从下手的感觉。面对这么多的寄存器,我们该怎么对其访问比较方便、科学和规范呢?

      近期到手ARM11架构的S3C6410片子,寄存器可谓繁多,正好拿它开刀,给大家来个现场解牛,下面是S3C6410的GPIO配置的相关寄存器一瞥(冰山一角啊,呵呵):

         

          如图,观察这些寄存器的地址是连续的,这点很重要,与我们将要讨论的第二种操作方式息息相关。通常我们有两种常用的寄存器的操作方式。

      第一种方式:宏定义。

      #define GPACON  (*(volatile U32 *) (0x7F008000))

      #define GPADAT  (*(volatile U32 *) (0x7F008004))

      #define GPAPUD  (*(volatile U32 *) (0x7F008008))

      ......

      解析:

      1、将地址强制类型转换为指向U32数据类型(即寄存器)的指针;

      2、再加“*”,表示引用指向该地址处存放的数据。

      第二种方式:结构体。

      #include <iostream>

        using namespace std;

      int regs_value[]={0,1,2,3,4,5,6,7,8,9};

      struct GPIO_REGS{
      int GPACON;
      int GPADAT;
      int GPAPUD;
      int GPACONSLP;
      int GPAPUDSLP;
      int GPBCON;
      int GPBDAT;
      int GPBPUD;
      int GPBCONSLP;
      int GPBPUDSLP;
      //......
      };

     #define GPIO_BASE (regs_value)
     #define GPIO ((volatile GPIO_REGS *) GPIO_BASE)

     void main()
     {
         cout<<GPIO->GPACON<<endl;
         cout<<GPIO->GPADAT<<endl;
         cout<<GPIO->GPAPUD<<endl;
         //......
      }

      上面的代码是我在VC6.0环境下模拟ARM第二种寄存器操作方式时写的,由于数组中元素的地址是连续的,所以这里采用一个数组的方式来模拟ARM的寄存器。下面为运行的结果,以证实确实正确的访问到了想要访问的目标寄存器。

        

        从图可以看到确实得到了正确的访问,上面的模拟程序很小大家可自行分析体会ARM的这种操作寄存器的方法。

     总结:

       对于这两种方法,第一种比较简洁,但第二种可能会更加方便(尤其是一大片地址连续的寄存器),个人意见比较推荐使用第二种方法。

       以上,希望对刚由单片机开发转向ARM开发的朋友有所帮助。

原创粉丝点击