搜索
bottom↓
回复: 134

MDK:位区(bitband)操作新方法

  [复制链接]

出0入0汤圆

发表于 2010-11-25 15:20:35 | 显示全部楼层 |阅读模式
利用MDK提供的关键字__attribute__((bitband)),可以很方便地进行Cortex-M3所提供的位区(bitband)操作。下面以USART的定义为例:

/* ------------------------ USART寄存器 ---------------------- */
typedef struct                                  // 状态寄存器结构
{
    u16 PE:1;                                   // 校验错误(r)
    u16 FE:1;                                   // 帧错误(r)
    u16 NE:1;                                   // 噪声错误标志(r)
    u16 ORE:1;                                  // 过载错误(r)
    u16 IDLE:1;                                 // 监测到总线空闲(r)
    u16 RXNE:1;                                 // 读数据寄存器非空(rc_w0)
    u16 TC:1;                                   // 发送完成(rc_w0)
    u16 TXE:1;                                  // 发送数据寄存器空(r)
    u16 LBD:1;                                  // LIN断开检测标志(rc_w0)
    u16 CTS:1;                                  // CTS 标志(rc_w0)
}USART_SR __attribute__((bitband));

typedef struct                                  // 控制寄存器1结构
{
    u16 SBK:1;                                  // 发送断开帧(rw 1:将要发送断开字符)
    u16 RWU:1;                                  // 接收唤醒(rw 1:接收器处于静默模式)
    u16 RE:1;                                   // 接收使能(rw)
    u16 TE:1;                                   // 发送使能(rw)
    u16 IDLEIE:1;                               // IDLE中断使能(rw)
    u16 RXNEIE:1;                               // 接收缓冲区非空中断使能(rw)
    u16 TCIE:1;                                 // 发送完成中断使能(rw)
    u16 TXEIE:1;                                // 发送缓冲区空中断使能(rw)
    u16 PEIE:1;                                 // PE中断使能(rw)
    u16 PS:1;                                   // 校验选择(rw 0:偶校验,1:奇校验)
    u16 PCE:1;                                  // 检验控制使能(rw)
    u16 WAKE:1;                                 // 唤醒的方法(rw 0:被空闲总线唤醒,1:被地址标记唤醒)
    u16 M:1;                                    // 字长(rw 0:8位,1:9位)
    u16 UE:1;                                   // USART使能(rw)
}USART_CR1 __attribute__((bitband));

typedef struct                                  // 控制寄存器2结构
{
    u16 ADDR:4;                                 // 本设备的USART节点地址(rw)
    u16 RESERVED1:1;
    u16 LBDL:1;                                 // LIN断开符检测长度(rw 0:10的断开符检测,1:11位)
    u16 LBDIE:1;                                // LIN断开符检测中断使能(rw)
    u16 RESERVED2:1;
    u16 LBCL:1;                                 // 最后一位时钟脉冲(rw )
    u16 MODE:2;                                 // 时钟相位(rw 0:在时钟的第一个边沿进行数据捕获,1:第二个)
                                                // 时钟极性(rw 0:总线空闲时CK引脚上保持低电平;1:高电平)
    u16 CLKEN:1;                                // 时钟使能(rw)
    u16 STOP:2;                                 // 停止位(rw)
    u16 LINEN:1;                                // LIN模式使能(rw)
}USART_CR2 __attribute__((bitband));

typedef struct                                  // 控制寄存器3结构
{
    u16 EIE:1;                                  // 错误中断使能(rw)
    u16 IREN:1;                                 // 红外模式使能(rw)
    u16 IRLP:1;                                 // 红外低功耗(rw)
    u16 HDSEL:1;                                // 半双工选择(rw)
    u16 NACK:1;                                 // 智能卡NACK使能(rw)
    u16 SCEN:1;                                 // 智能卡模式使能(rw)
    u16 DMAR:1;                                 // DMA使能接收(rw)
    u16 DMAT:1;                                 // DMA使能发送(rw)
    u16 RTSE:1;                                 // RTS使能(rw)
    u16 CTSE:1;                                 // CTS使能(rw)
    u16 CTSIE:1;                                // CTS中断使能(rw)   
}USART_CR3 __attribute__((bitband));

