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

嵌入式学习—STM32 通用IO

[复制链接]
STMCU小助手 发布时间:2022-12-13 17:00
每个通用 I/O 端口包括 4 个 32 位配置寄存器(GPIOx_MODER、 GPIOx_OTYPER、. s) H, C( R5 F  v" y$ O! G
GPIOx_OSPEEDR 和 GPIOx_PUPDR)、 2 个 32 位数据寄存器(GPIOx_IDR 和7 d8 i1 c- Z" Y6 y( ~
GPIOx_ODR)、 1 个 32 位置位/复位寄存器 (GPIOx_BSRR)、 1 个 32 位锁定寄存器+ _2 g' t: A( x1 r! A7 y  W
(GPIOx_LCKR) 和 2 个 32 位复用功能选择寄存器(GPIOx_AFRH 和 GPIOx_AFRL)
GPIO主要特性:
  • 输出状态:推挽或开漏+上拉/下拉
  • 从输出数据寄存器(GPIOx_ODR)或外设(复用功能输出)输出数据
  • 可为每个IO选择不同的速度
  • 输入状态:浮空、上拉、下拉、模拟
  • 将数据输入到输入数据寄存器(GPIOx_IDR)或外设(复用功能输入)
  • 置位和复位寄存器(GPIOx_BSRR),对GPIOx_ODR具有按位写权限
  • 锁定机制(GPIOx_LCKR),可冻结IO配置
  • 模拟功能
  • 复用功能输入/输出选择寄存器(一个IO最多可以具有16个复用功能)
  • 快读翻转,每次翻转最快只需要两个时钟周期
  • 引用复用非常灵活,允许将IO引脚用作GPIO或多种外设功能中的一种

    4 Q: W' z$ O/ p5 Y$ _# _& d/ Q

