首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

F28335的位域和寄存器结构的学习

F28335的位域和寄存器结构的学习

实现位域和寄存器文件结构体的具体步骤(以SCI外设为例)
         1)、定义一个寄存器文件结构体,SCI外设的寄存器在结构体中按实际的地址由低向高依次列出。
  • /********************************************************************
  • * SCI header file
  • * Defines a register file structure for the SCI peripheral
  • ********************************************************************/
  • #define    Uint16    unsigned int
  • #define    Uint32    unsigned long
  • struct SCI_REGS {
  • Uint16    SCICCR_REG      SCICCR;             // Communications control register
  • Uint16    SCICTL1_REG     SCICTL1;             // Control register 1
  • Uint16                                SCIHBAUD;         // Baud rate (high) register
  • Uint16                                SCILBAUD;         // Baud rate (low) register
  • Uint16    SCICTL2_REG     SCICTL2;             // Control register 2
  • Uint16  SCIRXST_REG    SCIRXST;            // Receive status register
  • Uint16                               SCIRXEMU;               // Receive emulation buffer register
  • Uint16  SCIRXBUF_REG SCIRXBUF;         // Receive data buffer
  • Uint16                               rsvd1;                   // reserved
  • Uint16                               SCITXBUF;          // Transmit data buffer
  • Uint16  SCIFFTX_REG     SCIFFTX;            // FIFO transmit register
  • Uint16  SCIFFRX_REG    SCIFFRX;            // FIFO receive register
  • Uint16  SCIFFCT_REG     SCIFFCT;             // FIFO control register
  • Uint16                               rsvd2;                   // reserved
  • Uint16                               rsvd3;                   // reserved
  • Uint16  SCIPRI_REG        SCIPRI;                      // FIFO Priority control
  • };

复制代码
        2)、上面的定义本身并没有建立任何的变量,只是定义了一个结构体,而并没有实例化。下面即定义了具体的变量。注意在这里使用了volatile关键字,它在这里的作用很重要,这使得编译器不会做一些错误的优化。

  • /********************************************************************
  • * Source file using register-file structures
  • * Create a variable for each of the SCI register files
  • ********************************************************************/
  • volatile    struct      SCI_REGS    SciaRegs;
  • volatile    struct      SCI_REGS    ScibRegs;

复制代码

         3)、利用DATA_SECTION Pragma,将寄存器文件结构体变量分配到特殊的数据段中。如果不使用这条指令,那么定义的寄存器文件结构体变量默认是被分配在.ebss或者.bss段的,但通过使用DATA_SECTION Pragma指令,编译器会将其放在了一个特殊的数据段中。具体实现如下:

  • /********************************************************************
  • * Assign variables to data sections using the #pragma compiler statement
  • * C and C++ use different forms of the #pragma statement
  • * When compiling a C++ program, the compiler will define __cplusplus automatically
  • ********************************************************************/
  • //----------------------------------------
  • #ifdef      __cplusplus
  • #pragma  DATA_SECTION("SciaRegsFile")
  • #else
  • #pragma  DATA_SECTION(SciaRegs,"SciaRegsFile");
  • #endif
  • volatile    struct      SCI_REGS    SciaRegs;
  • //----------------------------------------
  • #ifdef     __cplusplus
  • #pragma DATA_SECTION("ScibRegsFile")
  • #else
  • #pragma DATA_SECTION(ScibRegs,"ScibRegsFile");
  • #endif
  • volatile    struct      SCI_REGS    ScibRegs;

复制代码
        通过上面的代码可以看到,定义的SciaRegs被分配到了SciaRegsFile段中,ScibRegs被分配到了ScibRegsFile段中。
         4)、上面只是将定义的寄存器结构体变量分配到了一个特殊的数据段中,通过cmd文件,可将其映射到实际的存储单元,进而和外设实际的存储器映射地址统一起来。实现如下:

  • /********************************************************************
  • * Memory linker .cmd file
  • * Assign the SCI register-file structures to the corresponding memory
  • ********************************************************************/
  • MEMORY
  • {
  • ...
  • PAGE 1:
  • SCIA : origin = 0x007050, length = 0x000010 /* SCI-A registers */
  • SCIB : origin = 0x007750, length = 0x000010 /* SCI-B registers */
  • ...
  • }
  • SECTIONS
  • {
  • ...
  • SciaRegsFile : > SCIA, PAGE = 1
  • ScibRegsFile : > SCIB, PAGE = 1
  • ...
  • }

复制代码

         5)、添加位域定义。
         获取寄存器中特定的位经常是很有用的,位域的定义就提供了这种方便性;但是与此同时位域也缺乏硬件平台之间的可移植性。在位域的定义中,最低位,也就是0位,是寄存器中的第一个位域;位域不能超过寄存器的位数,最多为16位。

  • /********************************************************************
  • * SCI header file
  • ********************************************************************/
  • //----------------------------------------------------------
  • // SCICCR communication control register bit definitions:
  • //
  • struct      SCICCR_BITS {                 // bit deion
  • Uint16    SCICHAR:3;                       // 2:0 Character length control
  • Uint16    ADDRIDLE_MODE:1;        // 3 ADDR/IDLE Mode control
  • Uint16    LOOPBKENA:1;                 // 4 Loop Back enable
  • Uint16    PARITYENA:1;                  // 5 Parity enable
  • Uint16    PARITY:1;                         // 6 Even or Odd Parity
  • Uint16    STOPBITS:1;                      // 7 Number of Stop Bits
  • Uint16    rsvd1:8;                              // 15:8 reserved
  • };
  • //-------------------------------------------
  • // SCICTL1 control register 1 bit definitions:
  • //
  • struct SCICTL1_BITS {                            // bit deion
  • Uint16    RXENA:1;                          // 0 SCI receiver enable
  • Uint16    TXENA:1;                          // 1 SCI transmitter enable
  • Uint16    SLEEP:1;                           // 2 SCI sleep
  • Uint16    TXWAKE:1;                       // 3 Transmitter wakeup method
  • Uint16    rsvd:1;                                // 4 reserved
  • Uint16    SWRESET:1;                      // 5 Software reset
  • Uint16    RXERRINTENA:1;             // 6 Receive interrupt enable
  • Uint16    rsvd1:9;                              // 15:7 reserved
  • };

复制代码
        在上面的定义中,使用了操作符“:”,用来说明位域的长度,即当前位域占几位。
继承事业,薪火相传
返回列表