typedef struct                                  // 保护时间和预分频寄存器结构
{
    u16 PSC:8;                                  // 预分频器值(rw )
    u16 GT:8;                                   // 保护时间值(rw)
}USART_GTPR __attribute__((bitband));

typedef struct                                  // USART寄存器结构
{
    __IO USART_SR   SR;                         // 状态寄存器
    u16 RESERVED0;
    __IO u16        DR;                         // 数据寄存器
    u16 RESERVED1;
    __IO u16        BRR;                        // 波特比率寄存器
    u16 RESERVED2;
    __IO USART_CR1  CR1;                        // 控制寄存器1
    u16 RESERVED3;
    __IO USART_CR2  CR2;                        // 控制寄存器2
    u16 RESERVED4;
    __IO USART_CR3  CR3;                        // 控制寄存器3
    u16 RESERVED5;
    __IO USART_GTPR GTPR;                       // 保护时间和预分频寄存器
    u16 RESERVED6;
}USART_TypeDef;

#define PERIPH_BASE           0x40000000                            // 外围设备的基地址
#define APB1PERIPH_BASE       PERIPH_BASE                           // APB1设备的基地址
#define APB2PERIPH_BASE       (PERIPH_BASE + 0x10000)               // APB2设备的其地址

#define USART2_BASE           (APB1PERIPH_BASE + 0x4400)            // USART2基地址
#define USART3_BASE           (APB1PERIPH_BASE + 0x4800)            // USART3基地址
#define UART4_BASE            (APB1PERIPH_BASE + 0x4C00)            // UART4 基地址
#define UART5_BASE            (APB1PERIPH_BASE + 0x5000)            // UART5 基地址
#define USART1_BASE           (APB2PERIPH_BASE + 0x3800)            // USART1基地址

#define USART2                ((USART_TypeDef *) USART2_BASE)       // 定义USART2
#define USART3                ((USART_TypeDef *) USART3_BASE)       // 定义USART3
#define UART4                 ((USART_TypeDef *) UART4_BASE)        // 定义UART4
#define UART5                 ((USART_TypeDef *) UART5_BASE)        // 定义UART5
#define USART1                ((USART_TypeDef *) USART1_BASE)       // 定义USART1

    如果想给USART1的CR1寄存器的RXNEIE置位,直接这样操作就行了:
    USART1->CR1.RXNEIE = 1;
    MDK就能正确编译成位区操作地址,根本不需要自己去计算位区地址。

阿莫论坛20周年了!感谢大家的支持与爱护!!

一只鸟敢站在脆弱的枝条上歇脚,它依仗的不是枝条不会断,而是自己有翅膀,会飞。

出0入0汤圆

发表于 2010-11-25 15:53:51 | 显示全部楼层
牛,学习了!

出0入0汤圆

发表于 2010-11-25 15:56:12 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-11-25 16:14:27 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-11-25 16:17:43 | 显示全部楼层
战略马克

出0入0汤圆

发表于 2010-11-25 16:49:23 | 显示全部楼层
固定地址的bitband,本来就不用去计算地址。

不知道全局变量bitband,是不是不用算地址,如果不用,则是MDK的一点进步。

而局部变量,MDK应该不可能做到bitband不算地址。

出0入0汤圆

发表于 2010-11-25 21:27:12 | 显示全部楼层
咔嚓,照个相先。

出0入0汤圆

发表于 2010-11-25 21:48:29 | 显示全部楼层
哈哈,好

出0入0汤圆

发表于 2010-11-25 21:59:49 | 显示全部楼层
结构体,有点迷糊。。

出0入9汤圆

发表于 2010-11-25 22:05:32 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-11-25 22:07:41 | 显示全部楼层
谢谢分享经验

出0入0汤圆

发表于 2010-11-25 22:14:09 | 显示全部楼层
这样也行啊

出0入0汤圆

 楼主| 发表于 2010-11-26 06:26:12 | 显示全部楼层
如果采用这种方式操作位区,片内功能块的定义需要全部重新编写(不能使用库了),就形成了新的库,效率比ST公司提供的库要高很多。
    同时,对RAM区,也同样可以这样操作。

出0入0汤圆

发表于 2010-11-26 07:40:46 | 显示全部楼层
备用

出0入0汤圆