+ T1 G  ]" v& j
640 (23).png
/ u0 E; Y0 }! q* f: o7 f
注意:在复位期间及复位刚刚完成后,复用功能尚未激活,IO端口被配置为输入浮空模式。复位后,调试引脚处于复用功能的上拉/下拉状态。
; o6 p/ x/ R8 U0 ^! [' s( v
● PA15:JTDI 处于上拉状态
3 i4 c6 t( Y1 c+ o. E, D● PA14:JTCK/SWCLK 处于下拉状态
7 _0 }& y! H. D# B● PA13:JTMS/SWDAT 处于下拉状态
1 u. m9 o% A  k, Y  X$ u● PB4:NJTRST 处于上拉状态
* h5 W/ @/ _& z3 S9 ?8 o5 v● PB3:JTDO 处于浮空状态
当引脚配置为输出后,写入到输出数据寄存器 (GPIOx_ODR) 的值将在 I/O 引脚上输出。可以在推挽模式下或开漏模式下使用输出驱动器(输出 0 时仅激活 N-MOS)。
1 e8 D' i. M9 M2 K3 z  o. i输入数据寄存器 (GPIOx_IDR) 每隔 1 个 AHB1 时钟周期捕获一次 I/O 引脚的数据。
% |$ k  S7 M* D; M所有 GPIO 引脚都具有内部弱上拉及下拉电阻,可根据 GPIOx_PUPDR 寄存器中的值来打开/关闭。
I/O 引脚复用器和映射1 J* F) [$ a& [' ~+ b
微控制器 I/O 引脚通过一个复用器连接到板载外设/模块,该复用器一次仅允许一个外设的复3 z+ ~" B1 V: L* n5 H" `
用功能 (AF) 连接到 I/O 引脚。这可以确保共用同一个 I/O 引脚的外设之间不会发生冲突。
. _3 a/ H' h; }每个 I/O 引脚都有一个复用器,该复用器采用 16 路复用功能输入(AF0 到 AF15) ,可通过
& D+ p7 S( R) I) P" c8 fGPIOx_AFRL(针对引脚 0 到 7)和 GPIOx_AFRH(针对引脚 8 到 15)寄存器对这些输入
: K% v& {* u/ ~  m8 q进行配置:
% F2 U/ d( D7 [; J! |) ^● 完成复位后,所有 I/O 都会连接到系统的复用功能 0 (AF0)。
! h- V# q$ Q$ M) {● 外设的复用功能映射到 AF1 至 AF13。  r1 [0 W2 W$ z/ H& K
● Cortex™-M4F EVENTOUT 映射到 AF15 。8 c9 T8 ~  F2 Z2 j
要将 I/O 配制成所需功能,请按照以下步骤操作:
: C" i5 b2 X. [+ g! \* t9 _1. 系统功能# }% L9 Y; J, b( L' y
将 I/O 连接到 AF0,然后根据所用功能进行配置:
* H/ A- y* \. ?) @5 D— JTAG/SWD:在各器件复位后,会将这些引脚指定为专用引脚,可供片上调试模块
- w* }7 G+ F; P) W立即使用(不受 GPIO 控制器控制)。. t+ {# U1 G; q9 D/ w; {
— RTC_REFIN:此引脚应配置为输入浮空模式。
3 v5 Z5 i; p- V) G1 L— MCO1 和 MCO2:这些引脚必须配置为复用功能模式。
可禁止部分或全部 JTAG/SWD 引脚,以释放相关联的引脚供 GPIO 使用* J4 ?, v6 S% S6 c7 x) z+ Z1 C
% L9 s4 J; {, d7 Z7 t
640 (22).png
1 k  `% R5 d5 g5 `" r8 E7 u
2. GPIO+ X6 m" m7 r9 j4 _6 c% K. P& u
在 GPIOx_MODER 寄存器中将所需 I/O 配置为输出或输入。6 e' @8 g0 A% o/ `. C. f
3. 外设复用功能
# V# P! w+ U! ~: e对于 ADC 和 DAC,在 GPIOx_MODER 寄存器中将所需 I/O 配置为模拟通道。6 e: H, k+ G) i6 `5 f( N7 h7 B% \9 o
对于其它外设:
% y9 e% u* n. M— 在 GPIOx_MODER 寄存器中将所需 I/O 配置为复用功能5 L& @" x* _# v) Y! H
— 通过 GPIOx_OTYPER、 GPIOx_PUPDR 和 GPIOx_OSPEEDER 寄存器,分别选
* V) I, W" ?$ }; _择类型、上拉/下拉以及输出速度
% f' v% j6 l2 Q7 q$ u8 ?— 在 GPIOx_AFRL 或 GPIOx_AFRH 寄存器中,将 I/O 连接到所需 AFx. z2 k+ l! N" L- O" s
4.EVENTOUT
: q( U2 w; q+ \配置用于输出 Cortex™-M4F EVENTOUT 信号的 I/O 引脚(通过将其连接到 AF15)

# Q& q. t9 B  |6 K
640 (21).png

, b! X4 l) n2 S9 i  l: {% Z
I/O 端口控制寄存器
* F: `8 M$ g  Y1 P每个 GPIO 有 4 个 32 位存储器映射的控制寄存器(GPIOx_MODER、 GPIOx_OTYPER、
5 G' V3 F4 @( `# F. d) c( gGPIOx_OSPEEDR、 GPIOx_PUPDR),可配置多达 16 个 I/O。GPIOx_MODER 寄存器用于  j9 B$ r! `6 C7 O
选择 I/O 方向(输入、输出、 AF、模拟)。GPIOx_OTYPER 和 GPIOx_OSPEEDR 寄存器分
7 V' w/ f' \0 O8 B别用于选择输出类型(推挽或开漏)和速度 (无论采用哪种 I/O 方向,都会直接将 I/O 速度引
# Z* M2 u( `+ M' \5 Z: J) ?脚连接到相应的 GPIOx_OSPEEDR 寄存器位)。无论采用哪种 I/O 方向, GPIOx_PUPDR 寄
3 ^$ V  j3 }7 k, m存器都用于选择上拉/下拉。- _9 y3 _9 @+ F( o% x: r
I/O 端口数据寄存器4 a' W% \8 d+ \: {& U4 n8 y! Q
每个 GPIO 都具有 2 个 16 位数据寄存器:输入和输出数据寄存器(GPIOx_IDR 和; z' r1 a, ?2 _$ Z" Z: t  A
GPIOx_ODR)。GPIOx_ODR 用于存储待输出数据,可对其进行读/写访问。通过 I/O 输入# e( \; r, m* e- i$ m9 Z
的数据存储到输入数据寄存器 (GPIOx_IDR) 中,它是一个只读寄存器。
5 {+ k. \6 n/ i3 O' t3 n9 k
I/O 复用功能输入/输出
( b) F8 b% S" B6 J有两个寄存器可用来从每个 I/O 可用的 16 个复用功能输入/输出中进行选择。借助这些寄存
) Z/ L; l: s4 ^( E- f1 d, l3 D6 H器,可根据应用程序的要求将某个复用功能连接到其它某个引脚。
) c7 E8 d) C4 J6 B+ A6 Y2 c/ y6 _这意味着可使用 GPIOx_AFRL 和 GPIOx_AFRH 复用功能寄存器在每个 GPIO 上复用多个可, }: d' q5 d3 e/ i3 }1 d1 A
用的外设功能。这样一来,应用程序可为每个 I/O 选择任何一个可用功能。由于 AF 选择信# ?9 e# G* ?, e3 V- l' r0 ]
号由复用功能输入和复用功能输出共用,所以只需为每个 I/O 的复用功能输入/输出选择一个
" s% Y( ?1 X+ Z2 v通道即可。
8 l) P7 C; T) Q1 p  u
输入配置
) |5 @  T  W8 K! Y9 D* u( ]8 i对 I/O 端口进行编程作为输入时:6 ^) [# X; X! i4 Z1 U
● 输出缓冲器被关闭
, I+ W6 W( ~- R- p; L8 R  ?● 施密特触发器输入被打开1 m) {3 J. p9 [" H9 z7 o
● 根据 GPIOx_PUPDR 寄存器中的值决定是否打开上拉和下拉电阻. C9 r/ C% F, f8 B3 q) s6 ~
● 输入数据寄存器每隔 1 个 AHB1 时钟周期对 I/O 引脚上的数据进行一次采样
* U( J5 J) Q! V5 ^$ m" l● 对输入数据寄存器的读访问可获取 I/O 状态
  }  d3 J1 E, y- j* q

; q  C5 g! r7 i. a% R
640 (19).png

. S$ v' O. q( P/ o% d
输出配置
6 S" ]; }. C2 W( U' c# S对 I/O 端口进行编程作为输出时:
9 G! |; N) z/ J5 T& N; y6 ~● 输出缓冲器被打开:* C% @$ V- X8 v8 I; S5 z
— 开漏模式:输出寄存器中的“0”可激活 N-MOS,而输出寄存器中的“1”会使端
! _" I# [4 i" t/ E" A口保持高组态 (Hi-Z)(P-MOS 始终不激活)。# M3 _  ^% [$ x1 \# S
— 推挽模式:输出寄存器中的“0”可激活 N-MOS,而输出寄存器中的“1”可激活
  P% r( Q8 S4 CP-MOS。! ?, [: `3 \) w3 ?
● 施密特触发器输入被打开
. H  ?: U; f2 z* y$ m5 y● 根据 GPIOx_PUPDR 寄存器中的值决定是否打开弱上拉电阻和下拉电阻( }2 I+ b2 b5 ?
● 输入数据寄存器每隔 1 个 AHB1 时钟周期对 I/O 引脚上的数据进行一次采样
- u8 X- g) B; M+ ]; S* o& T● 对输入数据寄存器的读访问可获取 I/O 状态
! m7 r' X# P1 C/ [4 {, S' S1 W● 对输出数据寄存器的读访问可获取最后的写入值

" }8 U; |" ?+ n, j7 s6 {+ [- H; ~, W6 i
640 (18).png

' }2 s1 C: i0 _1 m: D( W4 a
复用功能配置
/ g1 I  i0 x9 z对 I/O 端口进行编程作为复用功能时:
% t5 p* N2 h4 i' P! s$ q● 可将输出缓冲器配置为开漏或推挽
  V" f) R1 O1 b& I) Y$ |● 输出缓冲器由来自外设的信号驱动(发送器使能和数据)5 O! S5 d( O! V* T7 D
● 施密特触发器输入被打开
, y$ J3 j/ k3 p! \# F+ R9 e) q● 根据 GPIOx_PUPDR 寄存器中的值决定是否打开弱上拉电阻和下拉电阻3 b1 C+ t. N  b  m
● 输入数据寄存器每隔 1 个 AHB1 时钟周期对 I/O 引脚上的数据进行一次采样2 u! l( F' O$ u% P% w: ^1 _  n
● 对输入数据寄存器的读访问可获取 I/O 状态

$ T' M  Q) W( R/ f2 b3 V, h
640 (17).png

5 }. _% ~4 V& C5 M+ }
模拟配置
1 u$ t, M! J6 A& d8 R; z1 t对 I/O 端口进行编程作为模拟配置时:% j* B; l, E0 g9 d$ a
● 输出缓冲器被禁止。4 v1 c* e$ b! f5 d  X' q. x
● 施密特触发器输入停用, I/O 引脚的每个模拟输入的功耗变为零。施密特触发器的输出被
6 L0 W" p/ M. d! _" ~9 i( S强制处理为恒定值 (0)。
8 p; Q: U6 N, t3 N2 I, C● 弱上拉和下拉电阻被关闭。
# T! S$ p0 ^  n0 z● 对输入数据寄存器的读访问值为“0”。6 s5 H* A7 t# S$ ]7 K

6 D$ r/ C0 M5 `% W& U, V
640 (16).png
( y. L! s+ f) ]2 S) P" f1 B. D7 d/ C
将 OSC32_IN/OSC32_OUT 引脚用作 GPIO PC14/PC15 端口引脚4 {; C5 n9 v: Y) K* q
当 LSE 振荡器处于关闭状态时,可分别将 LSE 振荡器引脚 OSC32_IN 和 OSC32_OUT 用5 d9 D# Q; ~/ ^+ D! R6 @! U- ]: i
作通用 PC14 I/O 和 PC15 I/O。当 LSE 振荡器处于开启状态时, PC14 I/O 和 PC15 I/O 只能( e2 d# k  E1 e1 p/ b
被配置为 LSE 振荡器引脚 OSC32_IN 和 OSC32_OUT。可通过在 RCC_BDCR 寄存器中将" U7 m* ~% m& y$ e, A' G
LSEON 位置 1 来完成此操作。LSE 的优先级高于 GPIO 功能。
; b- V$ N$ S6 n1 f7 ~注意:当 1.2 V 域掉电时(因器件进入待机模式),或者当备份域由 VBAT 供电时(VDD 不再供电),PC14/PC15 GPIO 功能将丢失。在此情况下, I/O 被设置为模拟输入模式。
将 OSC_IN/OSC_OUT 引脚用作 GPIO PH0/PH1 端口引脚$ f' R' }4 W( F) v% ^
当 HSE 振荡器处于关闭状态时,可分别将 HSE 振荡器引脚 OSC_IN 和 OSC_OUT 用作通
  g( p5 G/ e! ], o) X: d/ l用 PH0 I/O 和 PH1 I/O。(完成复位后, HSE 振荡器处于关闭状态)。当 HSE 振荡器处于
