个人使用stm32f103zet6使用芯片内部IIC的理解,如果有问题欢迎大家讨论

2019-08-13 20:19发布

首先是初始化,我看别人写IIC速度的时候用的都是400KHz,50000是我随便写的,手册要求低于400KHz,库函数中有个默认设置用的是5000,我就取了个中间值,这个值的设置有什么注意点,知道的朋友可以说一下
初始化 初始化
我主要想说的是写的过程和读的过程,我测试用的是24C02
write.png
在上面的程序,是我在参考别人的程序写出来的,下面写的是我的理解(程序初始设置u8 i,和for()我没有算在下面的步骤中)
第一步是检测是否处于BUSY;
第二步是设置CR1位8,产生起始条件;
第三步是EV5,BUSY总线忙, MSL 主模式and SB起始位已发送 ,这些标志位置位后跳出while;
第四步也是EV5,这时候给DR写入24C02的地址,清除了SB位,EV5才算完成;
第五步是EV6,BUSY总线忙, MSL主模式, ADDR地址已经发送, TXE数据寄存器为空(发送地址时不设置这位,手册中写的) and TRA数据已发送(手册中说是指示主设备是发接收器模式还是发送器模式,发送器时为1),这些标志位置位后跳出while;
第六步是发送在24C02中准备写入数据的起始地址,也就是手册中的EV8-1;
第七步是EV8,TRA数据已发送, BUSY总线忙, MSL主模式, TXE数据寄存器空;此时地址在移位寄存器中
第八步还是EV8,把要发送的数据写入数据寄存器中;
第九步,仔细看就会发现和第七步是一样的;个人感觉就是前一个数据转移到移位寄存器后,EV8中的标志位置位,我们就把要发送的数据写入DR寄存器,数据写入数据寄存器也正好清除了EV8中的TXE位;
第十步是设置CR1位9,产生停止条件;
手册中提到的EV8-2和EV8相比就是多了个BFT位,说是最后一个数据发送完成之后没有数据写入DR寄存器,就会置位;最后一次数据发后,等待EV8的标志位置位后,我们就跳出for循环,此时就在EV8_2,我们第十步就直接设置停止条件,也清除了BFT位。
我在写程序的时候就在想为什么IIC中的应答,在程序中没有体现,在中文参考手册的509页,DR数据寄存器的描述中,IIC可以保持连续的数据流,我的理解是移位寄存器的数据传输开始,TXE就置位,我们就可以把下个数据写入DR寄存器,而发送完成并接收应答信号后,移位寄存器才会取走数据寄存器的值;应答这步操作芯片自己完成了。
read1.png
read2.png
至于读操作的话,跟这个是类似的:
开始要有个写的操作,把24C02的地址写入,再把存放位置的地址写入;这步操作在接收器时序上没有体现;
再重新开始,写入24C02的地址,这是需要注意要把方向改为读,等待EV6;
如果只有一个数据要读,就进入EV6_1,如程序中if(num==1)的程序,清除响应,并设置停止产生位(中文手册翻译的不是很好懂,看看英文手册就知道了);然后判断标志位EV7,为1后读DR;因为在EV6-1中把应答改为了非应答,所以读完数据后要改回去;
如果读多个数据,直接判断EV7,为1后读DR;在接收了NUM-2个数据后,此时num=2;进入EV7_1,读取倒数第二个数,然后num--后值为1,然后操作和EV6-1是一样的;然后判断EV7标志位后读取最后一个字节;把非应答还未应答。

友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。