发表于 2010-11-26 07:50:48 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-11-26 07:59:09 | 显示全部楼层
结构体指针+强制类型转换  这个N年前就会用了。

出0入0汤圆

 楼主| 发表于 2010-11-26 08:12:29 | 显示全部楼层
回复【15楼】shell.albert  Shell
结构体指针+强制类型转换  这个n年前就会用了。
-----------------------------------------------------------------------

    你的眼睛看花了吧,我说的重点并非强制类型转换。

出0入0汤圆

发表于 2010-11-26 08:25:42 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-11-26 08:50:55 | 显示全部楼层
bitband貌似很鸡肋。

固定地址不用算算地址,用bitband才有用。

如果对变量bitband还要算地址,用bitband还不如不用。

出0入0汤圆

 楼主| 发表于 2010-11-26 09:14:57 | 显示全部楼层
回复【18楼】stm32w  啥时能玩32位单片机
bitband貌似很鸡肋。
固定地址不用算算地址,用bitband才有用。
如果对变量bitband还要算地址,用bitband还不如不用。
-----------------------------------------------------------------------

    举例如下:
typedef struct
{
    u32 bit0:1;
    u32 bit1:1;
    u32 bit2:1;
    u32 bit3:1;
    u32 bit4:1;
    u32 bit5:1;
    u32 bit6:1;
    u32 bit7:1;
    u32 bit8:1;
    u32 bit9:1;
    u32 bit10:1;
    u32 bit11:1;
    u32 bit12:1;
    u32 bit13:1;
    u32 bit14:1;
    u32 bit15:1;
    u32 bit16:1;
    u32 bit17:1;
    u32 bit18:1;
    u32 bit19:1;
    u32 bit20:1;
    u32 bit21:1;
    u32 bit22:1;
    u32 bit23:1;
    u32 bit24:1;
    u32 bit25:1;
    u32 bit26:1;
    u32 bit27:1;
}DEMO __attribute__((bitband));

DEMO tt;

tt.bit0 = 1;
tt.bit1 = 0;
   前提:变量tt是全局变量(因为编译器在编译时就能给全局变量定位了,编译器可以事先计算好)。

出0入0汤圆

发表于 2010-11-26 09:40:57 | 显示全部楼层
顶一下吴总。

出0入0汤圆

发表于 2010-11-26 09:45:31 | 显示全部楼层
这样很好呀,可以功能为来访问寄存器了,这样非常方便,而且程序上也更明白了。真不明白为什么STM在定义的时候不将所有的功能位来都定义成bitband

出0入0汤圆

发表于 2010-11-26 09:46:31 | 显示全部楼层
另外,有一个小问题,是不是所有外设功能位都可以利用位区来操作呢?

出0入0汤圆

发表于 2010-11-26 09:58:06 | 显示全部楼层
mark

出0入0汤圆

 楼主| 发表于 2010-11-26 10:06:19 | 显示全部楼层
回复【22楼】tiancaigao7  天才杨威利
另外,有一个小问题,是不是所有外设功能位都可以利用位区来操作呢?
-----------------------------------------------------------------------

    应该所有的功能位都支持的。

回复【21楼】tiancaigao7  天才杨威利
这样很好呀,可以功能为来访问寄存器了,这样非常方便,而且程序上也更明白了。真不明白为什么stm在定义的时候不将所有的功能位来都定义成bitband
-----------------------------------------------------------------------

    好像关键字__attribute__((bitband)),MDK 4.0以上才支持。另外,IAR好像不支持。ST的库,是为了在IAR、MDK、GCC中都能用吧。

出0入0汤圆

发表于 2010-11-26 10:27:07 | 显示全部楼层
回复【22楼】tiancaigao7  天才杨威利
-----------------------------------------------------------------------

从参考手册上看所有外设的地址都是在0x4000 0000-0x4010 0000这段内存中,这段内存是可以映射到0x42000000-0x43ffffff这个位段里的。

出0入0汤圆

发表于 2010-11-26 10:28:00 | 显示全部楼层
啊,搜到这个贴,外设都是可以映射到bitband里的

http://www.ourdev.cn/bbs/bbs_content.jsp?bbs_sn=3861107&bbs_page_no=1&bbs_id=3020