. l& S9 b2 B3 H" v3 X7 ^  d/ `开启状态时, PH0/PH1 I/O 只能被配置为 OSC_IN/OSC_OUT HSE 振荡器引脚。可通过在
6 V9 [" k1 N" N/ h, Y7 yRCC_CR 寄存器中将 HSEON 位置 1 来完成此操作。HSE 的优先级高于 GPIO 功能。1 c4 K8 R: W) j3 O

- g1 ]" g$ c, E9 _1 M
640 (24).png
640 (12).png
/ Z- e- S7 V. V9 f* J
640 (25).png
640 (14).png
640 (26).png
2 V7 O' {! p+ G$ v
640 (13).png
5 [% s  U; o, U2 c& y4 E  B
640 (11).png
640 (27).png
640 (28).png

) ~: h- X. z* M, v. a+ f2 t
640 (29).png
640 (9).png
9 h2 ~, O! ~3 \& n5 e/ M9 O) P) _
640 (30).png
640 (8).png

) h* D- ~8 r6 K8 ]& p
640 (31).png
640 (7).png

$ ?$ D& O1 ?4 I2 E9 W1 @/ w
640 (32).png
0 [4 ?8 |, n* |' v5 \
640 (6).png
640 (5).png
) |  r% V) E0 v7 i: h
640 (33).png
640 (4).png

