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

【经验分享】STM32 位带原理分析和应用

[复制链接]
STMCU小助手 发布时间:2022-4-2 15:00
01. 位带概述
! Q" @& ~7 o1 Y8 {3 [/ r位带操作简单的说,就是把每个比特膨胀为一个 32 位的字,当访问这些字的时候就达到了访问比特的目的,比如说 GPIO 的 ODR 寄存器有 32 个位,那么可以映射到 32 个地址上,我们去访问这 32 个地址就达到访问 32 个比特的目的。这样我们往某个地址写 1 就达到往对应比特位写 1 的目的,同样往某个地址写 0 就达到往对应的比特位写 0 的目的。6 T4 j' W9 l" y3 w8 ], v
: g% }8 O' X3 P3 o
支持了位带操作后,可以使用普通的加载、存储指令来对单一的比特进行读写。在CM3中,有两个区中实现了位带。其中一个是 SRAM 区的最低 1MB 范围,第二个则是片内外设区的最低 1MB 范围。这两个区中的地址除了可以像普通的 RAM 一样使用外,它们还都有自
+ Z2 k  p1 p5 P; P己的“位带别名区”,位带别名区把每个比特膨胀成一个 32 位的字。当你通过位带别名区访问这些字时,就可以达到访问原始比特的目的。
; L( T& g: t* V7 a
( N" Z/ {6 k6 I: g" m2 C 20200820152437356.png
7 O6 a" {( }* i' c5 {) J/ @
' R2 n; }4 {" }& q! Y1 \$ I02. 位带操作2 S) T$ D, \* t2 s

( H7 P) }3 k; L. z# Z) a 20200820152450171.png
6 O1 ^. w- ]  [4 m$ H9 |  h+ n& ]: P
SRAM 区中的位带地址映射
: a! Y. b) N3 B4 o; w: J/ Q, _! b' H. {) w" u5 t
20200820152458959.png : I1 ^$ x- k9 [- ^* `9 ^6 b. M  V
0 A7 I5 Y- o" \# |/ _7 t  H
对于片上外设,映射关系如下表所示
8 ^  E: o( g4 [8 g1 O, w: @4 O5 Q7 l' r8 ~0 e- X
20200820152508681.png
. U& g3 w* q! v# j# h
5 Z4 y6 U" B) C# Y4 ]: z03. 位带C语言实现
9 L8 U0 Q  J, I3 M
  1. //位带操作,实现51类似的GPIO控制功能9 f7 F9 B4 m& O+ j
  2. //IO口操作宏定义
    2 T7 r3 L: u6 _1 \" S% ^, ^
  3. #define BITBAND(addr, bitnum) ((addr & 0xF0000000)+0x2000000+((addr &0xFFFFF)<<5)+(bitnum<<2)) ! ?, D* F" l$ R4 j1 g
  4. #define MEM_ADDR(addr)  *((volatile unsigned long  *)(addr))
    6 u1 s1 u# F4 H8 l/ L
  5. #define BIT_ADDR(addr, bitnum)   MEM_ADDR(BITBAND(addr, bitnum))
    0 C. n, F( s9 G1 D( M, a$ }; {/ [
  6. //IO口地址映射' u' R- f+ }7 F6 W( D; m' n! A( i4 N4 N
  7. #define GPIOA_ODR_Addr    (GPIOA_BASE+20) //0x400200142 k0 F# G: ~& A- c( G5 }
  8. #define GPIOB_ODR_Addr    (GPIOB_BASE+20) //0x40020414
    . R+ f/ z4 n2 \$ r& _3 V% e
  9. #define GPIOC_ODR_Addr    (GPIOC_BASE+20) //0x40020814
    9 p7 O+ k6 B3 d; a
  10. #define GPIOD_ODR_Addr    (GPIOD_BASE+20) //0x40020C14
      r! v7 k( J: c1 a2 ^8 Y/ N0 J4 g8 k: h& v+ N
  11. #define GPIOE_ODR_Addr    (GPIOE_BASE+20) //0x40021014
    3 y, Y* ?' Z7 N% M! k5 r8 O- U
  12. #define GPIOF_ODR_Addr    (GPIOF_BASE+20) //0x40021414   
    6 V) t: w7 C* e' {" k# s7 h# l& _
  13. #define GPIOG_ODR_Addr    (GPIOG_BASE+20) //0x40021814   
    ! g8 A) w+ z" Z$ l1 D3 p
  14. #define GPIOH_ODR_Addr    (GPIOH_BASE+20) //0x40021C14   
    # \. _! v+ d% U$ D! }' ?
  15. #define GPIOI_ODR_Addr    (GPIOI_BASE+20) //0x40022014     
    4 a/ X$ n" e1 h" {; G3 [7 e

  16. - q- H* [0 _) a6 @9 e1 A+ [7 A$ _
  17. #define GPIOA_IDR_Addr    (GPIOA_BASE+16) //0x40020010
    7 \9 w* J+ D* T. U9 i! F
  18. #define GPIOB_IDR_Addr    (GPIOB_BASE+16) //0x40020410
    * @2 V1 d/ ~! F. f4 h( q7 s, C
  19. #define GPIOC_IDR_Addr    (GPIOC_BASE+16) //0x40020810
    5 _( Z/ B2 r  }) w. M6 n- ~
  20. #define GPIOD_IDR_Addr    (GPIOD_BASE+16) //0x40020C10 - Y$ f( P! ?! @. P2 b! O$ E
  21. #define GPIOE_IDR_Addr    (GPIOE_BASE+16) //0x40021010
    % h, N% w. r$ k( d7 k
  22. #define GPIOF_IDR_Addr    (GPIOF_BASE+16) //0x40021410 $ d; p: C6 y3 r3 X
  23. #define GPIOG_IDR_Addr    (GPIOG_BASE+16) //0x40021810
    & p1 X% y: S8 x+ |9 T( q
  24. #define GPIOH_IDR_Addr    (GPIOH_BASE+16) //0x40021C10
    8 C* P2 V4 m4 C
  25. #define GPIOI_IDR_Addr    (GPIOI_BASE+16) //0x40022010
    ( t+ v( b( }$ E3 _5 |

  26. * W2 Z8 q8 L; P" ]6 f. a
  27. //IO口操作,只对单一的IO口!
    * t7 j8 ?$ J! f9 w& k
  28. //确保n的值小于16!
    - a- q! h5 s3 |; u
  29. #define PAout(n)   BIT_ADDR(GPIOA_ODR_Addr,n)  //输出
    3 e' {! [& k& Z) Z1 k* m: R
  30. #define PAin(n)    BIT_ADDR(GPIOA_IDR_Addr,n)  //输入
    * R) N% z& p7 A  r
  31. 3 r* s+ \' I+ H
  32. #define PBout(n)   BIT_ADDR(GPIOB_ODR_Addr,n)  //输出
    5 ?" C+ A7 P2 `& Z
  33. #define PBin(n)    BIT_ADDR(GPIOB_IDR_Addr,n)  //输入
    4 m5 F6 g" t0 p* F- c# v
  34. / y$ V! \9 h+ J1 V
  35. #define PCout(n)   BIT_ADDR(GPIOC_ODR_Addr,n)  //输出
    1 ]( n8 O! h/ Z9 r$ V7 N- I
  36. #define PCin(n)    BIT_ADDR(GPIOC_IDR_Addr,n)  //输入
    2 \  B! O, y; w: V
  37. 4 a- s8 P1 f8 h9 A1 l: i. J' V
  38. #define PDout(n)   BIT_ADDR(GPIOD_ODR_Addr,n)  //输出 % C& D3 ~, h/ ?3 z
  39. #define PDin(n)    BIT_ADDR(GPIOD_IDR_Addr,n)  //输入   B0 L  i, G6 Z$ ]4 M/ ]  i" U% o
  40. ( u1 E- o6 @0 [( \/ S
  41. #define PEout(n)   BIT_ADDR(GPIOE_ODR_Addr,n)  //输出 ) s  c" T; {9 J8 h
  42. #define PEin(n)    BIT_ADDR(GPIOE_IDR_Addr,n)  //输入7 U( C! A+ |0 E, i1 z0 x# f
  43. 7 }& M* k3 @/ v7 v: E4 P
  44. #define PFout(n)   BIT_ADDR(GPIOF_ODR_Addr,n)  //输出
    9 [8 Y* P0 n, F- z: H2 ~9 [5 W
  45. #define PFin(n)    BIT_ADDR(GPIOF_IDR_Addr,n)  //输入
    ; g/ |% l, _# N
  46. 9 r1 N+ {' G- v$ I" o1 [( j9 v
  47. #define PGout(n)   BIT_ADDR(GPIOG_ODR_Addr,n)  //输出
    ; e) ~8 s4 Z# w% L- ]
  48. #define PGin(n)    BIT_ADDR(GPIOG_IDR_Addr,n)  //输入
    * T9 G  L0 }9 q6 J3 w; n# I

  49. - u; C7 e% G; k# d# t' d
  50. #define PHout(n)   BIT_ADDR(GPIOH_ODR_Addr,n)  //输出
    8 C( U% B) a9 p! ~3 @* W  k
  51. #define PHin(n)    BIT_ADDR(GPIOH_IDR_Addr,n)  //输入: q! ]- ~: Z9 x/ v
  52. % B9 I& F! k% O
  53. #define PIout(n)   BIT_ADDR(GPIOI_ODR_Addr,n)  //输出 9 a- I) d$ G' h& w' Z/ I2 [. i
  54. #define PIin(n)    BIT_ADDR(GPIOI_IDR_Addr,n)  //输入  {5 D5 d7 z0 }; _# k9 a. V
复制代码

! b+ [$ `" o  [, {. q( U. m- u& R04. 应用示例一3 f6 Y# @) g$ E3 d
LED循环亮1秒 灭1秒3 K: m) [" `3 G) E6 c; T  s+ {# |
! k- t$ w' a0 g
led.h文件
- a, J8 P9 b( B9 |9 \, L
7 t  a( a* }5 ^5 U- k* a
  1. #ifndef __LED_H__
    * k' \3 H1 @) I5 q% s
  2. #define __LED_H__, t) x( [* \, d8 O* Q4 \

  3. 3 c9 {) f- E; `1 ~: f6 X
  4. #include "sys.h"
    2 I' v+ f0 M2 k4 ?8 z* P2 |, o

  5. + q+ l( E/ }8 g% T
  6. //LED初始化
    / Y2 r3 o6 R/ O: B, G- {
  7. void LED_Init(void);
      V) S$ M" Z% \
  8. + \+ T" e: [3 h  K7 w: ]4 `0 B
  9. //位带操作
    : B7 w& c" z( N$ _
  10. #define LED1 PFout(9)0 |4 {' Z  ~. p, V# O3 t
  11. #define LED2 PFout(10)
    ; \9 l% L5 m) _! b

  12. / }, l" W$ G1 q" z4 U5 A+ a; w
  13. 1 Q' W3 U& s8 c% S5 h
  14. #endif /*__LED_H__*/
复制代码

0 W* X; L1 D. p2 [# A/ C/ _$ Dled.c文件
' s0 Z6 N6 j, j6 M: x& [
$ C$ \# @) p: B: f+ a
  1. #include "led.h"
    ! }7 L+ [& ]' [6 S9 j

  2. ; i: b; a9 r8 {- Z0 C

  3. 3 Z! C$ m1 f5 e% d
  4. //LED初始化" w6 A# B. ]% w8 V7 o: g
  5. void LED_Init(void)/ n, d- p" n4 \7 ~$ z6 K
  6. {) j, E! k: }( S. Z; J% _: T
  7.         GPIO_InitTypeDef gpio_InitTypeDef;
    1 O4 Z2 g7 q7 n5 c+ O
  8.         , J7 L$ [7 L# a% c9 Y# [7 ]
  9.         gpio_InitTypeDef.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10;4 v# e! F2 G& k, O1 H9 I
  10.         gpio_InitTypeDef.GPIO_Mode = GPIO_Mode_OUT;$ I, O8 u  x) K+ p5 |
  11.         gpio_InitTypeDef.GPIO_Speed = GPIO_Speed_100MHz;
    $ F2 a3 E: T9 Z2 X9 _6 {) G
  12.         gpio_InitTypeDef.GPIO_OType = GPIO_OType_PP;( H3 j, F6 Z% q2 w! y0 K5 L0 n
  13.         gpio_InitTypeDef.GPIO_PuPd = GPIO_PuPd_UP;
    0 T) \9 ~* L3 ]4 A. {0 b
  14.         
    : d* H7 R  x5 k
  15.         //使能时钟* Z  V9 G; y9 s! p
  16.         RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF, ENABLE);- q+ d2 x8 E+ h1 j5 H  v
  17.         . A' M3 j# K! r& T7 F
  18.         //GPIO初始化
    7 w, ]# @* z: }
  19.         GPIO_Init(GPIOF, &gpio_InitTypeDef);
    ( p: N- ]. u! q
  20.         
    : ?8 V1 Q. K+ I! }$ _
  21.         //设置高电平 LED灭
    ) t! s, ], D8 G- a
  22.         GPIO_SetBits(GPIOF, GPIO_Pin_9 | GPIO_Pin_10);& T3 p5 X2 i, V$ F  S- B
  23. }
    ' {" _1 @5 x2 T( V6 Q  I8 i
