结构体与共同体(联合体)的妙用

结构体与共同体(联合体)的妙用

 

 

学习过C语言后,大家都了解了结构体与共同体。两者之间的区别是:

共同体:使几个不同类型的变量共占一段内存(相互覆盖)。所占内存长度是各最长的成员占的内存长度。

结构体:把不同类型的数据组合成一个整体。所占内存长度是各成员占的内存长度的总和。

在C2000官方样例中,对寄存器的定义就大量使用了这两种数据结构来完成对寄存器总体或者对寄存器每一位的操作。下面,我们通过EPWM寄存器结构体设计的例子来看一下它们的使用方法。

首先,我们声明一个结构体:

结构体与共同体(联合体)的妙用_第1张图片

TBCTL_BITS的结构体声明了TBCTL里的每一个位的分配情况。对应一下技术参考手册对TBCTL的描述:

结构体与共同体(联合体)的妙用_第2张图片

可以看到结构体是按低位开始向高位排列,而后面跟的数字就是每一个寄存器域占的位长,例如第一个CTRMODE对应了TBCTL Register的最低两位。

然后再声明一个共同体:

结构体与共同体(联合体)的妙用_第3张图片

里面有两个参数,一个是all,一个是上面声明的结构体。根据union共同体的说明,我们就知道整型变量all和结构体bit占用了同一个数据空间,对all的操作会影响bit,同样对bit的操作会影响all。这也意味着,all这个16位整型变量的每一位,就对应了bit这个结构体的相应的一个成员变量。例如,对all的最低两位的操作,就对应了bit中的CTRMODE这个位长为2的成员变量。

然后我们知道,TBCTL_REG是属于EPWM寄存器,正如技术参考手册上的描述:

所以我们又可以声明一个EPWM寄存器的结构体:

这样,再将EPWM_REGS 声明的寄存器例如Epwm1Regs分配到EPWM1寄存器的地址,就完成了一个名为Epwm1Regs寄存器的声明。如何来操作呢?

例如,我想把计数模式改成1,就有两种方法来实现:

首先

整体赋值:Epwm1Regs.TBCTL.all |= 0x01;位赋值:Epwm1Regs.TBCTL.bit.CTRMODE = 0x01;

第一个是全局赋值,因此要和all不赋值的位进行或0,赋值位进行或1,即改变了all的最低两位为1,而第二个是位赋值,即直接对计数模式位进行1的赋值。

理解了这个方法后,再来看样例对寄存器的操作是不是就很轻松了?掌握这个方法以后,你也可以设计一个带全局或者位操作的结构体来完成自己的程序数据的应用了。

你可能感兴趣的:(C语言)