出0入0汤圆

 楼主| 发表于 2010-11-26 10:39:56 | 显示全部楼层
回复【20楼】capron  
顶一下吴总。
-----------------------------------------------------------------------

    你认识我?

出0入0汤圆

发表于 2010-11-26 10:52:03 | 显示全部楼层
和位域有多大区别

出0入0汤圆

发表于 2010-11-26 10:59:44 | 显示全部楼层
mark

出0入0汤圆

 楼主| 发表于 2010-12-5 15:35:33 | 显示全部楼层
顶起来!

出0入24汤圆

发表于 2010-12-5 17:55:34 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-2-23 13:24:17 | 显示全部楼层
麻烦请教一个问题,

typedef struct                                  // 保护时间和预分频寄存器结构
{
    u16 PSC:8;                                  // 预分频器值(rw )
    u16 GT:8;                                   // 保护时间值(rw)
}USART_GTPR __attribute__((bitband));
   
" u16 PSC:8;"的8指的是占8个位么?,是的话程序中如何访问呢?还有在那里指定一个位在它所在的字或半字中的位置呢?是按从前到后的顺序么?

出0入0汤圆

 楼主| 发表于 2011-2-23 16:40:26 | 显示全部楼层
回复【32楼】philipsrazor  
麻烦请教一个问题,
typedef struct                                  // 保护时间和预分频寄存器结构
{
    u16 PSC:8;                                  // 预分频器值(rw )
    u16 GT:8;                                   // 保护时间值(rw)
}USART_GTPR __attribute__((bitband));
   
" u16 psc:8;"的8指的是占8个位么?,是的话程序中如何访问呢?还有在那里指定一个位在它所在的字或半字中的位置呢?是按从前到后的顺序么?

-----------------------------------------------------------------------
    如:
    USART_GTPR p;
    p.PSC = 20;
    p.GT = 49;

    u16 i;
    u8 j;
    i = p.PSC;
    j = p.GT;

    *(u16*)&p = 0x1234;

    就这样啊。

出0入0汤圆

发表于 2011-2-23 17:33:33 | 显示全部楼层
要是有个把库按这种重写一下就爽了

出0入0汤圆

 楼主| 发表于 2011-2-23 18:13:02 | 显示全部楼层
我把经常用到的寄存器,全部都这么改造过了,应该是好用的,但不敢100%保证没BUG,所以就不上传了,^_^。

出0入0汤圆

发表于 2011-2-23 20:33:54 | 显示全部楼层
传上来呀,发现错误,大家一起发改正嘛

出0入0汤圆

发表于 2011-2-23 20:35:05 | 显示全部楼层
你告诉我,哪些没有改的,我来改

出0入0汤圆

 楼主| 发表于 2011-2-24 23:21:45 | 显示全部楼层
STM32F10x的寄存器文件(修改过的)。
点击此处下载 ourdev_618284JGMW9Q.rar(文件大小:16K) (原文件名:stm32f10x.rar)

出0入0汤圆

发表于 2011-2-24 23:26:38 | 显示全部楼层
MARK

出0入0汤圆

发表于 2011-2-25 00:37:11 | 显示全部楼层
38L,谢谢

出0入0汤圆

发表于 2011-2-25 01:04:02 | 显示全部楼层
38L,
用这个头文件建了个工程,好多问题.能传个用这个文件做的工作参考一下吗?谢谢

出0入0汤圆

发表于 2011-2-25 08:05:42 | 显示全部楼层
不错,先学下

出0入0汤圆

发表于 2011-2-25 08:46:25 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-2-25 11:28:34 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-2-25 18:37:21 | 显示全部楼层
马克

出0入0汤圆

发表于 2011-2-25 18:50:42 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-2-25 20:25:20 | 显示全部楼层
有什么方法可以在上面的头文件的基础上能够使USART1->CR1=0x0000_0000可以使用?
有的寄存器要全部清零的话,按上面的头文件,只能一个个清位域??

出0入0汤圆

 楼主| 发表于 2011-2-25 20:31:23 | 显示全部楼层
*(__IO u32*)&USART1->CR1 = 0x00000000;

出0入0汤圆

发表于 2011-2-25 21:36:16 | 显示全部楼层
谢谢楼上,编译错误的问题解决了!

