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

STM32学习笔记05—GPIO输入输出实验

[复制链接]
STMCU-管管 发布时间:2020-10-27 14:55
STM32学习笔记05—GPIO输入输出实验

' w6 B7 ?! k  Q# e3 D
5 c) T5 C4 O3 f7 v
5.1 STM32单片机GPIO概述
9 v1 v9 ^, A1 ]4 l& b! D       STM32中每个IO口都有很多个作用,比如这次我们使用的STM32F103ZET6的PA0口,既可以作为IO口使用,还可以作为待机唤醒(WAKEUP),模拟输入(ADC功能)等。根据数据手册中列出的每个I/O端口的特定硬件特征,GPIO端口的每个位可以由软件分别配置成多种模式。3 a$ }3 ]8 F6 ?% A+ Y

+ H. K: \* J* b+ `5 ?" M' G
/ m2 K, [, U1 }* z* J# H
(1)输入浮空
* E" `9 X! N/ o(2)输入上拉
$ q* W8 P$ x4 T! c5 S! ](3)输入下拉
3 T2 x5 W$ Q6 [(4)模拟输入
+ s- j0 k7 `) `+ M" O(5)开漏输出
8 N2 S0 [4 ?/ v9 F' n; X7 V7 Z" n(6)推挽式输出
2 {2 Z$ M6 E7 s( n(7)推挽式复用功能
& O) A3 d* G) B& ]& z% }- A(8)开漏复用功能) {$ s" y: `  q1 i5 ~$ p

  |: z- J" `4 }, ]+ O

  X! q: z4 I! c; X       每个I/O端口位可以自由编程,然而I/O端口寄存器必须按32位字被访问(不允许半字或字节访问)。GPIOx_BSRR和GPIOx_BRR寄存器允许对任何GPIO寄存器的读/更改的独立访问;这样,在读和更改访问之间产生IRQ时不会产生异常错误。3 K: ]3 B$ F" L( B' n: z& n5 r7 m

