请选择 进入手机版 | 继续访问电脑版

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

分享关于STM32f103 的硬件IIC I2C 调试心得 精华  

[复制链接]
motianlun1111 发布时间:2015-8-4 22:28
STM32电机培训online,大佬带你玩电机$ w% ?3 x6 Z7 x, k! J2 E0 g
. r9 z- G/ W4 f! L5 }9 ]7 U' v
stm8硬件I2C 主机/从机 发送/接收 完全解决测试验证通过8 e  _2 c  ^+ u( A6 ~. }
0 v& q+ j. B) X! s
基于stm32的I2C总线通讯简介及使用操作(附代码)
/ Q* l; s9 g4 ?; J! G, k* j8 c& [9 R; s' p" {6 ~
. c5 N$ L1 W6 `" A" t8 u0 B! f
首先说一下用的是stm32f103vct6 100脚封装的,有IIC1,和IIC2,其中IIC都是复用的,采用usart3串口打印输出EEPROM里面的东西,USART3采用重新映射了引脚,不然和IIC2有冲突,(记不得是IIC1,还是IIC2有冲突了,反正是有一个有)首先要看明白stm32的IIC的流程框图,
, h* E4 J! x* E$ F+ \: Z. o- L' ? 捕获.JPG ! e5 @) g. X  C1 u# G# E
5 u* j) o+ W2 e& c
简要的描述一下这个流程; C& H0 z" S- i
如上图所示,低下的EV5EV6等等的表示的是你要执行的操作,以及这个操作的时候对应的IIC总线上发生的事情,比如EV5中,是star发送了之后,你需要进行EV5操作,这里的EV5包括标识位检测,也就是whilecheckEV5))EV5标志位都达到了,这样跳出while,但是注意EV5没有完,你需要接着执行写入DR寄存器里面器件地址,这些整体构成了EV5,实际上是你在S发送了的时候,就进行while判断EV5了,但是只有s过完了,才正式开始进入EV5,因为那个时候才是标志位成立,所以每个方框的交界的地方,比如EV5这个的左边的那条线,那时刻开始是EV5标志位成立的意思,接着EV6,你在EV5之后就开始判断EV6的标识位了,但是只有等到A成立之后那条右边的线之后,EV6才成立,而实际上库函数里面把对EV6的判断事件也包含了EV8_1的判断事件,也就是说,EV6EV8_1实际可以看做一个事件,EV6的判断成立之后,操作的事件其实就是执行EV8_1EV8_1执行完之后,也就是右边的竖线表示执行结束,同时这一时刻数据1开始发送了,在操作中是操作完EV8_1之后就继续操作EV8,是有个while判断过程,实际上EV8判断一成立,同一时刻数据1也在总线上发送了,EV8之后,继续执行EV8(首先还是判断EV8条件成立,而这个条件成立就是在A之后才会条件成立了)如果只有一个数据1和数据2的话,数据1下面对应的EV8执行之后,要执行的是EV8_2,由图流程可以看出来的。

2 d9 v2 c2 C) _- I- O2 d3 L8 o
另外注意一点,就是标识位在while里面的判断,while1)一直等待,while0)就退出了,比如我想知道I2C->SR1寄存器的ADDR位,这是bit1,显然想到把12C->SR1 & 0X0002,这就把其他的位都变成0了,只有bit11(如果ADDR1的时候)也就是取完余之后的结果是0x0002,但是问题是这个值要怎么在while里面表示为0?取反可不是表示的为0,取反只是把bit1变成0了,其他的位全变1了,也就是~0x0002 = 0xfffd 而若用!表示的是非的意思,!0x0002是什么呢?是0,因为0X0002不是0,非它就是0
好了有了这个流程,基本就按这个代码写了,下面我想说说一些网上的代码,其实都是互相粘贴的,乱七八糟的,没搞明白这里面事件的流程和关系,乱写一通,
我看的是刘凯的视频里面,首先感谢他给的好多思路,慢慢的我现在自己能自己写些库了,或者直接在官方的库里找想要的了,另外说句他的视频上面的IIC那部分,应该他自己都有点乱了,可以肯定的代码不是他写的,他讲IIC代码时候应该也没有做好功课,他的代码里面有些混乱的,注释也是英文的,应该是在哪里粘贴的,下面看下他的一段读操作,或者写操作的首代码,

# N1 i  T- G4 \7 \9 b0 H
/ {8 m! Q' Y) _% B/ d& @
这里名字是我改的,代码是他的源文件里面的,这段代码我个人感觉加与不加没有意义,

2 `  }3 G3 L$ u
他的出发点应该是写或者读之前,判断下总线是否为空闲,判断下器件是否为空闲,但是这里面的while语句上,疑惑就如我标注的所示,如果地址写到DR寄存器里面了,但是没有发送完啊,还没有得到器件的ACK,这之前若就已经进入这个while里面读SR1寄存器了,那就会在while里面一直出不来,不是说器件没闲着,是因为这个语句思路就是有问题的,
) h: R7 Q% c* l/ ~6 f6 j4 x6 F
我也上网找了找别人的学习笔记,还重点加标注这个代码是防爆代码,和这里的代码是一模一样,本人愚钝,不明白,还是说写那些心得的人根本也没明白?都是一样抄的?这段代码的位置就是在如下所示的位置