出0入0汤圆

发表于 2011-2-28 13:39:59 | 显示全部楼层
这个要学习一下。谢谢分享。

出0入0汤圆

发表于 2011-2-28 13:44:05 | 显示全部楼层
MARK

出0入0汤圆

发表于 2011-2-28 15:48:30 | 显示全部楼层
很牛啊,一直在困扰那个位区怎么利用得到

出0入0汤圆

发表于 2011-3-3 12:35:30 | 显示全部楼层
请问一下,使用这种方法的目的是方便书写代码和阅读 还是 能提高速度

之前我的做法是开一个数组,在程序中计算位置,比起不用位快很多,尤其大量循环,而且我是做LED显示的,必须一位一位的处理。
但是这样的速度还是不太满意,比如将64*1024*4个点分4路(每路64*1024位)同时SPI串行移出需要400US,这样太慢了。

请问有没有快一点的方法,要怎么做呢?

出0入0汤圆

发表于 2011-3-3 12:41:15 | 显示全部楼层
void SendRow_16S_1Col_4Line(uint8 row, uint8 *DispBuffer)
{
       
        uint16 k;
        uint32 StartAddr;  
        uint32 temp1,temp2,temp3,temp4;
        uint8  b;               

        b = 28 - (row % 8) * 4;

        StartAddr = ((uint32)DispBuffer + (row / 8) * (Screen.Len * 8) - 0x20000000) * 32;

         
        temp1 =  StartAddr + 0x2200001c        - (row % 8) * 4;
        temp2 =  temp1 + Screen.Len * 512;
        temp3 =  temp1 + Screen.Len * 1024;
        temp4 =  temp1 + Screen.Len * 1536;                    
                  
        for (k = 0; k < Screen.Len ; k ++)   // 多少列
        {                         
        //        StartAddr  = k * 64 * 8;//32*2*k
                StartAddr  = k * 256;
                SCK = false;       
                D1 = ~*( unsigned int *)( StartAddr + temp1);                           
                D2 = ~*( unsigned int *)( StartAddr + temp2);       
                D3 = ~*( unsigned int *)( StartAddr + temp3);       
                D4 = ~*( unsigned int *)( StartAddr + temp4);                         
                SCK = true;


                StartAddr  += 32;//32*2*k

                SCK = false;       
                D1 = ~*( unsigned int *)( StartAddr + temp1);                           
                D2 = ~*( unsigned int *)( StartAddr + temp2);       
                D3 = ~*( unsigned int *)( StartAddr + temp3);       
                D4 = ~*( unsigned int *)( StartAddr + temp4);                         
                SCK = true;

                StartAddr  += 32;//32*2*k

                SCK = false;       
                D1 = ~*( unsigned int *)( StartAddr + temp1);                           
                D2 = ~*( unsigned int *)( StartAddr + temp2);       
                D3 = ~*( unsigned int *)( StartAddr + temp3);       
                D4 = ~*( unsigned int *)( StartAddr + temp4);                         
                SCK = true;

                StartAddr  += 32;//32*2*k

                SCK = false;       
                D1 = ~*( unsigned int *)( StartAddr + temp1);                           
                D2 = ~*( unsigned int *)( StartAddr + temp2);       
                D3 = ~*( unsigned int *)( StartAddr + temp3);       
                D4 = ~*( unsigned int *)( StartAddr + temp4);                         
                SCK = true;

                StartAddr  += 32;//32*2*k

                SCK = false;       
                D1 = ~*( unsigned int *)( StartAddr + temp1);                           
                D2 = ~*( unsigned int *)( StartAddr + temp2);       
                D3 = ~*( unsigned int *)( StartAddr + temp3);       
                D4 = ~*( unsigned int *)( StartAddr + temp4);                         
                SCK = true;

                StartAddr  += 32;//32*2*k

                SCK = false;       
                D1 = ~*( unsigned int *)( StartAddr + temp1);                           
                D2 = ~*( unsigned int *)( StartAddr + temp2);       
                D3 = ~*( unsigned int *)( StartAddr + temp3);       
                D4 = ~*( unsigned int *)( StartAddr + temp4);                         
                SCK = true;

                StartAddr  += 32;//32*2*k

                SCK = false;       
                D1 = ~*( unsigned int *)( StartAddr + temp1);                           
                D2 = ~*( unsigned int *)( StartAddr + temp2);       
                D3 = ~*( unsigned int *)( StartAddr + temp3);       
                D4 = ~*( unsigned int *)( StartAddr + temp4);                         
                SCK = true;

                StartAddr  += 32;//32*2*k

                SCK = false;       
                D1 = ~*( unsigned int *)( StartAddr + temp1);                           
                D2 = ~*( unsigned int *)( StartAddr + temp2);       
                D3 = ~*( unsigned int *)( StartAddr + temp3);       
                D4 = ~*( unsigned int *)( StartAddr + temp4);                         
                SCK = true;                       
        }         
        STB = false;                  //stb
        STB = true;                           
}       


