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

基于STM32F1模拟I2C通信中寄存器操作IO方向经验分享

[复制链接]
攻城狮Melo 发布时间:2023-5-22 20:00
  1. #define SDA_IN()  {GPIOB->CRL&=0X0FFFFFFF;GPIOB->CRL|=(u32)8<<28;}
    $ D1 e! p# P) x* u; D
  2. #define SDA_OUT() {GPIOB->CRL&=0X0FFFFFFF;GPIOB->CRL|=(u32)3<<28;}- r# N  y, S0 J/ m2 n2 ^# @
复制代码

* U( }  V+ k% b; p6 m: v
8 H" j; A& q- k& N4 ~; {- o对于我们学的STM32都是习惯性的调用库函数,操作GPIO直接对结构体成员直接赋值即可。学到I2C通信时,看到以上代码中突如其来的寄存器操作,对于我这个新手小白来说是一脸懵逼状态,经过一个下午的学习,也算是搞懂了GPIO寄存器操作。分享一下个人学结,有错误的地方欢迎各路大佬指正。  `$ m4 l( n/ e6 c

3 ?. C5 ]  m$ t0 r) @) b0 A
1 M# A) {9 m9 R) Y
1、所需基础知识回顾
% a4 c3 W. X9 x5 [4 U由参考手册可知,GPIO端口每个位可以由软件分别配置为:4 V3 r. W& ^9 h5 `
输入浮空5 J% V0 V3 H! I
输入上拉2 g5 g% a. W$ p' G0 R' L* }
输入下拉9 d6 M# M% p' Y/ ~
模拟输入& e. k4 ~' c  r4 ^" D
推挽式输出* [" i( D: I  r# U/ Y5 [
推挽式复用功能; Y0 x! a' X: q6 w
开漏复用功能$ \* S' E3 e$ w, Z
每个GPIO端口由七个寄存器来控制,分别为:8 |0 l: X4 N6 }( h5 w
端口配置低寄存器(GPIOx_CRL)& T+ l/ l5 L4 a6 A( K; q
端口配置高寄存器(GPIOx_CRH)
( k# N$ [8 V% p& B端口输入数据寄存器(GPIOx_IDR)# Z6 o5 s- g# j- i& F
端口输出数据寄存器(GPIOx_ODR)9 s/ Z; @, a  i. G- j
端口位设置/清除寄存器(GPIOx_BSRR)
) ]$ s0 w: Z' z. S% M端口位清除数据寄存器(GPIOx_BRR)
- e: T9 k" l& f' }* ?% n6 a端口配置锁定寄存器(GPIOx_LCKR)6 t* U( o4 `9 y" z! g6 \
注:其中GPIOx_CRL配置GPIOx_Pin0——GPIOx_Pin7引脚,GPIOx_CRH配置GPIOx_Pin8——GPIOx_Pin15引脚(这个必须要明白)6 I% h9 T6 n) S6 O3 g1 U

" L2 @" \0 p$ E5 A

0 K9 h3 V! |; j9 W; H逻辑运算5 W, F8 Q( v5 j; j5 }
左移运算
- M( _+ |  x9 X: e6 F% WValue << num
& r' J3 U, S! qnum:指定要移位值Value移动的位数$ h6 K* X% u1 o& j# U! |) P, @
丢弃最高位,0补在最低位
, m; {6 O- A% H0 @; R8 R# X左移一位相当于乘以2的1次方,左移n位相当于乘以2的n次方: c6 S* S4 `0 u4 Y
例如:8<<28,即:8向左移动28位3 D) T% ]/ b: q' E
与运算:1 & A = A ;可得出1跟任意数进行”与“运算不会改变其值
* p  `4 |9 i8 s6 {, N
STM32寄存器描述

; M4 R) y5 E; L, K, {6 qGPIOx_CRL寄存器,也就是低位寄存器。配置:Pin0—Pin7。图一如下:
: E5 ~2 T1 k" s- T! U% g! ~& s
+ _/ c. ?" r8 U4 J( `# q! o# a
8d0b99d571a841a0898e4f19d8fd4894.png - I# y* c. W- {) P' b! e# A5 f
) M3 f  p8 v; O! x8 ?# J( V
GPIOx_CRH寄存器,也就是高位寄存器.配置:Pin8—Pin15。图二如下:* D% \  E+ D* T8 r; R
; `1 `/ ^9 b3 E" k! i- H# Q
812f052b961547b4817ee64b743310f7.png
. c8 z/ g8 A6 |, O# A

