OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 23615|回复: 35

IIC实例的SDA_In和SDA_Out的代码理解GPIOB->MODER&=~(3<<(9*2));GPIOB->MODER|=0<<9*2;

[复制链接]

2

主题

3

帖子

0

精华

新手上路

积分
31
金钱
31
注册时间
2016-3-1
在线时间
6 小时
发表于 2016-5-25 10:37:39 | 显示全部楼层 |阅读模式
1金钱
各位前辈大家好:

IIC通讯实验里面的例程:

#define SDA_IN()  {GPIOB->MODER&=~(3<<(9*2));GPIOB->MODER|=0<<9*2;}        //PB9输入模式
#define SDA_OUT() {GPIOB->MODER&=~(3<<(9*2));GPIOB->MODER|=1<<9*2;} //PB9输出模式


第一句 GPIOB->MODER&=~(3<<(9*2)) 该如何理解?PB9的MODER寄存器低位右移3位取反相与,即是保留原来的值(貌似也把PB10的MODER寄存器也连带设置了下?为啥要这样呢),后面的PB9输出模式相或配置成输出能理解,但是PB9输入模式也相或,假如原来是01输出,相或之后岂不还是01输出模式,PB9输入模式是否应该为 GPIOB->MODER&=0<<9*2; ,望前辈指教,多谢。如果幼稚之处,还请谅解。

最佳答案