毫无疑问,我用的是最笨的方法。尽量减少循环

出0入0汤圆

发表于 2011-3-3 13:26:52 | 显示全部楼层
还没用上,感觉不错。尤其谢谢吴助建

出0入0汤圆

 楼主| 发表于 2011-3-3 14:29:38 | 显示全部楼层
回复【53楼】wuyiduan  
请问一下,使用这种方法的目的是方便书写代码和阅读 还是 能提高速度
之前我的做法是开一个数组,在程序中计算位置,比起不用位快很多,尤其大量循环,而且我是做led显示的,必须一位一位的处理。
但是这样的速度还是不太满意,比如将64*1024*4个点分4路(每路64*1024位)同时spi串行移出需要400us,这样太慢了。
请问有没有快一点的方法,要怎么做呢?
-----------------------------------------------------------------------
    这种方法,既方便书写代码,方便阅读,又能提高速度。
    至于是否提高了速度,你可以通过MDK生成的汇编代码进行对比。

出0入0汤圆

发表于 2011-3-10 10:08:57 | 显示全部楼层
*(__IO u32*)&USART1->CR1 = 0x00000000;这是一种变通的用法,能不能不改变原来的使用习惯,二种用法都通吃?

出0入0汤圆

发表于 2011-3-10 15:38:39 | 显示全部楼层
用得到 标记一下

出0入0汤圆

发表于 2011-3-10 15:46:32 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-3-11 10:06:23 | 显示全部楼层
typedef struct                // ADC状态寄存器        +0x0000
{
        u32        AWD:1;                                                                                                        // 模拟看门狗标志位
        u32 EOC:1;                                                                                                        // 转换结束位
        u32 JEOC:1;                                                        // 注入通道转换结束位
        u32 JSTRT:1;                                                // 注入通道开始位
        u32 STRT:1;                                                        // 规则通道开始位
}ADC_SR __attribute__((bitband));

#define ADC1_SR                ((ADC_SR *) ADC1_BASE)
#define ADC2_SR                ((ADC_SR *) ADC2_BASE)
#define ADC3_SR                ((ADC_SR *) ADC3_BASE)
引用的时候:ADC1_SR->STRT=0;原来对寄存器操作的习惯也不会改变,感觉还比较方便。

出0入0汤圆

发表于 2011-3-11 11:27:24 | 显示全部楼层
好办法

出0入0汤圆

发表于 2011-3-26 21:56:49 | 显示全部楼层
学习一下……

出0入0汤圆

发表于 2011-4-5 17:10:32 | 显示全部楼层
你那能整体赋值吗?

出0入0汤圆

发表于 2011-4-5 17:55:39 | 显示全部楼层
好东西

出0入0汤圆

发表于 2011-4-5 20:46:45 | 显示全部楼层
好东西 我也来学来试试

出0入0汤圆

发表于 2011-4-5 20:49:21 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-5-5 19:47:40 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-5-5 20:49:33 | 显示全部楼层
mark!~

出0入0汤圆

发表于 2011-5-5 20:50:10 | 显示全部楼层
位回复【28楼】mcu5i51 学途浪子
和位域有多大区别
-----------------------------------------------------------------------

同问!

出0入0汤圆

发表于 2011-5-6 01:32:10 | 显示全部楼层
并不是所有的寄存器位都可以用bitband的....比如gpio的某些控制位....请仔细看手册.....

出0入0汤圆

发表于 2011-5-6 08:50:09 | 显示全部楼层
好帖~顶~~

