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

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

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

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)在需要清除PIEIFRx某个位的值的时候,需要借助CPU的中断来清除。这时将修改中断向量表,将对应的中断重新分配到一个假的ISR中,然后让CPU进入这个假的ISR,自动清除相应的位,然后再恢复中断向量表。
         (2)当对GPxDAT进行操作时,由于GPxDAT反映的是引脚上的值,在对其连续“读-修改-写”操作时,由于读和写操作的时间不同,会得到不希望的结果。解决措施是:不通过GPxDAT改变引脚的值,而使用其他寄存器GPxSET/GPxCLEAR/GPxTOGGLE,由于这些寄存器只对具体的位操作,因而不会影响到其他的位。
         2、具有写1清除位的寄存器。
         例如TCR寄存器中的TIF位,当向其中写1的时候回将其清零。在读取它的值之前如果先要停止寄存器,就要对TSS位操作,这时就会发生一次“读-修改-写”操作。如果此时TIF为1,经过这个操作后就会被清零,所以后面的质量永远也检测到TIF为1。比如下面的例子:

  • // Stop the CPU-Timer
  • CpuTimer0Regs.TCR.bit.TSS = 1;              3F80C7 MOVW DP,#0x0030
  • 3F80C9 OR         @4,#0x0010
  • // Check to see if TIF is set                        3F80CB TBIT      @4,#15
  • if (CpuTimer0Regs.TCR.bit.TIF == 1)        3F80CC SBF       L1,NTC
  • {                                                             3F80CD        NOP
  • // TIF set, insert action here                       3F80CE L1:
  • // NOP is only a place holder ....
  • asm(" NOP");
  • }

复制代码
        解决的方法是使用一个虚拟的寄存器,在停止定时器时,对TIF位写0,这样就不会改变TIF的值了。示例代码如下:
  • union TCR_REG shadowTCR;
  • // Use a shadow register to stop the timer
  • // and preserve TIF (write 1-to-clear bit)
  • shadowTCR.all = CpuTimer0Regs.TCR.all;               3F80C7 MOVW DP,#0x0030
  • shadowTCR.bit.TSS = 1;                                         3F80C9 MOV     AL,@4
  • shadowTCR.bit.TIF = 0;                                          3F80CA        ORB      AL,#0x10
  • CpuTimer0Regs.TCR.all = shadowTCR.all;               3F80CB MOVL   XAR5,#0x000C00
  • 3F80CD        AND      AL,@AL,#0x7FFF
  • // Check the TIF flag                                               3F80CF MOV     *+XAR5[4],AL
  • if(CpuTimer0Regs.TCR.bit.TIF == 1)                       3F80D0 TBIT      *+XAR5[4],#15
  • {                                                                           3F80D1 SBF       L1,NTC
  • // TIF set, insert action here                                     3F80D2 NOP
  • // NOP is only a place holder                                   3F80D3 L1:
  • asm(" NOP");
  • }

复制代码

         3、需要特定值的寄存器。
         在向WDCHK中的检查位写数的时候必须始终为1,0,1;否则就会被认为是不合法的,将复位器件。但是在读取的时候这几位始终为0,0,0;如果将这个值写回,那么就会造成器件的复位。解决方法是:在头文件中,不对WDCHK定义位域操作,这样就避免了对WDCHK的“读-修改-写”操作,在对其操作时只有一个固定的写操作。示例代码如下:
  • SysCtrlRegs.WDCR = 0x0068;

复制代码
        对F28335的程序来讲,它充分利用了位域和寄存器文件结构体,通过这种结构将众多的外设组织起来了,甚至中断向量表也是通过这种结构来实现的。
继承事业,薪火相传
返回列表