( a7 R' c" H) T7 x0 Q7 ?5 J$ M
4 M: X# B  C$ O) L
STM32F103系列的基本IO口结构如下图所示
# p  z  V$ t; g/ S+ n% C% A
1.png

* `6 Y$ G# i' W& X
9 ~$ w8 l6 ]% G: V

) B5 {% [1 Y  q6 n/ R

9 A" D2 @# b, _9 c9 ~8 S从结构图可以看出来,STM32的GPIO口可以配置好几个选项,内部上拉下拉电阻的选择,推挽输出或者开漏输出,对于复用功能,有专门的复用输入支路和输出支路。STM32F103的端口由10个寄存器控制,但是常用的并不多,时钟控制寄存器APB2ENR,模式控制寄存器CRH和CRL,输入寄存器IDR,输出寄存器ODR。
' s! ]9 v& ^7 o# I0 U8 p5 @; r
  q# z% n8 U: |

( ?. B( p3 ?4 [5.2 相关寄存器
7 o+ @2 C* |1 E3 _6 g/ }# L% V5.2.1 APB2 外设时钟使能寄存器:RCC_APB2ENR
1 p- M4 \' B' m9 e) T* h# Y3 J$ H1 _ 2.png
' u+ x* _1 i" k- g3 j1 Z* pBit 14:串口1时钟使能(写1开启,写0关闭)
% I. {  S+ q2 |) LBit 12:SPI1时钟使能(写1开启,写0关闭), R( L- n& K+ G1 @9 p, O
Bit 11:定时器1时钟使能(写1开启,写0关闭)
9 Y4 W) A4 R% ^( qBit 10:ADC2时钟使能(写1开启,写0关闭)
" k0 g+ e# u( y. L' `$ k# u  nBit 9:ADC1时钟使能(写1开启,写0关闭)
; V) i+ x9 b5 s2 t) R$ {Bit 6:GPIOE时钟使能(写1开启,写0关闭)
# e* V$ y. T. d  v! A: O% B' mBit 5:GPIOD时钟使能(写1开启,写0关闭)
" [3 k* f( {, {2 y+ o1 _9 ZBit 4:GPIOC时钟使能(写1开启,写0关闭)
; i' h' r+ k: Q" h" NBit 3:GPIOB时钟使能(写1开启,写0关闭)
& g8 F5 g9 P- u+ OBit 2:GPIOA时钟使能(写1开启,写0关闭)+ S4 K- S; m+ l
Bit 0:辅助时钟IO时钟使能(写1开启,写0关闭)! Y# ]* H( R+ c, D
; b' n* `: S' V% F! q
1 G3 N+ S3 s' E8 o
2 {/ L9 E+ `. Q: j7 g
5.2.2 端口配置低寄存器:GPIOx_CRL(x=A..E)" d' i+ K" B. p* x* T
3.png 7 f, `2 ?" C! r7 i
端口配置表:% c  X# F$ k9 h- j0 ^& s( N
4.png & X) I9 M' Q! }' f
5.2.3 端口配置高寄存器:GPIOx_CRH(x=A..E)( R8 h( X) b, ~9 X- ?$ J+ |) S
5.png ' o* ]0 }; X0 B! q
配置方式和端口配置低寄存器一致。
$ _% I& X2 @- n3 m
( L$ _/ E' q2 g9 _5 y
  [! ~$ s5 {" j9 E# Y

- c. C5 H' j- ]1 h5.2.4 端口输入数据寄存器:GPIOx_IDR(x=A..E)8 }$ J! A: o) }' F3 `
6.png
+ h& [  V+ a# \* f8 IBit 15~Bit 0:端口输入数据(这些位属于只读并只能以字的形式读出)
# Q9 u5 {7 v. B: A7 U9 Z3 q0 S# p# k1 S

5 t% p2 H8 i' Q
% C' J# F: ^4 o1 L% L/ U5 l5.2.5 端口输出数据寄存器:GPIOx_ODR(x=A..E)! o' v. W/ O$ s1 @+ m- V; V
7.png
( g# W+ |. w2 _4 t4 n( V6 dBit 15~Bit 0:端口输出数据(这些位属于只读并只能以字的形式操作)  l- z  l6 L1 }; P+ l% T& ?
注:在输入模式下,ODR的数据可以控制端口内部是上拉还是下拉,写入1意味着端口上拉输入。9 x) n4 T) `3 a  Z

8 R" R/ x5 D) i' m/ ?9 G! t# M

  ~' i6 s; {1 m* H! j; S' F7 j5.3 GPIO的输入与输出例程
4 w9 ^9 e5 ^4 v! O4 Q       我们现在在PA0端口接一个按键,PA端口接一个LED,当按下按键的时候,LED以100ms亮,100ms灭,抬起按键后LED常亮。: Q* ^4 o9 C, z. e
4 M) s+ j* C2 D7 x# T; ^% n" P0 g
# O7 i& @( b3 s  P

2 ]3 J5 e5 q: Y+ X; z% R7 y(1)在stm32f103x.h文件中添加GPIO的结构体和地址映射。5 B- d) X% Y% G& X0 L, V+ f
8.png
+ N+ y. y' D- j" l(2)在HEADERWARE目录下创建GPIO文件夹,并创建gpio.c和gpio.h两个文件* A& S$ g7 ]0 w* r* ?. n/ i/ x
9.png ( z3 G6 ?3 E# F7 o0 U
(3)在gpio.h文件中输入以下内容:
" W7 E- h3 O1 S& o0 |( L* ] 10.png
  m! u) @+ K  [' `(4)在gpio.c文件中输入以下内容
6 M9 A( S/ X& @1 Y 11.png 9 d! |! e$ N( @/ ~
(5)将gpio.c文件和gpio.h文件添加进项目
. T$ t# A9 c# p7 v 12.png
( k" |% ?5 N) H6 Z, X(6)在1.c文件中输入以下内容:
0 s2 K' p9 q4 Q$ b 13.png
2 I+ L2 {* k' \! l       注:实验中,按键一端接GND,LED一端接VCC,所以按键是检测到0代表按下,端口输出低电平代表LED点亮。- \; k+ T1 \2 E' T. j. f
! u* |1 g4 a( f- p5 [* n, N
9 u- w1 X: U: N6 R  {2 \
5.4 CM3内核的位带操作
; I6 H( G# t7 @5 E9 z- ?# b6 k       Cortex-M3内核中有一个非常有用的功能,叫做位带操作,支持了位带操作以后,可以使用普通的加载/存储指令来对单一的比特进行读写。在CM3中,有两个区中实现了位带。其中一个是SRAM区的最低1MB范围,第二个则是片内外设区的最低1MB范围。这两个区中的地址除了可以像普通的RAM一样使用外,它们还都有自己的“位带别名区”,位带别名区把每个比特膨胀成一个32位的字。当你通过位带别名区访问这些字时,就可以达到访问原始比特的目的。下图从另一个侧面演示比特的膨胀对应关系。
3 L; E- v0 F! \% A- q; k' g 14.png
" p0 c4 x, v# }& V+ d' [4 q5 L! S欲设置地址0x20000000中的比特2,则使用位带操作的设置过程如下图所示。
4 j/ T- _# ^) n# |3 Y5 ]4 @6 e 15.png " |8 L3 h( X( M6 ?  w6 d6 f8 b
    30年前其实就已经有位带操作的概念了,自8051单片机开始,到现在的CM3内核,位带操作有什么优越性呢?最容易想到的就是通过GPIO的管脚来单独控制每盏LED的点亮与熄灭。另一方面,也对操作串行接口器件提供了很大的方便(典型如74HC165,CD4094)。位带操作使代码更简洁,这只是位带操作优越性的初等体现,位带操作还有一个重要的好处是在务中,用于实现共享资源在任务间的“互锁”访问。多任务的共享资源必须满足一次只有一个任务访问它——亦即所谓的“原子操作”。
/ y, M+ G3 h+ t/ [0 L; b; H4 {; U7 q) E2 j, R7 J0 _) m% |  h

  @& X1 w" A/ z5.5 利用位带操作实现GPIO的输入与输出$ {5 m+ W2 w" p4 N
现在利用位带操作来实现上一题目中的功能。
1 Y3 b6 a; y$ G0 _+ E
$ F/ P5 k  p3 l' w0 r2 p

3 G2 r1 T" f! G, N! a(1)在sys.h文件中添加实现位带操作的代码。
! i% A( s7 A, @, n  b0 w 16.png   p+ E& K$ L3 w, ?7 n6 p
(2)修改gpio.h中的代码如下图所示。' }; C& |( Y$ ?: @  k/ u
17.png
9 W; V" c  V5 S" r$ \3 E(3)修改gpio.c中的代码如下图所示。
0 G7 x  z5 d% k( B7 B 18.png : _, C2 R) L' o2 z6 d% P
(4)修改1.c中的代码如下图所示。/ P0 D3 }$ N( _2 F
19.png , N7 Q, G( J8 c) N( ~6 F
5.6 外部中断的实现
5 o' E' N  v. j: w    关于STM32F103的中断机制在之前已经详细讲述过,现在利用外部中断来实现上一题目的功能。- {( U1 Y% o+ P9 A
! C/ I3 i3 p& E* X9 Y

2 j% i) }. i# V, h9 e  X% M7 j(1)修改gpio.c中的代码如下图所示。
  X9 z- H0 e+ t/ A: w4 o- h 20.png
" F8 c3 P; w% U% U& C$ x# m(2)添加代码到文件stm32f103.h中。' R: g& h2 T2 j, O, Q) u9 O& ~
21.png
. D& G* T, s& a( c1 [( k) Z(3)修改1.c中的代码如下图所示。$ p9 a  v3 ^0 k
0 g* L) L5 n" D* N; @0 w' V0 s
22.png
: v1 l$ o1 l  K- Y
$ s$ @0 Q& F4 Z& C0 n上一篇:/ \; Z( @7 r9 L8 J5 N# E. i
STM32学习笔记04—SysTick时钟; n+ {1 g( V- c3 ^6 N& V! h
' l/ x6 T, p; D! ^+ u: c+ O$ l2 R
赞 收藏 2 评论0 发布时间:2020-10-27 14:55

举报

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