出0入0汤圆

发表于 2011-5-6 11:08:58 | 显示全部楼层
位域操作,程序上美观直接,可是生成的汇编就有点惨不忍睹了……

出0入0汤圆

发表于 2011-8-4 16:37:06 | 显示全部楼层
个人不太喜欢一位一位操作寄存器,感觉太繁琐了,而且要了解寄存器中的每一位的功能,用ST提供的库配置外设操作感觉很爽,现在不用ST的库还不顺手了!!
不过LZ的方法还是很值得借鉴的,这技巧很牛逼

出0入0汤圆

发表于 2011-8-4 18:18:53 | 显示全部楼层
学习le

出0入0汤圆

发表于 2011-8-4 19:55:41 | 显示全部楼层
ding!

出0入0汤圆

发表于 2011-8-4 20:01:51 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-8-4 20:31:27 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-8-4 20:34:05 | 显示全部楼层
MARK

出0入0汤圆

发表于 2011-8-6 15:38:39 | 显示全部楼层
mark!

出0入0汤圆

发表于 2011-8-9 12:22:04 | 显示全部楼层
mark!

出0入0汤圆

发表于 2011-8-10 10:20:03 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-8-10 12:02:17 | 显示全部楼层
初学STM32,我看手册上有一种“位带”操作,如果访问0x40000000 地址上的0,1,2,3位上的值,只需访问0X42000000 0X42000004
0X42000008 0X4200000C上的值

出0入0汤圆

发表于 2011-8-10 12:09:04 | 显示全部楼层
MARK

出0入9汤圆

发表于 2011-8-16 11:33:21 | 显示全部楼层
不错。这个要顶。

出0入0汤圆

发表于 2011-8-16 12:48:23 | 显示全部楼层
这个在官方编译器参考手册中 (RealView Compiler Reference Guide) 是有说明的
http://www.keil.com/support/man/docs/armccref/armccref_babcbgfc.htm

出0入0汤圆

发表于 2011-8-16 13:11:37 | 显示全部楼层
mark

出0入476汤圆

发表于 2011-8-16 13:27:20 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-12-22 11:36:17 | 显示全部楼层
学习一下

出0入0汤圆

发表于 2011-12-22 11:58:35 | 显示全部楼层
学习!!!

出0入0汤圆

发表于 2011-12-22 12:04:49 | 显示全部楼层
MARK

出0入0汤圆

发表于 2011-12-23 08:56:39 | 显示全部楼层
回复【楼主位】wuzhujian 吴助建
-----------------------------------------------------------------------

非常感谢!

出0入0汤圆

发表于 2012-6-25 16:04:36 | 显示全部楼层
连抽了两根烟,发现自己是一坨屎

出0入0汤圆

发表于 2012-6-30 16:50:35 | 显示全部楼层
这正好解决sbit的问题

出0入0汤圆

发表于 2012-7-2 10:16:10 | 显示全部楼层
为什么在对RCC寄存器操作时,有问题呢??不能正确的配置啊。外设时钟不工作。

出0入0汤圆

发表于 2012-7-15 22:46:08 | 显示全部楼层
Mark备用

出0入0汤圆

发表于 2012-11-23 23:12:43 | 显示全部楼层
本帖最后由 xizi 于 2012-11-23 23:14 编辑

缺点是不能整体赋值。比如
typedef union
{
    u8 byte;
    struct
    {
        u8 bit0:1;
        u8 bit1:1;
    } bits;

} mytype __attribute__((bitband));

mytype var;

var.byte = 0xff;

上述定义不支持,报告错误。
只支持位结构。

出0入0汤圆

发表于 2012-11-24 04:25:07 | 显示全部楼层
wuzhujian 发表于 2010-11-26 06:26
如果采用这种方式操作位区,片内功能块的定义需要全部重新编写(不能使用库了),就形成了新的库,效率比ST ...

汇编效率其实差的真不多....很多寄存器项目也不止一位,反而处理起来麻烦

出0入0汤圆

发表于 2012-11-24 10:17:17 | 显示全部楼层
这个必须顶一个,进来学习学习

出0入0汤圆

发表于 2012-12-13 10:47:16 | 显示全部楼层
不错。。。。
刘明马克。
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-3-29 22:09

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表