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

【经验分享】STM32F0xx之IO口控制(寄存器方式)

[复制链接]
STMCU小助手 发布时间:2021-11-25 15:00
STM32F0xx的IO口定义方式与STM32F10x类似,一组GPIO包含16个IO。每组GPIO同样用GPIO_TypeDef的结构指向对应的寄存器空间。% |. W$ E- O2 s1 w' x7 \/ G( A

7 X$ v4 I: \9 Z8 ~5 Z* f' a
  1. <blockquote>#define GPIOA               ((GPIO_TypeDef *) GPIOA_BASE)
复制代码
! @, Q9 J2 w' Z/ l; `
但是寄存器空间与STM32F10x的不同。& j% F0 W7 B: a5 b) h
  1. <blockquote>typedef struct
复制代码

! T% L. s6 [7 `4 C* y1. 使能GPIO的RCC
# l( a5 A# ?5 h& r% fRCC->AHBENR |= RCC_AHBPeriph_GPIOn# [7 m! W+ ^& t' ?/ r( l0 [

8 m/ {, [! l% x其中n的范围为A-F。
3 z# k5 L# H: E: Z9 t' h
' [6 d& W, X: `2 N. S如果涉及到复用,与STM32F10x不同,这里用寄存器AFR[2]来设定复用。每个IO用4bit来选择复用功能,最多有8种复用。4 {! V( p! U( L8 Q+ O
% q0 ?8 U3 @! i6 M9 x3 Y) R
20210603162156418.png
9 e- R$ Y4 ?7 {! p+ b5 L
例如GPIOA9,GPIOA10的AFR设定:
$ z+ ]% Q* C% h" C2 B6 |
% G. R: I- e9 |" m
  1. *((uint32_t *)GPIOA->AFR + ((9 / 8))) &= ~(0x0000000F << ((9 % 8) * 4));
    ' e% F4 M; j" a: I9 g
  2. *((uint32_t *)GPIOA->AFR + ((9 / 8))) |= (0x00000001 << ((9 % 8) * 4));  1 }$ }; N8 k; Q- k, p
  3. *((uint32_t *)GPIOA->AFR + ((10 / 8))) &= ~(0x0000000F << ((10 % 8) * 4));  m# K2 T1 B0 w: `3 v! a1 v
  4. *((uint32_t *)GPIOA->AFR + ((10 / 8))) |= (0x00000001 << ((10 % 8) * 4));  
复制代码

7 @; C/ _% j$ [2 v0 I% G2. 配置GPIO# D( e+ W1 t' e! P! H
2.1 设置输出频率(OSPEEDR)) H& A/ H4 ^$ A6 _

2 |3 C3 e! }( @( Q
20210603171958361.png
  T/ R+ q' J( s$ o6 X! d+ S, z

4 x2 ]( M& G0 {+ I! s% T7 S" }* n' H每2个位配置一个Pin。默认是2MHz。
: m. K7 u: X# U8 ~& w3 O' s
: u8 n$ V1 N# c. ]0b00, 0b10: 2MHz" m! o: z) }0 c. d, F2 [
" P- t# ]9 \  W6 T8 i/ x3 V
0b10: 10MHz5 I/ [& A3 I$ W- n7 D7 v$ w+ w

8 K& G$ s/ v2 {( T- J0b11: 50MHz
+ B& |9 L. ?2 H# l# ]/ s0 ]* W/ B+ F$ h: {* h! R* B
  1. typedef enum
    " _3 Y$ D! T# @5 y& L0 b& Z
  2. {
    8 ^3 e7 U8 P/ Z" t& y- T3 ?& i
  3.   GPIO_Speed_Level_1  = 0x00, /*!< I/O output speed: Low 2 MHz */) h* K7 Z) B& A, Y" G+ b  M
  4.   GPIO_Speed_Level_2  = 0x01, /*!< I/O output speed: Medium 10 MHz */! q6 `! n3 T4 j/ I6 U
  5.   GPIO_Speed_Level_3  = 0x03  /*!< I/O output speed: High 50 MHz */
    5 V1 R0 K& \, \0 r
  6. }GPIOSpeed_TypeDef;; t# _  J% f& x# J

  7. + b+ R+ v* c! j) e, O
  8. #define GPIO_Speed_2MHz  GPIO_Speed_Level_1   /*!< I/O output speed: Low 2 MHz  */$ u9 u' L# w- S( ^; w& l
  9. #define GPIO_Speed_10MHz GPIO_Speed_Level_2   /*!< I/O output speed: Medium 10 MHz */5 X8 e& N+ P) z& z2 p1 d
  10. #define GPIO_Speed_50MHz GPIO_Speed_Level_3   /*!< I/O output speed: High 50 MHz */
复制代码

. h5 N" K- K3 L' p* D例如A9、A10都为50MHz:
; Y2 _" H5 v+ H, j2 u
1 M& W) B2 f6 q8 z9 N
  1. GPIOA->OSPEEDR |= (0x0000000F << (9 * 2));
复制代码
: [5 r  t6 W. Q, G* x$ F7 }2 A
2.2 配置输入输出(MODER)' \9 A( G9 m4 m$ \6 d6 l4 \* R' R
4 |" w  p7 o4 f1 w

' Y" x* ]% y: M& T8 b$ P5 F8 H
! g+ I2 ?, a8 x- w/ `每2个位配置一个Pin。 默认Input(除了SWD的A13,A14)0 {2 D* o* e/ G. P' a* n8 c

. V, o9 H* C: q  ~" N3 }' P0b00: Input
# [' y4 m) H" Q2 t) c2 J
* M7 q( m8 s9 |, `# @0b01: Output; x5 s4 F1 A- J. V

( ?  J0 H6 X- e" _4 r/ [3 t0b10: AF
9 ]( ?( k( k0 _. o7 c$ _6 ^! h/ n  U, v& E- v. D1 Q
0b11: Analog In/Out( z- V$ ^3 L& ?' f- h# _

+ e& D; _) a' {* @
  1. typedef enum
    - [" R% t9 v) i% O( O& u
  2. {
    5 d3 t+ `2 n) w7 X5 ^4 N* V
  3.   GPIO_Mode_IN   = 0x00, /*!< GPIO Input Mode              */1 n2 n3 v0 g- q) V3 p: n. F: H
  4.   GPIO_Mode_OUT  = 0x01, /*!< GPIO Output Mode             */5 l' B8 T9 b: M
  5.   GPIO_Mode_AF   = 0x02, /*!< GPIO Alternate function Mode */
      k. j# R8 F) N" k" Q3 h
  6.   GPIO_Mode_AN   = 0x03  /*!< GPIO Analog In/Out Mode      */) B5 i; Q, X+ _7 Z
  7. }GPIOMode_TypeDef;
复制代码
6 U, C! M1 t5 X) F9 j8 r- J' Q1 j9 h
例如GPIOA9,GPIOA10为AF:
. K. f) O& I; X  z9 @/ {
  1. GPIOA->MODER |= ((uint32_t)GPIO_Mode_AF << (9 * 2)) | ((uint32_t)GPIO_Mode_AF << (10 * 2));
复制代码
8 z8 L: Y7 _4 f2 r( F* d8 K7 c
2.3 配置输出模式(OTYPER)) Z: }( @) ]: O9 B% J' B

