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

【经验分享】STM32固件库文件编程结构思想的理解

[复制链接]
STMCU小助手 发布时间:2022-1-30 01:00
STM32的固件库文件功能相当完善,提供的API完全能满足一般的项目需要。刚从51单片机转到STM32的人,肯定会被这么庞大的东东吓到,51单片机上对IO口操作,简简单单几行代码就搞定了,一个C源文件就搞定。假如用STM32,对IO口进行简单操作,远不是几行代码能搞定的。(其实直接操作寄存器也能搞定)。
   废话不多说,这就带你解剖固件库文件,包你看完之后豁然开朗。
   首先,请看一段简单的C语言代码
  1. #include <stdio.h>
    , p0 M7 o) s9 n4 \: S- q

  2. . {  u) p/ p2 i  \/ C6 o
  3. #define base  0x0012ff60
    / g# R/ Z3 M( e: I  |: e
  4. #define flash ((TestType *)base)6 k' m5 m4 G" R( x) U8 F- \

  5. / G$ ^: `. b8 m
  6. 4 C2 u+ P2 ~: ?& f* U2 R
  7. typedef struct+ u6 i5 y6 B; U
  8. {
    ' q! s  N3 H9 I: u
  9.       int i;
    2 I1 q1 c+ \* H( v
  10.       int j;
    ' W" x0 D' V9 y' _8 @4 h
  11.       int k;- d- u. ?6 d% p! d- `! s$ p: B$ P4 R: w
  12. }TestType;
      C' C- {& d" p' j

  13. % J$ w; B. R5 h( A4 B, u1 F
  14. void main(), U4 d& d3 Y& r0 b
  15. {2 N: h4 d# T  \4 L! s
  16.        flash->i = 0;! x, q& @( V! o4 p" f
  17.        flash->j = 1;5 E: K% J7 G+ g/ {% l
  18.        flash->k = 2;; b9 s$ P. d5 Z1 A  [0 y
  19. / `7 u5 E; v* i
  20.        printf( "%x \n", flash->i);. O) u; ?8 r* A% J
  21.        printf( "%x", &(flash->i));
    5 s# e2 K2 s* J
  22. }
复制代码

! @- p& I* I5 N: r4 |' G
有人会问了这段代码有什么用?我告诉你ST的固件库都是按照这种方式编写的
上面程序打印出来结果为   0
                                  0x0012ff60
把上面的程序分析几分钟后,我再给你揭晓。就拿GPIOA口来说吧,你看stm32f10x.h中能看到
  1. #define PERIPH_BASE            ((uint32_t)0x40000000)
    6 u# h4 g+ M4 |, e. r
  2. #define  APB1PERIPH_BASE                 PERIPH_BASE8 }0 D: l9 O! Z6 M% z' }8 T6 V7 N7 N
  3. #define APB2PERIPH_BASE     (PERIPH_BASE + 0x10000)& ]; E0 b% z3 W5 G* l# L+ n" o9 p
  4. #define AHBPERIPH_BASE       (PERIPH_BASE + 0x20000)3 V+ h. P2 I! X6 w
  5. #define GPIOA_BASE             (APB2PERIPH_BASE + 0x0800)
复制代码
% P1 j' D. N- K; F# \6 h; h
小学学的加减法就能把GPIOA_BASE 算出来,为什么是这么多呢?看ST的手册,人家就是要规定这样,没办法。
有了地址之后,GPIOA的各个寄存器怎么办涅,它们是控制IO的关键所在。GPIO的各个寄存器都是连续排列的,为什么要连续排呢,方便找啊,用结构体就能很好搞定了
在stm32f10x.h中
  1. typedef struct) p* ?% L5 A) u) t
  2. {& b; j$ l6 D/ a4 x3 X$ H* j
  3.   __IO uint32_t CRL;
    $ y& Z3 I5 `, I5 R
  4.   __IO uint32_t CRH;
    3 w: f; h+ r- i0 t) w5 K
  5.   __IO uint32_t IDR;, n, c! G' k1 q3 _* G4 M
  6.   __IO uint32_t ODR;
    3 ~* q8 V, ?) ]
  7.   __IO uint32_t BSRR;' o7 @) L: \" Y0 [2 E& N) o
  8.   __IO uint32_t BRR;
    4 W! A$ @1 A4 Q, o& E! m
  9.   __IO uint32_t LCKR;& D! K# g7 S% _! @: \- n6 ~
  10. } GPIO_TypeDef;
复制代码
; l% B7 f/ @; h% ~4 V/ G
每个寄存器都是32位的,所以很方便用结构体寻找每个寄存器,准备工作都做好了,接下来就要开始针对GPIOA设置了
在core_cm3.c中
  1. #define GPIOA               ((GPIO_TypeDef *) GPIOA_BASE)
复制代码

( H8 h6 V% j& u4 x
把地址强制转换成结构体指针,这样就能很方便对寄存器操作。
寄存器搞定了,接下来就真对用户操作了,要很好的让用户使用,就得人性话点,所以用enum枚举变量就能实现,你就再也不用为想输入的值去烦恼了,直接输入名称就行了,拿IO口的输出速度来说
  1. typedef enum6 t5 r+ q' v' ], v+ z
  2. { , w- D) R. ?; O( h
  3.   GPIO_Speed_10MHz = 1,# T# g+ l: {% |8 U1 {- e: j" t
  4.   GPIO_Speed_2MHz, . M6 e$ r  `1 M* Q8 c8 a
  5.   GPIO_Speed_50MHz
    5 F" M& K# Q( c6 Z& l; P
  6. }GPIOSpeed_TypeDef;
复制代码
( D- N  G# a3 U1 t
要说人性化,ST还有一点不得不提,那就是位带操作,改变了 写地址-取地址数据-位操作-数据写入地址的操作,直接改为写地址-数据写入
,直接位操作。
ST的编程结构是很值得借鉴的,使得编程序时结构很清晰,脉络很清楚。至于如何去发挥,得看个人水平了

: a/ c- V" E7 i0 [! O
赞 收藏 评论0 发布时间:2022-1-30 01:00

举报

0个回答

所属标签

相似技术帖

官网相关资源

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