! e; \3 Z% E4 T/ m; @
9 k/ m) {# o! b- r% R, G# [
说说我加了这个代码的情况吧,我一开始感觉他这个代码有逻辑bug,我自己写了一段,但是后面总是跳不出去,我想想我自己的 那个也确实有问题,我再想想其实安装手册的流程框图来操作,就已经考虑了器件忙,总线忙,你EV5,EV6这个事件都是解决这个忙的问题,等待着总线被stm32占用了,等待着器件闲下来回应你一下,完全没有必要加这段代码,

( E; N- y4 s7 l' U
我加了这段代码,在仿真里面出不去,但是在板子上运行,这个问题比较奇葩了,有时候运气好,一直都能出去,有时候运气不好,一直出不去,另外这段代码我发现还有个大问题,有可能把stm32,本来是默认从设备,经过这段代码之后就变成主设备了,然后在真正进行写操作时候,那个EV6事件有可能出不来,因为EV6事件是一个判断start之后stm32由从变主(可能是这样,具体的寄存器里面的前一个s信号导致的变化在下个s信号里面会不会保持寄存器我没验证,反正可以知道的是第二个s时候,stm32在发s的时候就是主了,仿真里面的问题也可能是MDK自己的bug,因为我发现开着系统IIC窗口看寄存器,它会还没操作该寄存器就提前读取某些寄存器的值,这导致本该不清0的事情提前清零了,可能也是MDK的bug),这个问题不多见,偶尔出现,反正我实验的就是加这个防爆代码,看人品了,有时就是不好使,或者有哪位大神有别的理解,希望不吝赐教
4 C6 `1 b4 k0 @" Q2 }
下面附上我自己的代码,代码里面注释的非常详细,什么事件,要考虑什么,会做怎么样,有需要的可以自己下载看下,硬件的操作,是通过usart3打印出来观察的,usart3采用了冲新映射的引脚,可以自己看看里面的定义,写了IIC1和IIC2的都实验了,加代码总出问题好像是在IIC2中发生的,各位大神,欢迎多发表意见,多多交流

1 E' ^4 K6 N' r+ r$ m- B( |
11 IIC1 实验 USART3 打印 (FLASH版本).rar (298.85 KB, 下载次数: 3290)

评分

参与人数 10 ST金币 +21 收起 理由
danshuizz + 1 很给力!
robotjjs + 1 很给力!
stickvc + 1 很给力!
xfeng + 1 感谢分享赞一个
heyangfengyue + 2 很给力!
skyarong + 2
羽非雨 + 1
yinlaj + 1 很给力!
似曾相识175 + 1 很给力!
damiaa + 10 赞一个!

查看全部评分

26 收藏 57 评论240 发布时间:2015-8-4 22:28

举报

240个回答
Dylan疾风闪电 回答时间:2016-4-14 10:48:32
本帖最后由 Dylan疾风闪电 于 2016-4-14 10:50 编辑
0 w% N% `, Y" T2 H( n$ h% }. E
+ y, h* y! s, ~8 u+ B好久没有stm32f103的i2c了,
$ G6 }- L; Y7 t2 s5 G0 B( n9 X5 b& l看到这个帖子,
# j( B- a4 v; ~% B- u% Q8 h顺带询问一下lz有没有遇到这样的问题:
/ e, u2 W" P3 G. x5 n! N7 ]6 H' R--------------------------------------------------------------------------------------
; B  W9 M! N/ ~5 w' ~“两块stm32f103芯片,一块做主i2c,另一块做从i2c。
% f+ `$ F( G; c- S: {1 Q通信方式是中断收发、速率400k。
' i0 r3 [# Z& }. H问题:通讯过程中由于i2c寄存器busy位,导致通信中断,并且之后也无法再进行相互通信了?
: w; R5 ]* F& z: u7 B: T7 r) u* [" |8 u9 H
---------------------------------------------------------------------------------------! U! [5 _& q$ K
有非常规的方式来处理解决这个问题,但是绕的比较远。+ Y& |) \  n4 c% X# Z. V
而且只在CM3的STM32F1系列上出现过。(CM0核的i2c变更后就不存在此问题). a" {3 y# K% h$ w. V
很久没用i2c了(10年的时候的问题,印象很深),不知道有没有新的处理方法?
2 E( s# _' T$ U% _4 z: u0 r- l) y4 }  e1 y* u' m6 {
Glenxu 回答时间:2020-2-4 20:45:54
我认为源程序没有问题,你的分析有问题:: f7 C" d9 [! a0 j
这个问题我以前在PIC中遇到过,“不稳定”,经过多次试验发现,接了这句就好了,原因很简单,因为IIC正如其它通讯一样,有事会有干扰,缓存提前收到了“信息”,如果你在开启后不立即清除缓存标志(读一次),则永远收不到你所等待的信息,即导致通讯失败。
! H2 f6 o$ v1 i: H* }$ a巧合的时在STM中也有这样的问题,这就是为什么很多人认为硬IIC不好用或不稳定的原因吧。
4 w9 a/ M( Q1 P2 m! z个人经验而已,请借鉴!
stickvc 回答时间:2019-4-21 15:39:35

0 {' P1 Q% ^' C8 u6 ?0 @下面附上我自己的代码,代码里面注释的非常详细,什么事件,要考虑什么,会做怎么样,有需要的可以自己下载看下,硬件的操作,是通过usart3打印出来观察的,usart3采用了冲新映射的引脚,可以自己看看里面的定义,写了IIC1和IIC2的都实验了,加代码总出问题好像是在
风子 回答时间:2015-8-5 09:02:56
谢谢分享
党国特派员 回答时间:2015-8-5 09:10:49
谢谢分享 blank.png blank1.png blank2.png blank3.png blank4.png
加拿大 回答时间:2015-8-5 09:43:38
,谢谢分享,学习了
那就地方 回答时间:2015-8-5 10:19:28
谢谢楼主分享
stary666 回答时间:2015-8-5 12:40:18
看看,,,,,
alisa123 回答时间:2015-8-5 19:20:35
楼主分析的很详细,前段时间用stm 32f302的硬件iic,没搞定,最后用软件模拟了,后面找空也的再学习。
wdzfd 回答时间:2015-8-5 19:29:46
不错,谢谢分享!
埃斯提爱慕 回答时间:2015-8-5 22:36:41
提示: 作者被禁止或删除 内容自动屏蔽
回答时间:2015-8-6 21:57:47
我也是前几天控制贴点存储器遇到了问题,后来也是软件模拟的,有时间好好学习下~~~~~~
Tarzan519 回答时间:2015-10-9 18:23:23
我按照楼主的代码调试,发现发送的时候EV5、EV6、EV8都可以产生,就是最后发送完成后没有EV8_2,细看是没有置BTF位,楼主知道是什么原因吗?
VRichard 回答时间:2015-11-4 20:33:47
谢谢分享 有些细节确实很难搞懂
foxglove 回答时间:2015-11-4 21:40:06
STM32f103 的硬件IIC I2C
谈笑间 回答时间:2016-1-19 16:32:10
感谢楼主分享,学习中
kingchou2 回答时间:2016-2-3 10:46:20
顶一下!!!!

所属标签

相似分享

关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版