打印
[技术问答]

结构体内部含有位域,程序看不懂,求解答!

[复制链接]
1881|15
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
wanga87|  楼主 | 2015-9-22 15:59 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
ui, IO, ISP, ni, se
typedef struct
{
    union
    {
        __IO uint32_t u32ISPCON;

        struct
        {
            __IO uint32_t  ISPEN:1;
            __IO uint32_t  BS:1;
                __I  uint32_t  RESERVE0:2;
            __IO uint32_t  CFGUEN:1;
                __IO uint32_t  LDUEN:1;
            __IO uint32_t  ISPFF:1;
            __IO uint32_t  SWRST:1;
            __IO uint32_t  PT:3;
                __I  uint32_t  RESERVE1:1;
                __IO uint32_t  ET:3;
            __I  uint32_t  RESERVE2:17;
        } ISPCON;
    };

    union
    {
        __IO uint32_t u32ISPADR;
        __IO uint32_t ISPADR;
    };

    union
    {
        __IO uint32_t u32ISPDAT;
        __IO uint32_t ISPDAT;
    };

    union
    {
        __IO uint32_t u32ISPCMD;

        struct
        {
            __IO uint32_t  FCTRL:4;
            __IO uint32_t  FCEN:1;
            __IO uint32_t  FOEN:1;
            __I  uint32_t  RESERVE:26;
        } ISPCMD;
    };

    union
    {
        __I uint32_t u32ISPTRG;

        struct
        {
            __IO uint32_t  ISPGO:1;
            __I  uint32_t  RESERVE:31;
        } ISPTRG;
    };

    union
    {
        __I uint32_t u32DFBADR;
        __I uint32_t DFBADR;
    };

    union
    {
        __IO uint32_t u32FATCON;

        struct
        {
            __IO uint32_t  FPSEN:1;
            __IO uint32_t  FATS:3;
            __IO uint32_t  LFOM:1;
            __I  uint32_t  RESERVE:27;
        } FATCON;
    };
} FMC_T;
结构体里面包含联合体,但是联合体却没有命名,后面就像下面一样引用了!if (FMC->ISPCON.ISPFF == 1)
    {
        FMC->ISPCON.ISPFF = 1;
        return E_DRVFMC_ERR_ISP_FAIL;
    }   
为什么我照着这种结构来编译器却让我给联合体取个名字?   
沙发
奔跑的牛| | 2015-9-22 17:33 | 只看该作者
可以用新唐BSP FMC样例来调试。


使用特权

评论回复
板凳
gejigeji521| | 2015-9-23 19:02 | 只看该作者
联合里还有结构体,结构体里还有联合,好变态的用法,直接用新唐的BSP的库函数吧。

使用特权

评论回复
地板
huangcunxiake| | 2015-9-23 20:09 | 只看该作者
我是用了库函数后,再也没有管过这些

使用特权

评论回复
5
wahahaheihei| | 2015-9-23 21:02 | 只看该作者
这个是混合使用的,联合和结构体混合了。

使用特权

评论回复
6
734774645| | 2015-9-28 12:58 | 只看该作者
用库函数确实省事的

使用特权

评论回复
7
wanga87|  楼主 | 2015-12-17 16:22 | 只看该作者
gejigeji521 发表于 2015-9-23 19:02
联合里还有结构体,结构体里还有联合,好变态的用法,直接用新唐的BSP的库函数吧。 ...

上面就是新塘的BSP库,我照着来却编译不通!我就感觉很奇怪!
结构体内部的联合体的位域在外面引用的时候竟然可以直接跨过结构体内部的联合体直接找到位域!我看了源程序我就觉得如果结构体内部的两个联合体的位域用一个名字的话不就乱套了么?为什么新塘的BSP库缺能够编译通过!

使用特权

评论回复
8
wanga87|  楼主 | 2015-12-17 16:23 | 只看该作者
734774645 发表于 2015-9-28 12:58
用库函数确实省事的

上面的就是库函数的语句,我是看不懂才来问的!而且我照着来编译器也明确提醒我内部的联合体需要给个名字!

使用特权

评论回复
9
落叶行健ywm| | 2015-12-21 16:42 | 只看该作者
这个编译不通过应该跟编译器有关了,有的编译器不支持这种用法的!

使用特权

评论回复
10
董自祝| | 2015-12-22 09:02 | 只看该作者
我没用过,但是一层层解析应该还是可以理解的

使用特权

评论回复
11
643757107| | 2015-12-22 11:53 | 只看该作者
冒号后面是占位符合,就是占了多少个B。

使用特权

评论回复
12
sjnh| | 2015-12-22 14:37 | 只看该作者
如果没有命名就直接用 FMC->ISPADR,如果有命名就必须加.例如FMC->ISPCON.ISPFF;
“我看了源程序我就觉得如果结构体内部的两个联合体的位域用一个名字的话不就乱套了么?”,用命名就是解决这个的;如果都不重复,就可以不用命名;

使用特权

评论回复
13
734774645| | 2015-12-28 21:51 | 只看该作者
混合使用的,联合和结构体混合了,这就是数据结构。

使用特权

评论回复
14
lai832| | 2015-12-28 22:41 | 只看该作者
变量多了,
要通迅了,
就得慢慢向结构,联合体转,

(以下指非专用接口,只有16个IO,没有ADDR,没有CS,没有COM/DAT等信号)
如设,并口是16BIT,每次传16BIT,
你知道传过来的是什么吗?不知
你可以取一BIT来区分是地址还是DAT(当然可以有其它方法)
这样,就只有15BIT了,
还有,你知道传过来的是读,还是写吗?不知,那是不是得再用1BIT来区分?
这样,就还只有14BIT了.
等等.

另外还有别的:
如有时传的是状态,选择参数,又或可能要传的是32BIT,如何区分哪一次传的是H,哪一次传的是L?等等.

有了结构,+联合就好玩很多了.

typedef struct
{
    uint16_t       Dat     :8;
    uint16_t       Other  :6;
    uint16_t       RW     :1;
    uint16_t       ADDR_DAT:1;
} Format_Type;

有了这个结构体就可以很清楚的表达了,程序也好写了;

但是问题来了,我的GPIO-OUT是16BIT操作的.你总不能每次都将各位进行   或   操作吧.

联合体就起作用了.

typedef union
{
   Format_Type      Format;
   uint16_t             U16;
} Comm_Type;

当然结构体有时没必要用得这么高深,带来方便就好.
有时变量多了,是不是老记错,或是怕输入错..

typedef struct
{
    uint8_t    Temp;
    uint8_t    Time;
    uint8_t    Year;
    uint8_t    Month;
    uint8_t    Date;
} Pra_Type;

只要:
Pra_Type    Tmp;

你只要记着Tmp;就行了.
当你输入Tmp.    输入.后就你可以选择结构里面的变量了...

还有.是不是老要:

Time++;
if (Time > 100)  Time = 0;

是不是很累;
typedef struct
{
    uint8_t  Time   :7;
    uint8_t            :1;
} Time_Type;

Time_Type    Coun_Val;

Coun_Val.Time++;   //计到127,    就这样一条就行了,   但是,你的计数最大次数要是2的N次
是不是很好玩.

使用特权

评论回复
15
734774645| | 2015-12-29 21:36 | 只看该作者
结构体和联合体里面使用这种位段的用法,可以将某几个位赋值给一个变量。

使用特权

评论回复
16
598330983| | 2015-12-29 22:29 | 只看该作者
可以用新唐BSP FMC样例来调试。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

3

主题

28

帖子

0

粉丝