复制代码
# F- j  q  M! D+ Z+ P/ Y
main.c文件
, r2 Q* V  r2 `0 _) t1 G* n
8 P6 o. o& v2 U, T
  1. #include "stm32f4xx.h": c- M& G" _/ ]5 }( _) ~
  2. ! R- h* S% Y2 P* Q
  3. #include "delay.h"3 O8 [- z8 g9 h/ i8 \
  4. #include "led.h"1 B9 p  i/ B5 z
  5. ) o8 g8 ], N* ?, }! U
  6. int main(void)0 X8 {  Q0 j* {! b6 v
  7. {               
      }9 F  e1 N# E  G- B
  8.         delay_init(168);3 `* f. G- T7 y7 M9 L" ]7 _
  9.         1 P& L- T6 `% w
  10.         LED_Init();1 u1 S. ^  D2 Z0 Q* M& m
  11.         
    & E6 k7 P! C  K7 C' p# R6 Q
  12.         //3. LED闪烁
    : G. o/ z  `3 F: }: L
  13.         while(1)6 h/ D# l) p1 a- o% X2 g3 \  D
  14.         {7 `' d  F4 H; y; g, l
  15.                 //灭4 R! Q# t7 x) ]0 L7 h8 |6 [
  16.                 LED1 = 1;! ~$ A: t; S) `9 ~+ Y9 X6 V1 @
  17.                 LED2 = 1;
    * c- s& O' ?5 W
  18.                 & _* h9 F  t! t% Z
  19.                 delay_ms(1000);! ^1 W2 n$ e/ e9 x! B) p
  20.                
    8 f1 T; f. }3 z8 j: H) P) u
  21.                 //亮2 D4 }: P' s( {
  22.                 LED1 = 0;) I  q3 y# x& d+ u" P8 y
  23.                 LED2 = 0;
    ' Z, U6 T" J4 y
  24.                 delay_ms(1000);/ D, G5 K7 S  s# N$ W% Z
  25.         }        ! f  w' G$ R1 [
  26. }
