I2C软件模拟中的IO方向设置问题

例程:STM32F103系列 I2C软件模拟实验(战舰例程)
问题:下面两行关于“IO方向”的代码不太明白。之前一直看的例程都是库函数的代码,突然间冒出来两行寄存器的代码一时间手足无措。

#define SDA_IN()  {GPIOB->CRL&=0X0FFFFFFF;GPIOB->CRL|=(u32)8<<28;}//Ⅰ
#define SDA_OUT() {GPIOB->CRL&=0X0FFFFFFF;GPIOB->CRL|=(u32)3<<28;}//Ⅱ

咋办?
解决:

纯逻辑分析

首先有下面几个必然成立的逻辑关系(十六进制):
A & F = A; A | F = F;
A & 0 = 0; A | 0 = A;
假设 CRL=0X########
Ⅰ.
CRL = CRL & 0X0FFFFFFF = 0X######## & 0X0FFFFFFF = 0X0#######
32位的8 (1000b) 按位(非循环)左移28位,(u32)8<<=28 => 0X80000000
CRL = CRL | 0X80000000 = 0X8#######
Ⅱ.
CRL = CRL & 0X0FFFFFFF = 0X######## & 0X0FFFFFFF = 0X0#######
32位的3 (0011b) 按位(非循环)左移28位,(u32)3<<=28 => 0X30000000
CRL = CRL | 0X30000000 = 0X3#######
这么一堆逻辑计算后,还是一头雾水,跟IO口的方向有什么关系?继续!

网络查找

最受启发的一篇博文,谢谢这位博主!(点击可查看)
查到这个问题涉及GPIO端口配置寄存器,关键词CRL,需要查看Manual。

Manual查找(多图预警)

目前接触到的STM32的手册有三种:
Datasheet 数据手册:主要内容是器件的技术特征、性能参数
RM0008(Reference Manual) 器件参考使用手册:寄存器版的编程手册
UM0427(User Manual) 固件库手册:库函数功能、参数等描述,库函数编程手册
这里主要参考RM(该版中文版我已上传资源,需要的朋友欢迎搬走)。

(1) I2C的GPIO配置表

I2C接口
由上图可知:I2C的SDA引脚的GPIO配置形式为开漏复用输出(Alternate function open drain)

(2) GPIO配置方式回顾

浮空输入 floating input
上拉输入 pull-up input
下拉输入 pull-down input
模拟输入 analog
开漏输出 open-drain output
推挽输出 push-pull output
复用开漏输出 alternate function open-drain
复用推挽输出 alternate function push-pull

(3) GPIO寄存器具体有哪些呢?看下表

I2C软件模拟中的IO方向设置问题_第1张图片

(4) GPIO寄存器是如何配置端口的呢?

如(3)中所示,GPIO有两个32位的端口配置寄存器,这里需要查找的是CRL端口配置低寄存器,如下面的表格所示,32位的每一位表示什么,置0还是置1,置位后对应怎样的输入输出模式,都写得一清二楚
I2C软件模拟中的IO方向设置问题_第2张图片
根据这个表格,我们就可以解释 1 中逻辑分析结果的含义:
Ⅰ. GPIOB->CRL & 0X0FFFFFFF :将GPIOB的CRL寄存器(第7个IO口)的地址位(CNF[1:0] MODE7[1:0])清零,其余位和1按位与 后 保持不变;
再将上面的结果给GPIOB->CRL,此时,
GPIOB->CRL | 0X80000000 :因为 0x8=1000b,所以此处是将GPIOB的CRL寄存器(第7个IO口)的地址位(CNF7[1:0] MODE7[1:0])置位为1000,即MODE7[1:0]=00,CNF7[1:0]=10,其余位和0按位或 后 保持不变。
最后,依照表格PB7的CRL寄存器 MODE7=00,处于输入模式,CNF7=10,上拉/下拉输入

Ⅱ. 同理,因为0X3=0011b,所以此时GPIOB的CRL寄存器(第7个IO口) MODE=11>00,处于输出模式,最大速度50MHz,CNF=00,通用推挽输出

总结

SDA对应IO口的输入输出方向和模式全部了解,与君共勉,以上!

【声明】本博文为个人学习笔记,仅供参考。转发请注明出处。如发现有误,还请不吝赐教,谢谢!

你可能感兴趣的:(嵌入式之STM32)