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

STM32学习笔记1——点亮第一盏LED灯

[复制链接]
Savy1314 发布时间:2017-7-14 14:59
2 X; D) C8 h3 i; _
STM32学习笔记1——点亮第一盏LED灯
本文不特殊说明都以stc32F103C8为例,软件平台为KEIL5V5.15
* x) ~$ M) v1 @首先这次我们用寄存器直接点亮LED灯
3 [; j* ]5 Q; JLED电路图如下图:
3 ~9 z, M2 R9 o, N 1.png 8 \$ c# N0 e- h. n" B
可以看出如果需要点亮一盏LED灯只需要IO口输出高电平即可,本次以GPIOB为例子。0 r# m5 y/ L! P; @. }5 O3 x

6 _+ e( f2 z$ l7 U1 z  g

7 T- d- E3 L: \1 [) p2 S" {' r+ _: O点亮LED灯
: ^, i' q7 H' h; h. o; t2 Q7 ~& |1 w
0 D& S  S+ c# X5 G8 M. |
5 J) ~# B% P% l% g
控制IO输出高电平通常需要三步:
5 H; J8 Z3 x1 o: ~1.开启时钟:因为STM32为了节约消耗,故上电时候外设时钟默认不开启。故我们需要开始GPIO的时钟。 $ M6 Z- Z* T4 {4 o5 T4 n# A& `0 M
2.设置GPIO输出模式:stm32F103提供了4种输出模式和3种输出速度:
4 X" y3 J) |- w; L) W% j  |- 通用输出推挽 0 G  z2 g) P- k4 T2 Y5 L9 `; A  y
- 通用输出开漏
' @, \- ~5 }5 s' {- 复用输出推挽:串口输出 5 {4 r& \3 a. P* [( w) Y- m9 o0 e
- 复用输出开漏:IIC
: M- A& s! ~$ k1 O2 ~3 R/ N
( v% ?6 F3 T0 a$ Q; P2 q' G: Y: ^
/ f8 |9 y, R' v% d
推挽输出电路如下图:
9 s2 I" S" ]1 H 2.png
" @' a% I* j7 I; r; b# i* ~两个三极管都是半个周期导通,轮流导通。从而减低了功耗,提高了每个管的承受能力。又由于不论走哪一路,管子导通电阻都很小,使RC常数很小,转变速度很快。因此,推拉式输出级既提高电路的负载能力,又提高开关速度。所以推挽输出可以输出高低电平,但输出幅度取决于输入,不可控。
+ U& F9 w* {2 P, o# h5 i1 a! Z
1 t% D; U$ y  m/ B) v
) O% i7 J+ k) O: a& l# K
开漏输出电路如下图: 7 D7 w' ^' M5 a- M
3.png
9 u$ z4 z3 E+ P从图中可以看出,当没有上拉电平和上拉电阻,当IN输出低电平时候,OUT输出低电平,当IN输出高电平时,OUT处于开漏状态,电平状态未知,当加上拉电阻时候,则上拉电平跟上拉电阻有关。
3 a+ J* n; h- \6 u开漏输出相当于三极管集电极,故它只能输出低电平,需要接上拉电阻才能得到高电平。开漏是用来连接不同电平的器件。很好的一个优点是通过改变上拉电源的电压,便可以改变传输电平。比如加上上拉电阻就可以提供TTL/CMOS电平输出等。(上拉电阻的阻值决定了逻辑电平转换的沿的速度 。阻值越大,速度越低功耗越小,所以负载电阻的选择要兼顾功耗和速度。)
" G0 Q- f. j* O0 j而且可以将多个开漏输出的管脚,连接到一条线上。通过一只上拉电阻,在不增加任何器件的情况下,形成“与逻辑”关系。这也是I2C,SMBus等总线判断总线占用状态的原理。6 X! m. X9 R/ W: f8 p! }% F
3.输出高电平
- r3 Q- V8 N4 W3 q' K. X
( g5 {( T6 _; N, m& V7 G# D
9 J! ~- N2 n! e0 K
寄存器设置
2 k- F' M! e! y6 [/ f# p" g" \* \' h. T# g9 i" u" O: S- @$ I
1.设置时钟寄存器
  J3 k' N/ j, K$ C. ]) h首先GPIO是挂载在APB2总线上的,APB2时钟使能寄存器为RCC_APB2ENR,如下图
6 n! |3 n/ B  P- N- } 4.png
% `  N4 y3 \; y) ~2 F$ A- r1 _故只需开启GPIOB的时钟,即将RCC_APB2ENR第3位置1
- X. H5 c5 z* w
/ q% {" w, y5 X7 Q7 I
+ ]6 {+ c1 g3 o2 _) |, F/ Q) c
2.设置IO口输出状态 % [& v- k6 I( T/ F* c0 ?! o
有关寄存器为GPIOB_CRL和GPIOB_CRH,如下图:
3 p  V! d3 y4 H; [ 5.png
+ a1 G& ~3 e% u5 R- R! [可以看出只需要设置MODEx[1:0]即可,我们可将他置01,设置成中速即可,则默认为推挽输出
% W" E: R  x4 n0 g2 o1 C. T( W- @
5 W* S% O& [/ \
; T! ]; N0 B+ j$ a% Q
3.设置IO口输出电平
" {0 W* d/ a5 F9 iIO电平有3个寄存器有关,分别是GPIOB_ODR,GOIOB_BSRR,和GPIOB_BRR;其中GOIOB_BSRR为置位/复位寄存器,GPIOB_BRR为复位寄存器,这两个寄存器都是间接控制GPIOB_ODR即端口数据输出寄存器,故为了初学方便,我们直接控制GPIOB_ODR寄存器。寄存器相关内容如下:6 ?; T. A9 j- q
6.png
0 m% n( Y9 @7 p. [9 q" j# u因为寄存器可以写和读,故可以直接置1即可。
+ D8 d: P& Q6 L' M; \5 B) U- a' f' ~2 p  m1 ^, B

. _1 I: K7 A- W& E" ]注意事项:
1 s! v+ X- B* x- U1.需要提前设定相关总线和寄存器地址,如下表: % `, ]1 ^+ {- z/ a' w5 B
7.png ( n5 V! j- [* j4 ^6 N% r
2.初学者为了简单,通常都操作GPIOx_ODR寄存器,但实际上我还是推荐使用GPIOx_BSRR寄存器,因为BSRR只有写操作,和ODR要经历读——写操作,时间显然慢很多,而且使用BSRR不会被中断打断。! h& L8 Q& `8 L' h

5 O! r- ]/ l1 N

- f$ J" ]7 E/ o; q2 y1 C以下附代码(灯接GPIOB_8~15)
4 h: U# W- a; W6 _4 K
  1. /*定义相关寄存器地址*/
    # z/ r) S- n% P) ^- K% m
  2. #define GPIOB_ODR            *(unsigned int *)(0x40010C00+0x0c)
    . i9 P7 F4 C* z: b  b
  3. #define GPIOB_CRH            *(unsigned int *)(0x40010C00+0x04)
    " O0 {' {- M: R  E6 k
  4. #define RCC_APB2ENR          *(unsigned int *)(0x40021000+0x18). ^2 s3 Y9 o; F; \2 O* G4 I
  5. /*延时函数*/
    . K, u' \8 N" B$ c  {0 L* {
  6. void delay(){& |# S( c( W9 u! w- X# q2 u2 X
  7.     unsigned long n = 30000,j;' i% f2 [# g8 a* L
  8.     while(n--){0 p: \; |. r* e5 ^, d
  9.         j = 12;
    ) ~, h" N8 {& b; o
  10.         while(j--);
    ; x1 N0 Y) G. J- C5 O
  11.     }
    . t' J  B. S+ \& U8 d& T
  12. }/ M5 i- `# ?4 |
  13. int main(){# R9 V4 m0 h  o+ t  W5 h$ y
  14.     unsigned char i;' G5 A( z2 w* B& f1 n0 q$ x0 }. k  c9 L: D
  15. % f* V2 E& l$ r2 }' q! n
  16.     /*开启时钟*/) T" Z2 j7 r0 d0 f9 b
  17.     RCC_APB2ENR |= 1<<3;! y: C" z; v, r/ D
  18.   y! p! G0 K2 J+ N1 \
  19.     /*配置PB8到PB15推挽输出,中速模式*/
    " h. b6 y2 I9 N2 k- ~+ Q
  20.     GPIOB_CRH |= 0x33333333;        5 Y7 c9 q& [' J- v3 o, I
  21. 5 y" B) s$ I; ?: X  q
  22.     while(1){) \( A# Q9 T, l0 V$ g: n
  23.         /*闪烁两次*/% w& X& P; D+ T3 G* P3 Y
  24.         GPIOB_ODR |= 0XFF00;
    8 \: p. x4 [4 B5 n+ L
  25.         delay();- M$ S( ~; O, w; N" e$ V9 ]% e; _
  26.         GPIOB_ODR &= ~0XFF00;
    * |$ [/ s, X8 W: p% D4 l
  27.         delay();
    6 Q3 R& A0 L0 E9 \3 e
  28. & R1 p( |. T9 Z6 }" n
  29.         GPIOB_ODR |= 0XFF00;
    5 q" f' I& x( B7 Y, f( s
  30.         delay();' `, h6 Z  l! F) j( |6 G: I* z
  31.         GPIOB_ODR &= ~0XFF00;* e2 w7 E' j1 T0 Y2 \; s: Z! Y
  32.         delay();
    : H* u5 y9 a6 V5 b; c
  33.         GPIOB_ODR = 0x0100;4 b/ n- l0 A& @% u; E! y
  34.         /*流水灯*/( |8 e. I* Y; \4 V, Y- ?4 D
  35.         for(i = 0;i<7;i++){
    . H6 t' {6 C% J. j! U
  36.             GPIOB_ODR<<=1;
    ! S# q+ T- e" W. @
  37.             delay();
    0 p, N- [$ Y' {8 H% K
  38.         }
    ! i" f: {) E8 @7 m0 l# w
  39.         for(i = 0;i<7;i++){/ z, L: e+ l! N# r  H! Q. e
  40.             GPIOB_ODR>>=1;
    2 Q+ `) u' `7 T3 N# ^3 p
  41.             delay();# S2 L9 F" ]$ ]6 j& J* S
  42.         }) q' b* i" O4 F/ M0 p5 a

  43. 7 W/ u( H( U5 f! b3 p5 S9 H3 y  I, z
  44.     }4 A( K0 i9 n+ R8 p4 p, m) R
  45. 7 j$ M6 `: q+ X" j. U
  46. }
复制代码

) z  z% z, d9 m- b
! v8 A* o$ X7 W8 f$ M
赞 收藏 1 评论0 发布时间:2017-7-14 14:59

举报

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