& @% J2 g+ s8 m" B# F* U
20210604084327134.png

, S. O. ]) ], N: n, _
  W, @1 m9 B* s: v* I# K每个bit表示输出模式,
" V7 }: y  N' @* H' }
: i/ \; r% H% ^5 a0b0: PP模式;
5 G4 ]) K8 H. W
& V) U! F: E0 b. Q9 U# A0b1: OD模式。 , T0 T+ b& P% {6 i# X% A8 |" {
0 R4 e0 F* q4 C! R2 [$ X9 b/ c* y' V
  1. typedef enum
    ' Y2 _5 X/ N4 ~0 p3 b8 Q' k
  2. {, i# D5 w1 c) W. `; A+ w
  3.   GPIO_OType_PP = 0x00,3 g5 |7 e$ ^: V1 Z+ `' v) |3 e5 o
  4.   GPIO_OType_OD = 0x01
    / i& K) Y! f2 L2 H5 M
  5. }GPIOOType_TypeDef;
复制代码
) i0 T% Q9 i" |8 Q4 A
例如:
) u( v% J8 {+ L, P% H
  1. GPIOA->OTYPER |= (((uint32_t)GPIO_OType_PP << (9 * 1))
    * o& v; d. F8 V: Y( E
  2.     | ((uint32_t)GPIO_OType_PP << 10 * 1))
复制代码
  Z, x) l# R  k; |7 V* j
2.4 配置上下拉模式(PUPDR)' M+ X; b7 r4 }- y4 s$ t( s+ Q  H

' `% A5 z3 ]. S5 r) `) G: U
20210604085305353.png
: a: R0 ]9 D; }( |4 _- w5 N0 A

& |: p7 ^& I3 y( M4 @7 s% n% |每2个位表示上下拉模式。- g; X& Z' j* \1 R. u3 h1 Q
  1. typedef enum
    : {* o9 M6 Q$ h% o1 c5 Y
  2. {% e* Q% u( g) q/ i5 J
  3.   GPIO_PuPd_NOPULL = 0x00,
    & ^8 D  v+ q2 c* C
  4.   GPIO_PuPd_UP     = 0x01,
    # e5 ~7 \/ K2 e
  5.   GPIO_PuPd_DOWN   = 0x02
    + @& E* M* ?: m8 K3 B% k% p& f
  6. }GPIOPuPd_TypeDef;
复制代码
0 h. \! y8 L. E9 w0 c2 z2 j
例如:+ `+ s9 C) a& `$ ?' K6 ^
  1. GPIOA->PUPDR &= ~((0x00000003 << (9 * 2)) | (0x00000003 << (10 * 2)));
复制代码
; |, S8 Y' C3 w, F$ b* U
3. 输出
, S* W: w/ I+ L" a' K8 ]- P( b输出电平通过寄存器BSRR(输出高电平和低电平)和BRR(输出低电平)实现,写入1表示对应操作,写入0无效。例如:
2 V/ c# L4 m) S& D. [6 N3 Z& a
+ f/ V9 {' \9 `; j9 {" k$ t
  1. #define SDA_HIGH(n)                 IO_I2CIO_SDA->BSRR = ((uint32_t)1 << PIN_I2CIO_SDA)
    # s5 U5 q& |$ A6 O* p
  2. #define SDA_LOW(n)                  IO_I2CIO_SDA->BRR = ((uint32_t)1 << PIN_I2CIO_SDA)
复制代码

9 D7 H, `9 @' b( |; {+ M6 P BSRR的低16位分别对应16个PIN的输出高电平操作,高16为对应输出低电平操作。
# g; O& U$ U# Q* K$ Q
# Q6 o% |8 s0 s7 I+ u; k0 q; I而BRR只有低16位有效,对应对应输出低电平操作。" g& Z6 H7 g$ _  x' h: J

- `: b1 w* [8 e' u9 u) A9 s( J8bit总线输出6 g: u$ P2 R: r" f* W7 [- @
4 l6 _5 d3 }0 R0 m
  1. #define I8080_D8_OUT(dat)           IO_I8080_D8->BSRR = (dat & 0xff) | ((uint32)((~dat) & 0xff) << 16)
复制代码
4. 读入IO
7 V7 ]: u2 b% v/ k0 ^$ l% s1 N通过寄存器IDR读出对应I/O口的状态。低16位有效。" e8 C+ ^2 x  w% j  d  R' S5 y' i& S
' T+ C1 o$ H5 N" D+ q
  1. #define SDA_READ(n)                 (IO_I2CIO_SDA->IDR & ((uint32_t)1 << PIN_I2CIO_SDA))
复制代码

( }% s( E8 v6 ^& J* b
' I8 m1 U- {2 m6 Z2 r; N- b$ Y+ }
20210603165224704.png
收藏 评论0 发布时间:2021-11-25 15:00

举报

0个回答
关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32Cube扩展软件包
意法半导体边缘AI套件
ST - 理想汽车豪华SUV案例
ST意法半导体智能家居案例
STM32 ARM Cortex 32位微控制器
关注我们
st-img 微信公众号
st-img 手机版