位段操作随笔
位段操作并不是ARM Cortex M4独有的,早在8051时代就有类似的特性。
在Cortex M4内核的MCU中当进行数据读取或者写入时,位段操作可以减少指令数量。
例如,对数据写,不使用位段时
1 LDR RD,=0x20000000 ;设置地址 2 LDR R1,[R0] ;读 3 ORR.W R1,#0x04 ;修改位 4 STR R1,[R0] ;写
使用位段时
1 LDR RD,=0x22000000 ;设置地址 2 MOV R1,#0x01 ;设置dat 3 STR R1,[R0] ;写
另外位段的操作具有原子性,对数据的操作不会被中断打断,从而避免了数据冲突的发生。
要在Cortex M4的MCU中使用位段操作,需要了解以下术语:
1、位段区域;支持位段操作的存储器地址区域:
SRAM, 1MB, 0x20000000 ~ 0x200FFFFF
外设, 1MB, 0x40000000 ~ 0x400FFFFF
2、位段别名;位段区域的位映射地址,对这块内存的访问会影响位段区域各个位。地址转换C语言实现如下:
1 #define BIT_BAND(addr, bitnum) ((addr&0xF0000000) + 0x02000000 + ((addr&0x000FFFFF)<<5) + (bitnum<<2)) 2 #define MEM_ADDR(addr) (*(volatile unsigned long*)addr) 3 #define BIT_ADDR(addr,bitnum) MEM_ADDR(BIT_BAND(addr, bitnum))
对于STM32F407,其GPIO的地址就位于位段区域中,因此可以采用位段操作,加速GPIO的单个Pin管脚的数据读写:
例如,要将GPIOB的第3个管脚置高:
1 #define GPIOB_ODR_ADDR (GPIOB_BASE + 0x14) 2 #define PBOUT_REG(n) BIT_ADDR(GPIOB_ODR_ADDR, n) 3 4 PBOUT_REG(3) = 1;
对比库函数,大大提高了效率。