你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

STM32 位段详解

[复制链接]
STMCU-管管 发布时间:2020-9-8 09:59
) |) V/ z7 J! R
1 定义
首先需要明确下,位段,位带和别名区这三个名词
- A0 n6 a4 {$ Y9 K; i" Q% H  u
名词定义
# j8 b9 W' z: e+ @. k6 \' n8 l7 N
位段

, G. N4 G9 h# \8 f; J
STM32用户参考手册使用的名字

5 i! e  K# \+ N- T+ I: Z" t1 E
位带
4 _8 i7 f9 S  Q) o. ]
CortexM3参考手册使用的
% H) G2 g4 ?* a" x' Q2 r! E: I
别名区
/ k9 X- k# b/ L" ]
地址总线上用来位访问地址区域,

+ n  A% m" z& p) p' O
所以说,位段和位带是一个意思,是不同手册的不同叫法。
# t) C* U1 `# m7 l! [% r
由上述的名词解释得知,位带功能并不是STM32独有的,是CortexM3的功能(CortexM4也有这样的功能)。MCS51有位操作,以一位(bit)为数据对象的操作,MCS51可以简单的将P1口的第2位独立操作:P1.2=0;  P1.2=1 ;这样就把P1口的第三个脚(bit2)置0置1。而STM32的位段、位带别名区最重要的就为了实现这样的功能。
) T5 S; O4 ^( X+ K9 f/ @. C/ I

9 ^4 R' u" @) G2 位带操作

1 N/ ?, a% N* f
2.1 范围

9 `, l3 K2 V$ z/ H, f/ v
位带是有范围的,并不是CortexM3全部地址空间都支持的。在 CM3中,有两个区中实现了位带。其中一个是 SRAM 区的最低 1MB 范围,第二个则是片内外设区的最低 1MB 范围。这两个区中的地址除了可以像普通的 RAM 一样使用外,它们还都有自己的“位带别名区”,位带别名区把每个比特膨胀成一个 32 位的字。当你通过位带别名区访问这些字时,就可以达到访问原始比特的目的。
支持位带操作的两个内存区的范围是:
. c6 K$ v# |0 L  Y, s& Z9 @
. Q1 C& a1 `, y8 d

  R, t+ o' p( r0 {
0x2000_0000‐0x200F_FFFF(SRAM 区中最低1MB区域)

; j. O/ c' i2 I
0x4000_0000‐0x400F_FFFF(片上外设区中的最低 1MB)

! m& x! X2 q1 e
2.2 位带操作

% W4 Y9 Y7 X! B4 k  U
对 SRAM 位带区的某个比特,记该比特所在字节的地址为A,位序号为 n (0<=n<=7),则它在别名区的地址为:

6 v8 l( @" Q5 z  S" O/ E% G3 Z
  1. AliasAddr = 0x22000000 + ((A‐0x20000000)*8+n)*4 =0x22000000 + (A‐0x20000000)*32 + n*4
复制代码
) G# i# s+ C, E! [  g
对于片上外设位带区的某个比特,记该比特所在字节的地址为A,位序号为 n (0<=n<=7),则该比特在别名区的地址为:
  1. 9 Y1 P/ @2 m3 r
  2. AliasAddr = 0x42000000 + ((A‐0x40000000)*8+n)*4 = 0x42000000 + (A‐0x40000000)*32 + n*4
复制代码
8 z; H0 S; z& p/ L4 C
上式中,“*4”表示一个字为 4 个字节,“*8”表示一个字节中有 8 个比特。
1.png
2.3代码实现
把“位带地址+位序号”转换别名地址宏为:
  1. #define BITBAND(addr, bitnum) ((addr & 0xF0000000)+0x2000000 + ((addr &0xFF FFF)<<5) + (bitnum<<2))
复制代码
8 {9 {* l5 z3 E) W0 z
把该地址转换成一个指针:

  1. 0 H( F: F8 M, W0 @7 b7 g4 F
  2. #define MEM_ADDR(addr, bitnum) *((volatile unsigned long *)((addr & 0xF0000000)+0x2000000 + ((addr &0xFF FFF)<<5) + (bitnum<<2)))
复制代码
4 @6 Y! x. K# F' w
其中. U+ t+ @/ }* G

" i) m9 g( E/ r% v; y/ e! ^
addr的取值范围:
/ K) i; J+ G" `' w
0x2000_0000‐0x200F_FFFF
0x4000_0000‐0x400F_FFFF
注意:addr取值要32位对齐
, ~5 y2 s. Q1 z$ K$ u7 b
bitnum的取值范围:
0-31
! d  r/ O# P7 o. H2 o; p
解析:

+ l) `9 t- f. ~$ i, x) O) U, P/ F& L# W
(addr & 0xf0000000) + 0x02000000:
区分SRAM还是外设,如果是外设,结果为4,再加0x2000000就等于0x4200000,0x42000000就是外设别名位带区。如果是SRAM,结果为2,再加上0x2000000就等于0x22000000,0x22000000就是SRAM别名位带区。
, t: O3 ^9 S# \2 a+ f9 v
addr & 0x00ffffff:
屏蔽了最高2位,相当于减去0x20000000或者0x40000000。因为位带区的有效范围是1M,即0x100000,这样子就做到了低6位有效。

+ B( G1 W/ B( o# B% {( F
<< 5:
等价于乘以32

6 c( @5 T6 F/ L3 C1 A' U* r# E
<< 2:
等价于乘以4
& Y7 A; a% w9 J7 U7 h
特别提醒
5 [2 d- N& c) c1 B) Z1 D6 ~* W
当你使用位带功能时,要访问的变量必须用 volatile 来定义。因为 C 编译器并不知道同一个比特可以有两个地址。所以就要通过 volatile,使得编译器每次都如实地把新数值写入存储器,而不再会出于优化的考虑。  |; z& w/ g- R, X/ q3 O; X
6 V2 W+ d7 M7 ~7 O3 Z& P5 h
4 v( ^1 j" h1 n- i3 j$ Y" R: |
3 位段的优点
# }& H8 U' N' w7 ]
最容易想到的就是通过 GPIO 的管脚来单独控制每盏 LED 的点亮与熄灭。另一方面,也对操作串行接口器件提供了很大的方便(典型如 74HC165,CD4094)。位带操作可以把代码缩小, 速度更快,效率更高,更安全。总之位带操作对于硬件 I/O 密集型的底层程序最有用处了
; M) C/ ^& R5 n3 L& T
位带操作还能用来化简跳转的判断。
3 X$ U9 f. ^7 {
当跳转依据是某个位时,以前必须这样做

( J, J8 z# E( y6 S  U0 T
7 R4 ~$ j9 Y% Q+ I! s
1、读取整个寄存器
% _6 O. R$ |" V( r
2、掩蔽不需要的位
. W; P2 k' u7 [$ r; m
3、比较并跳转
, X6 S+ X( z+ `9 v
% ?7 T; a7 q+ Y; H
使用位带操作后
# [( P7 Z7 b! m' u8 q2 t8 A3 q

) g& X& o8 m, S* S- T, M& {
1、从未带别名区读取状态位

( b6 E2 l/ X/ x- w- R0 [- b9 a
2、比较并跳转
2.png
1 R* f: [2 {5 a
当然,对于写入操作也从4步精简到3步
3.png

; q. n( ]. y" ~  S" n- V2 k- ~
# A  o  F0 o# Y, a6 G; o4 E% }% n! t* C1 |
收藏 1 评论0 发布时间:2020-9-8 09:59

举报

0个回答

所属标签

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版