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

基于STM32F4与STM32F1的复用功能配置库函数分享

[复制链接]
攻城狮Melo 发布时间:2023-5-17 17:34
F4的复用功能配置
: a$ B( |; _$ r) ~之前使用F429的时候算是知道了怎么配置它的复用功能,但是前天在用到F103的时候发现和自己想的不一样,查了一下资料发现完全不用,所以这里做一些记录方便以后查阅,先来介绍F4复用功能配置
* g7 v8 q* a3 B& |2 _3 U: W
# W6 f+ S7 O& {3 F3 i" A
20191021030304265.png # x& @) T. w7 }) q5 J4 x0 d* e
, l( `7 {' m1 k6 t7 C- N2 E
20191021030246902.png
2 E/ b) ]. e5 w& k+ T4 C* x
2 ?1 V6 [; `$ h) F
% t; P( F' S  l* @2 i  _* j; u3 R
F4的复用功能配置数据手册上说的非常清楚,F4的复用功能配置寄存器有两个,一个低位寄存器和一个高位寄存器,低位寄存器用来配置对应GPIO端口的前8个IO口,高位寄存器用来配置后8个IO口,每4个bit位对应一个IO口,所以每个IO口可以配置的复用功能为AF0-AF15,但不是说每个IO口上AF0到AF15所有的功能都有,上面第二张图片给出了AF0到AF15所对应的复用功能,具体每个IO口上有哪些复用功能可以去看数据手册的alternate function mapping部分,有详细说明。1 i# k/ g* h! @# q4 E5 ^8 Q& H' y* Y
- h" n. c, X' P/ L* E
3 e" t$ ^% Q( K
F1的复用功能配置
, l8 t9 N; H5 f3 N: X9 E5 I" v! t
* ^& |, i" l' |9 R( ]
20191021222322379.png
1 u$ |; b! ?8 Y8 C" K5 _. [

* M& x8 Y4 Z/ M下面来说下F1的复用功能配置,F1的复用功能不想F4那样,想用那个就配置那个,具有复用功能的IO口默认就只有一个复用功能,换句话来说就是,每个能复用的IO口上都具有默认的复用功能,没有F4那么多的选择,默认你就只能用这一个,只需要把IO口配置成复用模式然后开启相对应的外设时钟就可以了。F1某些引脚还具有重映射的功能,比如上图,PB6,PB7默认是I2C的时钟线和数据线,你使用I2C功能时只需要开启I2C1这个外设的时钟就可以使用了,但是你如果不想使用这个默认功能,这个引脚上还有一个USART1外设功能,你想使用这个外设就必须要配置AFIO_MAPR这个寄存器将USART1这个外设重映射到这两个引脚上这时你的I2C1这个外设就不能用了1 e9 S9 M0 N* Y; S1 i. c$ [

  q1 Z, ^  p! U: t
$ t; {- H8 l  J7 r# O0 K
F4库里面的复用功能配置函数
9 G" A8 [$ ^# U! d" [8 Y最好来说一下我对F4这个库里面的复用功能配置函数的理解,F1的库暂时还没研究过,不过感觉算法上应该都差不多吧
2 z; s/ I/ O4 v! e( Y: o$ m
  1. void GPIO_PinAFConfig(GPIO_TypeDef* GPIOx, uint16_t GPIO_PinSource, uint8_t GPIO_AF)3 M4 Q, \; C. h- f/ q- p/ f( f
  2. {! |0 T: T/ b1 _* P2 |3 i3 {" m
  3.   uint32_t temp = 0x00;
    . t' Q2 [/ s! D
  4.   uint32_t temp_2 = 0x00;/ \1 w2 h0 A5 ^! |
  5.   
    : l% P3 J# a+ j5 ~: P
  6.   /* Check the parameters */
    " B8 C1 v/ _/ v3 D2 Y
  7.   assert_param(IS_GPIO_ALL_PERIPH(GPIOx));
    $ G, u8 P/ k7 v  p
  8.   assert_param(IS_GPIO_PIN_SOURCE(GPIO_PinSource));, c! Q: z* w- r" z& }$ o
  9.   assert_param(IS_GPIO_AF(GPIO_AF));
    6 W- Q0 w3 N8 l" R. P
  10.   7 N& t7 G1 F4 p" F1 }: B
  11.   temp = ((uint32_t)(GPIO_AF) << ((uint32_t)((uint32_t)GPIO_PinSource & (uint32_t)0x07) * 4)) ;
    . ^3 p0 ^$ e) `2 y  F% A
  12.   GPIOx->AFR[GPIO_PinSource >> 0x03] &= ~((uint32_t)0xF << ((uint32_t)((uint32_t)GPIO_PinSource & (uint32_t)0x07) * 4)) ;8 A0 o: F+ H+ R, X: E
  13.   temp_2 = GPIOx->AFR[GPIO_PinSource >> 0x03] | temp;
    # `4 J' E3 p5 p/ Y
  14.   GPIOx->AFR[GPIO_PinSource >> 0x03] = temp_2;9 I7 q4 Z1 a# k. _5 b5 Z6 W+ \' @
  15. }
复制代码

6 ?+ Y+ h& v! }# b" s  ^1.GPIO_PinSource这个参数对应的是GPIO口0-15的编号. C0 q0 t/ Y8 v- d5 E4 p
2.temp = ((uint32_t)(GPIO_AF) << ((uint32_t)((uint32_t)GPIO_PinSource & (uint32_t)0x07) * 4)) ;
6 \/ U$ m$ K: b# T- a# r1 q8 E$ }这一句是将需要配置的AF值GPIO_AF(0-15)移位到对应的IO口的4bit位上,GPIO_PinSource & 0x07便可以算出需要移位的单位因为与0x07相与得到的都是0-7之间的数,因为大于0-7的倍数部分都与0相与了,得到的都是0-7整除之后的余数,比如:9的二进制展开是1001,7的二进制展开是0111,这里bit3位都是前三位的倍数,相与之后等于1,刚好对应。这个例子中是每4个bit对应一个IO,对应0-7,每次右移的单位都是4bit。所以在0111这4bit位中低三位可以用来确定在32位寄存器中的属于哪个位置,bit3位可以用来确定在那个寄存器组' G; `1 Z: w8 B5 V  ?" U8 V3 i
3.PIOx->AFR[GPIO_PinSource >> 0x03] &= ~((uint32_t)0xF << ((uint32_t)((uint32_t)GPIO_PinSource & (uint32_t)0x07) * 4)) ;GPIOx->AFR[GPIO_PinSource >> 0x03]这一句就是验证了上面的算GPIO_PinSource的值右移3个bit位后就只剩下bit3位的值,如果该位为0就是0组,为1就是1组,也就是对应这复用功能低位寄存器和复用功能高位寄存器,后面的和上面的一样,只是这里是将0xF移位到对应的位置然后取反清0
6 d! ?1 B7 o. R: J9 r# \& x4.temp_2 = GPIOx->AFR[GPIO_PinSource >> 0x03] | temp;这句表示将当前寄存器的值与上AF值移位后的值,然后保存在temp_2这个变量中
) s: H, z3 c5 h. _5.GPIOx->AFR[GPIO_PinSource >> 0x03] = temp_2;将最终计算出来在temp_2中的值写入寄存器中7 N6 }+ g- o0 n2 J0 X! c
————————————————
) @- ], R. E, ?6 F版权声明:天才布里茨. ]3 H6 n5 w0 M8 q
如有侵权请联系删除; R2 {% v1 x5 j& b- ]3 M
2 |- w$ H( j9 T  H

8 d% Y" U9 i+ p8 J
赞 收藏 评论0 发布时间:2023-5-17 17:34

举报

0个回答

所属标签

相似技术帖

官网相关资源

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