; T( l2 I+ v  g
640 (34).png
640 (3).png

) w7 a) s8 {( w! B2 b0 C: o/ C4 h
GPIO配置方法:
第一步,使能IO口时钟,配置相关寄存器RCC->AHB1ENR
1 e  X" C2 x, J5 ~
第二步,初始化IO口模式,配置四个配置寄存器
GPIOx_MODER/GPIOx_OTYPER/GPIOx_OSPEEDR/GPIOx_PUPDR
第三步,操作IO口,输入高低电平,配置寄存器GPIOx_ODR或者BSRRL/BSRRH。
7 B$ ?% {3 x# O" M3 d$ P
//GPIO复用设置
//GPIOx:GPIOA~GPIOI.
//BITx:0~15,代表IO引脚编号.
//AFx:0~15,代表AF0~AF15.

7 o& J4 k! R7 o8 F/ _/ ?8 d
640 (35).png

8 Q" w$ s. s( G# h2 q1 X( R+ g: B
1 I! @) R' `( c/ k! q0 h
void GPIO_AF_Set(GPIO_TypeDef* GPIOx,u8 BITx,u8 AFx)
{  
        GPIOx->AFR[BITx>>3]&=~(0X0F<<((BITx&0X07)*4));
        GPIOx->AFR[BITx>>3]|=(u32)AFx<<((BITx&0X07)*4);
}   
//GPIO通用设置
//GPIOx:GPIOA~GPIOI.
//BITx:0X0000~0XFFFF,位设置,每个位代表一个IO,第0位代表Px0,第1位代表Px1,依次类推.比如0X0101,代表同时设置Px0和Px8.
//MODE:0~3;模式选择,0,输入(系统复位默认状态);1,普通输出;2,复用功能;3,模拟输入.
//OTYPE:0/1;输出类型选择,0,推挽输出;1,开漏输出.
//OSPEED:0~3;输出速度设置,0,2Mhz;1,25Mhz;2,50Mhz;3,100Mh.
//PUPD:0~3:上下拉设置,0,不带上下拉;1,上拉;2,下拉;3,保留.
//注意:在输入模式(普通输入/模拟输入)下,OTYPE和OSPEED参数无效!!
void GPIO_Set(GPIO_TypeDef* GPIOx,u32 BITx,u32 MODE,u32 OTYPE,u32 OSPEED,u32 PUPD)
{  
        u32 pinpos=0,pos=0,curpin=0;
        for(pinpos=0;pinpos<16;pinpos++)
        {
                pos=1<<pinpos;        //一个个位检查
                curpin=BITx&pos;//检查引脚是否要设置
                if(curpin==pos)        //需要设置
                {
                        GPIOx->MODER&=~(3<<(pinpos*2));        //先清除原来的设置
                        GPIOx->MODER|=MODE<<(pinpos*2);        //设置新的模式
                        if((MODE==0X01)||(MODE==0X02))        //如果是输出模式/复用功能模式
                        {  
                                GPIOx->OSPEEDR&=~(3<<(pinpos*2));        //清除原来的设置
                                GPIOx->OSPEEDR|=(OSPEED<<(pinpos*2));//设置新的速度值  
                                GPIOx->OTYPER&=~(1<<pinpos) ;                //清除原来的设置
                                GPIOx->OTYPER|=OTYPE<<pinpos;                //设置新的输出模式
                        }  
                        GPIOx->PUPDR&=~(3<<(pinpos*2));        //先清除原来的设置
                        GPIOx->PUPDR|=PUPD<<(pinpos*2);        //设置新的上下拉
                }
        }
}
640.png
  T! L$ ^7 P/ Q/ J# b. f
赞 收藏 评论0 发布时间:2022-12-13 17:00

举报

0个回答

所属标签

相似技术帖

官网相关资源

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