( m& m6 p/ c; p' K也就是一个GPIOx端口分为GPIOx_CRL寄存器和GPIOx_CRH寄存器,其中MODE0[1:0]和CNF7[1:0]一起表示Pin0的配置值,以下依此类推,MODE7[1:0]和CNF7[1:0]一起表示Pin7的配置值。
: a, Q# X+ e" z
& |$ G7 f: A0 |2 m6 M
2、代码详解- A1 Q: I+ u9 g. Q( ?
对于文章开头提到的两个宏定义分开两条解释,SDA_IN()如下:2 I- ^" m+ D. W: n5 J& M% R7 o0 f
/ [2 S% Z9 g8 @9 C
#define SDA_IN()  {GPIOB->CRL&=0X0FFFFFFF;GPIOB->CRL|=(u32)8<<28;}3 Q2 m$ R' _5 q& ^( V
5 ^4 C9 b; U! j& d# [- |
其中GPIOB->CRL&=0X0FFFFFFF 等价于 (GPIOB->CRL) = (GPIOB->CRL) & 0X0FFFFFFF
$ N, R: M5 E$ W* k4 p  j含义为:由于上述提到的CRL为低位寄存器,意思是把GPIOB端口的CRL寄存器的28、29、30、31位清0,即将PB7中CNF7[1:0]和MODE[1:0]四位都置零。(这里应该还是蛮好理解的)1 a! d9 D# f: [( u

; Y4 h! _4 x! l5 g% b. s& W5 o
其中GPIOB->CRL|=(u32)8<<28等价于GPIOB->CRL = GPIOB->CRL | (u32)(8<<28)& H% S6 S: R0 [: u; B8 L
由于u32强制类型转换为32位,则8的二进制为:0000 0000 0000 0000 0000 0000 0000 1000
7 M1 ^! \/ x& z6 T7 p6 a7 K) m将8左移28位得:1000 0000 0000 0000 0000 0000 0000 0000
8 {+ O- K+ \5 Y! w/ E8 D4 a由左移之后的数据可知:将31、30、29、28位设置为1000。下面对上图中的CNF和MODE解析
0 m9 x" |! `2 S9 _' S9 B
0 a* l3 d8 K8 V& p0 \
即将PB的CRL寄存器中29和28位设置为00,由图一可知,其中29位MODE7[1]的值=0;28位MODE7[0]的值为0;图三如下:
3 _. x6 F7 F! ]' u- t$ f
% |. G( e& j6 t$ N  b* x
( Q. |- w1 m$ ^
57bdb75cf48a484d836d20a6a31f7923.png
2 }0 @9 V2 C9 T) y. B" X/ O' F4 Q$ l) e0 x, t, y
由上图得知:29:28位配置为00,由下表得知,MODE1和MODE0为00时为输入模式。图四如下:1 t2 C7 L" @, A- b0 x. h  {
4 h/ x9 y8 V8 ?" X' O

7 _' i) R4 V7 T. l6 k) e& V3 p baf0dd61a6b348b6a47dfd6ecc295fc4.png
9 s. h, ~3 a4 o9 Y9 P
1 z) M, d/ i+ \5 j
接下来分析31:30位的值:10,由图一可知,其中31位CNF7[1]的值=1;30位CNF7[0]的值为0。图五如下:
, f: P' ^! ^( W# v, o6 ~5 }  Z5 G3 I! D) i  f
56323f282da24b1dbd2150136a292c37.png 5 u: e* W, a& I' K3 X
  C' x: i3 i7 i2 F( d; j8 ]
由29:28位得知:为输入模式,且31:30位的值为10,对照图四亦可得出,即为上下拉输入模式
% Y2 c4 t) [3 Q6 k8 DSDA_OUT()如下:. q$ w2 K4 }# L3 Q) k) L  Y

( y7 }% k3 T# e#define SDA_OUT() {GPIOB->CRL&=0X0FFFFFFF;GPIOB->CRL|=(u32)3<<28;}+ N3 N% u2 J: \. d( d! s' c
* ?6 R' f& }5 {& W4 c
其中(GPIOB->CRL) &= 0X0FFFFFFF等价于 (GPIOB->CRL) = (GPIOB->CRL) & 0X0FFFFFFF7 g; ]* P! x2 i1 D
其含义为:把PB端口的CRL寄存器的第28、29、30和31位清空,把GPIOB端口中的CNF7[1:0]和MODE7[1:0]置零" d, V  C% N5 \: d
6 Y, p5 T, [. G, A1 k9 |: F
其中GPIOB->CRL |= (u32)3<<28 等价于 GPIOB->CRL = GPIOB->CRL | (u32)(3<<12)
$ r/ j9 q; m5 |& e+ d$ ^3转换为2进制为:0000 0000 0000 0000 0000 0000 0000 0011' u3 R. v0 d& U7 s
将3左移28位得:0011 0000 0000 0000 0000 0000 0000 0000
* s7 X3 p, h( V5 P分析左移之后的数据为,将31、30、29、28位设置为00 11
. E# A* Z. V$ I$ `- I( {5 _7 E+ fPB的CRL寄存器中29和28位设置为11,其中29位MODE7[1]的值=1;28位MODE7[0]的值为1。即为输出模式,最大速度为50Mhz。
$ X$ V1 H- F& T
% m* L, X5 J  v6 {$ q
bd0b6655f914488c8b083441edf707d0.png
; T! Y6 W; x+ r5 B
) h0 a: K& O2 l0 [; {
PB的CRL寄存器中31和30位设置为00,其中31位CNF7[1]的值=0;30位CNF7[0]的值为0;由图五可知:通用推挽式输出模式。. X8 y  w7 Y. R
————————————————
& ^( w8 X; w4 q2 V' A; X版权声明:枫华雪悦v/ r" y! ^* g+ v- c5 @' f1 f8 M5 }
如有侵权请联系删除' |2 A$ G6 D4 x" T

( d- ]! E8 l3 r7 V9 l# W; z" m# `0 `/ K+ ^! N7 S- b0 M( o) F
4 H% c6 N5 g( @( q, x
收藏 评论0 发布时间:2023-5-22 20:00

举报

0个回答

所属标签

相似分享

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版