受到“位带别名区“启发,STM32F103.H头文件计划。

whili   2008-9-10 11:55 楼主
受到“位带别名区“启发,STM32F103.H头文件计划。

现在已经使用STM32F103.H头文,基本代替了STM32库,
直接使用寄存器和位结构。

现在受到“位带别名区“启发,把STM32 外设寄存器全部加上
“位带别名区“定义。

每个比特膨胀成一个32 位的字!使用更高效!


例子:
//---------------------------- 
struct BB_CRC_DR_BITS {
    
    Uint32  LPDS[32];//使用“位带别名区 每个比特膨胀成一个32 位的字  32比特膨胀到32个32位。
};
//----------------------------------
struct CRC_DR_BITS {
    
    Uint32  LPDS  :32;    // 0-31    
};

union CRC_DR_REG {
   Uint32             all;
   struct CRC_DR_BITS bit;
};

回复评论 (15)

前后对比更方便!

struct CRC_REGS {
   union CRC_DR_REG    dr  ;     // 
   union CRC_IDR_REG   idr ;     // 
   u8    RESERVED0;
   u16   RESERVED1;
   union CRC_CR_REG    cr  ;    //    
};
#define STM32_Crc_Regs  (((volatile struct CRC_REGS *)(CRC_BASE)))


//使用位带定义。
struct BB_CRC_REGS {
    
   struct BB_CRC_DR_BITS    DR  ;      
   struct BB_CRC_IDR_BITS   IDR ;     
   u32    RESERVED0[8];
   u32   RESERVED1[16];
   struct BB_CRC_CR_BITS    CR  ;        

#define STM32_BB_Crc_Regs  (((volatile struct BB_CRC_REGS *)(CRC_BASE+BB_OFFSET)))

//使用区别:

        STM32_BB_Crc_Regs->CR.RESET=0X1;
        STM32_Crc_Regs->cr.bit.RESET=1;




};
点赞  2008-9-10 12:11

切低倒塌STM32库。看来STM32库又要升级了!

#define STM32_BB_Crc_Regs  (((volatile struct BB_CRC_REGS *)(0x42000000+ (CRC_BASE-0x40000000)*32)))


STM32库 是应该 有 外设I/O寄存器的“位带别名区“定义的。
这样会非常高效。
点赞  2008-9-10 14:13

非常优秀的学者

                                  
点赞  2008-9-10 15:49

位带操作的优越性

位带操作有什么
点亮与熄灭。另一方面,也对操作串行接口器件提供了很大的方便(典型如74HC165,CD4094)。
总之位带操作对于硬件I/O 密集型的底层程序最有用处了。
CM3 中还有一个称为“bit‐bang”的概念,它通常是通过“bit‐band”实现的,但是它俩在
个不同的概念。

位带操作还
􀂋 读取整个寄存器
􀂋 掩蔽不需要的位
􀂋 比较并跳转
现在只需:
􀂋 从位
􀂋 比较并跳转

使代码更简洁,这只是位带操作优越性的初等体现,位带操作还有一个重要的好处是在多任务中,,用于实现共享资源在任务间的“互锁”访问。多任务的共享资源必须满足一次只
有一个任务访问它——亦即所谓的“原子操作”。以前的读-改-写需要3 条指令,导致这
中间留有两个能被中断的空当。于是可能会出现如下图所示的紊乱危象:
同样的紊乱危象可以出现在多任务的执行环境中。其实,图5.8 所演示的情况可以看作
是多任务的一个特例:主程序是一个任务,ISR 是另一个任务,这两个任务并发执行。
通过使用CM3 的位带操作,就可以消灭上例中的紊乱危象。CM3 把这个“读-改-写”
做成一个硬件级别支持的原子操作,不能被中断,
点赞  2008-9-10 16:12

比STM32库更高效!

例如点亮LED

// 代码比STM32库 
   GPIO_ResetBits(GPIOC, GPIO_Pin_4); //关LED5
   GPIO_SetBits(GPIOC, GPIO_Pin_7);   //开LED2

// 一般读操作
    STM32_Gpioc_Regs->bsrr.bit.BR4 =1;// 1:清除对应的ODRy位为0
    STM32_Gpioc_Regs->bsrr.bit.BS7 =1;// 1:设置对应的ODRy位为1

//如果使用 位带别名区操作
  STM32_BB_Gpioc_Regs->BSRR.BR[4] =1;// 1:清除对应的ODRy位为0
  STM32_BB_Gpioc_Regs->BSRR.BS[7] =1;// 1:设置对应的ODRy位为1

代码比STM32库 高效 十倍 !






点赞  2008-9-10 17:21

对内存变量的位操作。

// SRAM  变量

long CRCValue;

// 把“位带地址+位序号”转换别名地址宏
#define BITBAND(addr, bitnum) ((addr & 0xF0000000)+0x2000000+((addr &0xFFFFF)<<5)+(bitnum<<2))
//把该地址转换成一个指针
#define MEM_ADDR(addr)  *((volatile unsigned long  *)(addr))

// 对32位变量 的BIT1 置 1 :

MEM_ADDR(BITBAND( (u32)&CRCValue,1)) = 0x1;

//对任意一位( 第23位 ) 判断:

if(MEM_ADDR(BITBAND( (u32)&CRCValue,23))==1)
{

}
点赞  2008-9-10 17:25

上面,SRAM变量要加volatile

volatile long CRCValue;

// STM32 内部SRAM有 20K---64K,完全在1MB之内。

点赞  2008-9-10 17:52

是方便了

不过不同的场合,需求不一样
全部使用位变量操作寄存器,我觉得程序的可读性会变差
这个可以和c中插入汇编指令一样在特定的场合使用即可
点赞  2008-9-10 21:00

re

                                 位操作太麻烦,还是库好,喜欢用库。
点赞  2008-9-10 22:24

总于硬件可以象8051那样的位操作了。


确实的,自从8051后,发现 8051位操作都不被支持。其实很不爽也可惜。
因为 位操作确实 比 逻辑 操作要 高效些。

而且使用也很频繁的。 从代码密度和效率看,都应该保留才对。

现在 CORTEX-M3 重振 30年前 8051就有的这个功能,而且更强。

剩下 如果 编译器 在 特意 支持一下,那就VERY GOOD 了。
点赞  2008-9-11 11:15

C语句是短点,汇编可没省。

我对比过。用的多的话,还是子程序的方式省空间。
STM32_BB_Gpioc_Regs->BSRR.BR[4] =1
这句对应的汇编代码可不少呢。
点赞  2008-9-11 11:36

代码的效率。

从图可以看出,

一般逻辑操作要 5 条 THUMB-2指令

而 位带别名区操作 只要 3 条THUMB-2指令
点赞  2008-9-11 11:41

基本上与指南说的差不多的。

                                  
点赞  2008-9-11 11:46

对任意 SRAM 的操作。

由于没有使用绝对定位,而是使用 取地址办法。这就消耗了4条指令!

正常 逻辑操作要 6条指令。

用位带别名操作+取地址办法共7条指令,其中位带别名操作才3条指令!!

虽然 多了一条指令,但是 可以它非常紧密。符合 ”原子操作“。
点赞  2008-9-11 12:21

内存里没有特别要求最好不要用这玩意儿!

IO口倒是很有必要!
在模拟时序时是相当有用的!
点赞  2008-9-11 15:06
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复