复制代码

; Q4 p; H3 h5 Z, Q" a8 Q% X05. 应用示例二  u( f% P+ M9 C) f
流水灯
0 p& m5 A; r2 N0 c& V
% K5 K1 `. a5 F" |; `+ hmain.c文件
% k& ?+ n4 K; F# U% C; n. c+ e# `% K2 w' O
  1. #include "stm32f4xx.h"+ q7 q6 X! k& G4 }- w. V8 [
  2. ) q5 Q5 m: ?" D8 }% S! b" y
  3. #include "delay.h"
    / F8 b9 ]: {% w( y
  4. #include "led.h"  q) \3 G; d0 y2 z4 r
  5. . @& ~" z, j# ^
  6. int main(void)
    0 m9 \* r+ z; e3 G+ \/ }
  7. {               
    # e1 U4 \7 B/ S/ B# L
  8.         delay_init(168);
    $ p, U* a+ `- j! l' J
  9.         ) o( a6 j& p- D$ [
  10.         LED_Init();+ ^- x0 Y1 Z* T' t1 i2 |0 O
  11.         
      v( c  p* h  \
  12.         //3. LED闪烁
      _* `' @, A( e8 b; t
  13.         while(1)
    - k% ]' D5 u% w
  14.         {$ ]* @1 k* ^9 J/ k0 [8 Q( ^
  15.                 //灭
    , J" b$ b+ t2 X, Y. E5 ]8 ?
  16.                 LED1 = 0;; I% V0 s; Y0 Q1 g- s1 p9 ^
  17.                 LED2 = 1;
    % P$ S- ~! K4 R: m3 V, B3 S0 x
  18.                 , j( c2 M6 J$ C5 v8 o% e$ A( T
  19.                 delay_ms(1000);
      n$ T& s+ J% K
  20.                 : b! _+ o/ ?8 f8 {
  21.                 //亮6 b$ L' D* R$ v
  22.                 LED1 = 1;+ ?) \* y; j$ q2 f3 P& z7 v8 [
  23.                 LED2 = 0;1 |/ A$ V3 \" R# v0 H+ v
  24.                 delay_ms(1000);5 u3 o' C% T1 @  L
  25.         }        
    2 q0 s! X. g  ?* g/ V9 v
  26. }
复制代码

8 j/ h/ ^1 `) w
赞 收藏 评论0 发布时间:2022-4-2 15:00

举报

0个回答

所属标签

相似技术帖

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版