查看完整内容[请看2#楼]

不是右移3位 前部分GPIOB->MODER&=~(3MODER的16,17位变为00。第一句也就是将GPIOB->MODER的16,17位置0. 后部分GPIOB->MODER|=0
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

6

主题

35

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
357
金钱
357
注册时间
2016-4-2
在线时间
66 小时
发表于 2016-5-25 10:37:40 | 显示全部楼层
不是右移3位
前部分GPIOB->MODER&=~(3<<(9*2));  是将十进制的3(二进制是11)左移(9*2)个位,也就是将16,17位置置为11,然后取反变为00,再和GPIOB->MODER与运算,此时GPIOB->MODER的16,17位变为00。第一句也就是将GPIOB->MODER的16,17位置0.
后部分GPIOB->MODER|=0<<9*2和GPIOB->MODER|=1<<9*2也就是根据参考手册的输入输出给这两个位置赋值,过程和上面是一样的。
应该就是这样吧,,我也是初学,,
享受学习中的乐子,做合格的程序猿
回复

使用道具 举报

120

主题

7878

帖子

13

精华

资深版主

Rank: 8Rank: 8

积分
12012
金钱
12012
注册时间
2013-9-10
在线时间
427 小时
发表于 2016-5-25 19:51:39 | 显示全部楼层
Fighting_Tao 发表于 2016-5-25 10:37
不是右移3位
前部分GPIOB->MODER&=~(3MODER的16,17位变为00。第一句也就是将GPIOB->MODER的16,17位置0.
...

回答非常正确
现在,程序把烂铜烂铁变得智能化了,人呢,一旦离开了这烂铜烂铁就不知道干啥了
回复

使用道具 举报

13

主题

101

帖子

0

精华

高级会员

Rank: 4

积分
509
金钱
509
注册时间
2016-1-4
在线时间
87 小时
发表于 2016-8-16 10:56:15 | 显示全部楼层
顶一个
回复

使用道具 举报

9

主题

53

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
372
金钱
372
注册时间
2016-8-15
在线时间
55 小时
发表于 2016-9-7 23:12:38 | 显示全部楼层
顶一个
回复

使用道具 举报

8

主题

46

帖子

0

精华

初级会员

Rank: 2

积分
178
金钱
178
注册时间
2015-6-21
在线时间
41 小时
发表于 2016-12-13 16:18:02 | 显示全部楼层
Fighting_Tao 发表于 2016-5-25 10:37
不是右移3位
前部分GPIOB->MODER&=~(3MODER的16,17位变为00。第一句也就是将GPIOB->MODER的16,17位置0.
...

应该是18/19位吧?
回复

使用道具 举报

2

主题

27

帖子

0

精华

初级会员

Rank: 2

积分
128
金钱
128
注册时间
2016-10-28
在线时间
30 小时
发表于 2017-1-17 17:06:30 | 显示全部楼层
Allen.W 发表于 2016-12-13 16:18
应该是18/19位吧?

是的
回复

使用道具 举报

45

主题

135

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
249
金钱
249
注册时间
2016-12-29
在线时间
47 小时
发表于 2017-1-18 10:15:25 | 显示全部楼层
位段的赋值,就是给一个字节某几位赋值,其余几位不改变
回复

使用道具 举报

0

主题

34

帖子

0

精华

初级会员

Rank: 2

积分
179
金钱
179
注册时间
2017-2-2
在线时间
24 小时
发表于 2017-3-4 11:47:01 | 显示全部楼层
我要学习嵌入式 发表于 2017-1-18 10:15
位段的赋值,就是给一个字节某几位赋值,其余几位不改变

长知识了
回复

使用道具 举报

1

主题

23

帖子

0

精华

初级会员

Rank: 2

积分
145
金钱
145
注册时间
2017-1-8
在线时间
27 小时
发表于 2017-4-6 16:48:21 | 显示全部楼层
Fighting_Tao 发表于 2016-5-25 10:37
不是右移3位
前部分GPIOB->MODER&=~(3MODER的16,17位变为00。第一句也就是将GPIOB->MODER的16,17位置0.
...

解释的很好
回复

使用道具 举报

0

主题

11

帖子

0

精华

初级会员

Rank: 2

积分
129
金钱
129
注册时间
2017-4-11
在线时间
31 小时
发表于 2017-4-11 17:03:42 | 显示全部楼层
请问为什么是9*2呢,我现在要使用10和11引脚,难道是10*2,具体看哪些资料,找了好久都找不到
回复

使用道具 举报

4

主题

27

帖子

0

精华

高级会员

Rank: 4

积分
890
金钱
890
注册时间
2016-12-2
在线时间
39 小时
发表于 2017-4-20 12:04:06 | 显示全部楼层
在IIC试验中,读取压力传感器ABPLANT006KG2A3压力值显示到LCD上,结果压力示数一直显示FFFF,请问有人知道这是什么原因吗?有可能是硬件问题吗?
回复

使用道具 举报

1

主题

2

帖子

0

精华

新手入门

积分
13
金钱
13
注册时间
2017-4-27
在线时间
2 小时
发表于 2017-4-28 11:17:17 | 显示全部楼层
Ilena 发表于 2017-4-20 12:04
在IIC试验中,读取压力传感器ABPLANT006KG2A3压力值显示到LCD上,结果压力示数一直显示FFFF,请问有人知道 ...

注意用myiic.c的话,STOP那里时序有个版本有问题,可以检查下。SCL和SDA之间有延时才行,我就是遇到这个问题
回复

使用道具 举报

6

主题

37

帖子

0

精华

初级会员

Rank: 2

积分
125
金钱
125
注册时间
2016-8-13
在线时间
27 小时
发表于 2017-4-28 13:29:01 | 显示全部楼层
qq244748015 发表于 2017-4-11 17:03
请问为什么是9*2呢,我现在要使用10和11引脚,难道是10*2,具体看哪些资料,找了好久都找不到

看GPIO寄存器
回复

使用道具 举报

4

主题

27

帖子

0

精华

高级会员

Rank: 4

积分
890
金钱
890
注册时间
2016-12-2
在线时间
39 小时
发表于 2017-5-7 21:19:32 | 显示全部楼层
白天黑客 发表于 2017-4-28 11:17
注意用myiic.c的话,STOP那里时序有个版本有问题,可以检查下。SCL和SDA之间有延时才行,我就是遇到这个 ...

谢谢你的回答,我后来检查发现了是硬件有问题,换了一个新的传感器就好了。
回复

使用道具 举报

0

主题

1

帖子

0

精华

新手上路

积分
43
金钱
43
注册时间
2012-11-14
在线时间
5 小时
发表于 2017-7-4 14:12:11 | 显示全部楼层
好,解释的好
回复

使用道具 举报

0

主题

5

帖子

0

精华

初级会员

Rank: 2

积分
130
金钱
130
注册时间
2016-5-8
在线时间
27 小时
发表于 2017-8-31 08:16:31 | 显示全部楼层
非常准确
回复

使用道具 举报

2

主题

13

帖子

0

精华

新手上路

积分
37
金钱
37
注册时间
2017-9-19
在线时间
8 小时
发表于 2017-9-20 15:18:19 | 显示全部楼层
Fighting_Tao 发表于 2016-5-25 10:37
不是右移3位
前部分GPIOB->MODER&=~(3MODER的16,17位变为00。第一句也就是将GPIOB->MODER的16,17位置0.
...

Nice   
快回来,你代码还没写完呢!
回复

使用道具 举报

2

主题

13

帖子

0

精华

新手上路

积分
37
金钱
37
注册时间
2017-9-19
在线时间
8 小时
发表于 2017-9-20 15:19:48 | 显示全部楼层
         
快回来,你代码还没写完呢!
回复

使用道具 举报

33

主题

310

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
495
金钱
495
注册时间
2016-12-31
在线时间
63 小时
发表于 2018-4-4 14:24:53 | 显示全部楼层

你好,请问如果配置PB11脚的SDA输出,输入模式的话是把9修改成11吗?
回复

使用道具 举报

33

主题

310

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
495
金钱
495
注册时间
2016-12-31
在线时间
63 小时
发表于 2018-4-4 14:25:21 | 显示全部楼层
qq244748015 发表于 2017-4-11 17:03
请问为什么是9*2呢,我现在要使用10和11引脚,难道是10*2,具体看哪些资料,找了好久都找不到

你好,我也是这个问题,你的解决了吗?
回复

使用道具 举报

33

主题

310

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
495
金钱
495
注册时间
2016-12-31
在线时间
63 小时
发表于 2018-4-4 14:29:40 | 显示全部楼层
Fighting_Tao 发表于 2016-5-25 10:37
不是右移3位
前部分GPIOB->MODER&=~(3MODER的16,17位变为00。第一句也就是将GPIOB->MODER的16,17位置0.
...

你好,有个问题,这个配置的是PB9脚,我看数据手册上面如果是9脚的话,应该是y=9吧?不应该是左移20位吗?
回复

使用道具 举报

0

主题

4

帖子

0

精华

新手上路

积分
49
金钱
49
注册时间
2017-9-5
在线时间
6 小时
发表于 2018-5-19 17:26:34 | 显示全部楼层
Fighting_Tao 发表于 2016-5-25 10:37
不是右移3位
前部分GPIOB->MODER&=~(3MODER的16,17位变为00。第一句也就是将GPIOB->MODER的16,17位置0.
...

你好为什么是16,17位不是18,19位啊
回复

使用道具 举报

3

主题

24

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
200
金钱
200
注册时间
2018-3-17
在线时间
32 小时
发表于 2018-5-20 23:37:46 | 显示全部楼层
二楼答案正确,建议理解下寄存器操作及加强C语言的学习
回复

使用道具 举报

0

主题

7

帖子

0

精华

新手上路

积分
44
金钱
44
注册时间
2019-8-13
在线时间
11 小时
发表于 2019-8-26 10:18:59 | 显示全部楼层
Fighting_Tao 发表于 2016-5-25 10:37
不是右移3位
前部分GPIOB->MODER&=~(3MODER的16,17位变为00。第一句也就是将GPIOB->MODER的16,17位置0.
...

我觉得是19,18位被进行改变,对应的就是操作IO口9,先进行复位(都变成0,才好进行后面的操作),然后在进行配置,可以去看对应中文参考手册7.4.1(我参考的是F407)
回复

使用道具 举报

0

主题

7

帖子

0

精华

新手上路

积分
48
金钱
48
注册时间
2019-4-24
在线时间
9 小时
发表于 2019-8-26 11:57:29 | 显示全部楼层
注意运算符号的优先级问题
回复

使用道具 举报

0

主题

7

帖子

0

精华

新手上路

积分
48
金钱
48
注册时间
2019-4-24
在线时间
9 小时
发表于 2019-8-26 12:01:26 | 显示全部楼层
运算符号的优先级问题,0x3<<18位然后取反就是18,19位是0,然后跟这个32位的寄存器相与&,就是将这个模式寄存器的18,19位清零,你去看参考手册,将该寄存器的18,19位设置为0应该就是将PB9是配置成输入模式
回复

使用道具 举报

0

主题

7

帖子

0

精华

新手上路

积分
48
金钱
48
注册时间
2019-4-24
在线时间
9 小时
发表于 2019-8-26 12:02:11 | 显示全部楼层
C语言的位运算和运算符优先级加强下
回复

使用道具 举报

4

主题

15

帖子

0

精华

初级会员

Rank: 2

积分
68
金钱
68
注册时间
2019-8-21
在线时间
22 小时
发表于 2019-10-5 17:48:01 | 显示全部楼层
Fighting_Tao 发表于 2016-5-25 10:37
不是右移3位
前部分GPIOB->MODER&=~(3MODER的16,17位变为00。第一句也就是将GPIOB->MODER的16,17位置0.
...

请教一下9*2表示的是什么呢?谢谢指点
回复

使用道具 举报

0

主题

6

帖子

0

精华

初级会员

Rank: 2

积分
141
金钱
141
注册时间
2019-4-27
在线时间
52 小时
发表于 2019-11-4 12:54:16 | 显示全部楼层
Fighting_Tao 发表于 2016-5-25 10:37
不是右移3位
前部分GPIOB->MODER&=~(3MODER的16,17位变为00。第一句也就是将GPIOB->MODER的16,17位置0.
...

厉害,学习了
回复

使用道具 举报

0

主题

2

帖子

0

精华

新手入门

积分
19
金钱
19
注册时间
2019-11-11
在线时间
3 小时
发表于 2019-12-8 12:09:46 | 显示全部楼层
#define SDA_IN()  {GPIOB->MODER&=~(3<<(9*2));GPIOB->MODER|=0<<9*2;}       
#define SDA_OUT() {GPIOB->MODER&=~(3<<(9*2));GPIOB->MODER|=1<<9*2;}
GPIOB->MODER&=~(3<<(9*2)是把MODER寄存器的18、19两位置0,即MODER9设置为00,00代表输入,即把PB9设置为输入;GPIOB->MODER|=0<<9*2;个人认为没有用处,删掉也可以;
GPIOB->MODER&=~(3<<(9*2));GPIOB->MODER|=1<<9*2;这两句话同上,是把MODER9设置为01,01代表输出,即把PB9设置为输出模式
回复

使用道具 举报

5

主题

29

帖子

0

精华

初级会员

Rank: 2

积分
52
金钱
52
注册时间
2020-3-4
在线时间
18 小时
发表于 2020-4-17 13:22:00 | 显示全部楼层
我帅极了 发表于 2019-12-8 12:09
#define SDA_IN()  {GPIOB->MODER&=~(3

这两行代码移植到F1上怎么改啊不太会寄存器操作
回复

使用道具 举报

3

主题

26

帖子

0

精华

初级会员

Rank: 2

积分
65
金钱
65
注册时间
2019-8-3
在线时间
18 小时
发表于 2020-8-18 10:57:13 | 显示全部楼层
我帅极了 发表于 2019-12-8 12:09
#define SDA_IN()  {GPIOB->MODER&=~(3

个人觉得你说的才是正确的
回复

使用道具 举报

0

主题

5

帖子

0

精华

初级会员

Rank: 2

积分
60
金钱
60
注册时间
2020-7-30
在线时间
12 小时
发表于 2020-9-12 14:25:23 | 显示全部楼层
{GPIOB->MODER&=~(3<<(9*2));GPIOB->MODER|=0<<9*2;}
GPIOB->MODER&=~(3<<(9*2) 这一句的功能是实现MODER的第18、19位也就是GPIOB的MODER9置为00,第一步:将十进制3(二进制11)左移18位110000000000000000;第二步:取反~为00111111111111111111;第三步:00111111111111111111同之前的MODER寄存器与&运算(这样MODER寄存器的第18、19位变为00其他位无变化)
GPIOB->MODER|=0<<9*2   同理,这句的功能是MODER寄存器第9pin也就是第18、19位置为00    PB9输入模式
GPIOB->MODER|=1<<9*2   同理,这句的功能是MODER寄存器第9pin也就是第18、19位置为01    PB9输出模式
这是我的理解,有错误希望大神给予更正
回复

使用道具 举报

9

主题

48

帖子

0

精华

初级会员

Rank: 2

积分
169
金钱
169
注册时间
2020-11-24
在线时间
38 小时
发表于 2020-12-17 19:51:53 | 显示全部楼层
本帖最后由 shelden 于 2020-12-17 19:54 编辑
陈运de 发表于 2019-8-26 10:18
我觉得是19,18位被进行改变,对应的就是操作IO口9,先进行复位(都变成0,才好进行后面的操作),然后在 ...

感谢提供资料提示。

如上图,对于IIC SDA(PB9),由于使用的是第九个管脚,所以y=9;对18:19两个位进行操作配置。

  1. GPIOB->MODER &= ~(3<<(9*2));
复制代码
先将3,也就是0011左移18位,然后所有位取反,得到0011 1111 1111 1111 1111;然后与GPIO->MODER(端口模式寄存器)进行与操作,再赋值给GPIO->MODER,达到将18:19位置0的效果,即复位状态。其余的语句功能类似,可依此类推。
回复

使用道具 举报

0

主题

1

帖子

0

精华

新手上路

积分
22
金钱
22
注册时间
2019-8-7
在线时间
5 小时
发表于 2021-1-14 09:46:39 | 显示全部楼层

很明显用计算机算一下就知道了,18 19位改变

本帖最后由 wm77 于 2021-1-14 09:48 编辑

file:///C:/Users/administered/Desktop/1610588752(1).png
1610588752(1).png
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-3-1 01:32

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表