这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 嵌入式开发 » FPGA » 对F28335的位域和寄存器结构的学习(1)

共1条 1/1 1 跳转至

对F28335的位域和寄存器结构的学习(1)

工程师
2014-08-18 13:48:10     打赏

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


以前一直在使用C5000系列的DSP,具体型号为VC5509A。不久前也接触了C2000系列的28335。在学习这款DSP的过程中,感觉和C55X差别不少。特别是在编程方面,两者对底层寄存器的操作方式有很大区别。


F28335拥有很丰富的外设资源,这也就说明了它必然有比较复杂的存储单元映射和中断管理体系。关于存储单元映射,TI提供了C/C++ Header files文件来管理,这个和CSL有些类似,但和CSL并不完全相同。首先在CSL使用最多的是宏伪指令,而在F28335中使用最多的是位域和寄存器文件结构体。同CSL相比,有利也有弊。在下面会详细列出两者的优缺点。这是我认为的最有用的一块,它为F28335提供了一个硬件抽象层,使得编程者无需去记忆大量寄存器名称。而且它提供了一个很好的编程规范,是以后编程很好的参考。所以花了一番功夫研究位域和寄存器文件结构体。


现将其中重要的部分描述如下:


1、宏与位域和寄存器结构优缺点的对比


传统的#define宏提供了地址编号或者是指向寄存器地址的指针。


这样做的优点是:1、简单,快,很容易通过键盘敲出。


2、变量名和寄存器名一致,容易记忆。


缺点是:1、具体位不容易获取,必须生成掩码来对某个位操作。


2、不能够在CCSwatch window中方便的显示某些位的值。


3、宏不能够利用CCS的自动完成功能。


4、宏不能对相同外设重复使用。


位域和寄存器结构体的优点如下:


1TI提供,无需自己编写,规范性好。


2、容易读、写、升级,效率高。


3、很好的利用了CCS的自动完成功能。


4、可以在CCS的观察窗口中查看具体位的值。


2、实现位域和寄存器文件结构体的具体步骤(以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


};


在上面的定义中,使用了操作符“:”,用来说明位域的长度,即当前位域占几位。


6)、使用联合体。除了能够方便的访问位域外,有时候也希望能够对寄存器整体访问,使用联合体能够实现这种操作。


/********************************************************************


* SCI header file


********************************************************************/


union SCICCR_REG {


Uint16                                all;


struct      SCICCR_BITS      bit;


};


union SCICTL1_REG {


Uint16                                all;


struct      SCICTL1_BITS     bit;


};


7)、将添加位域后的寄存器结构体重新实现。


/********************************************************************


* 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


};


由于字数超限,文章分成了两部分。


共1条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]