写时序
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
起始条件
当BUSY位为0时,设置起始条件引起接口生产起始条件,并且切换至主机模式(MSL位为1)
注:在主机模式下,置位START位会引起接口在发送完当前字节后产生一个重复起始条件
一旦起始条件被发送:
l SB位会被硬件置1,并且在ITEVTEN位为1的情况下产生一个中断
然后,主机等待读取SR1寄存器,接下来向DR寄存器写入从机地址(参见Figure 21 & Figure 22 Transfer sequencing EV5)
上述描述就划为:
1. 产生起始条件 I2C-CR2->START=1
2. 查询是否产生起始条件 查询EV5并且清掉SB,读取SR1寄存器即可清
3. 写入从机地址
4. 读SR1寄存器
发送从机地址
从机地址通过内部移位寄存器发送到SDA线上
l 在7位地址模式,1个字节地址被发送
一旦地址被发送
硬件置位ADDR bit,并且在ITEVTEN bit为1的情况下产生一个中断
然后,主机等待读取SR1寄存器,接下来读取SR3寄存器(see Fiurger 21 & Figure 22 Transfer sequencing EV6)
主机依靠被发送的从机地址的最低位来决定进入发送模式还是接收模式
l 7位地址模式
-主机发送从机地址的最低位为0,进入发送模式
-主机发送从机地址的最低位为1,进入接收模式
//注释:地址发送完成标志位ADDR,需要读取SR1后,再读取SR3才能复位。查看手册关于I2C_SR1寄存器的ADDR位的说明部分有写。而官方提供的例程却没有按此要求来编写程序,只读取了SR1,并未读取SR3
主机发送模式
在发送完从机地址并清除ADDR后,主机从DR寄存器发送字节到移位寄存器中,并发往SDA线上。
主机等待直到第1个字节数据写入DR寄存器(see Figure 21 Transfer sequencing EV8_1)
当接收到ACK响应脉冲后:
l TxE位被硬件置位,并且在ITEVNTEN和ITBUFEN位同时为1的情况下产生1个中断
在TxE位为1,下一个数据发送完之前,1个数据字节没有被写入DR寄存器的情况下, BTF被置1,并且接口一直等待直到BTF被复位,BTF可依靠读取SR1寄存器复位,然后SCL 低电平期间写DR寄存器。
(也就是说,在主机接收到从机的ACK后,需要读SR1来复位BFT,然后再写DR寄存器)
关闭通信
在向DR寄存器写完最后一个字节后,STOP位被软件置1以产生停止条件(see Figure 21 Transfer sequencing EV8_2)。接口自动切回从机模式(MSL位被复位)
注意:停止条件应该在EV8_2事件期间产生,此期间TxE或BTF有1位为1。
主机接收模式
在地址发送完成并且复位ADDR之后,I2C接口进入主机读取模式。在该模式下,接口从SDA线上接收字节并通过移位寄存器存入DR寄存器中。每个字节之后,接口产生时序:
l 如果ACK位为1,1个响应脉冲
l RxNE位为1,并且在ITEVTEN和ITBUFEN位同时为1的情况下产生1个中断。(see Figure 22 Transfer sequencing EV7)
如果RxNE位为1,并且在下一个数据reception(接待)结束之前,DR寄存器中的数据没有被读取的情况下,BTF位被硬件置1,并且接口等待BTF复位,BTF可以在SCL低电平期间通过读取I2C_SR1和I2C_DR寄存器来复位。
关闭通信
方法1:
该方法适用于在应用程序中I2C被用于拥有最高级中断的情况下。
主机为从从机那接收到的最后一个字节发送1个NACK。在接收该NACK后,从机释放总线的SCL和SDA线。接下来,主机发送一个停止条件或重复起始条件。
l 为了在接收最后一个字节后产生非应答脉冲,在读倒数第2个字节期间(在倒数第2个RxNE事件)ACK位必须被复位。
l 为了产生停止条件或重复起始条件,在读倒数第2个字节期间(在倒数第2个RxNE事件)软件必须置位STOP位和START位。
l 如果只接收单独1个字节,应答失去作用并且在EV6后产生停止条件(在ADDR被复位,EV6_1期间)
在产生停止条件之后,接口自动切回从机模式(MSL被复位)
方法2:
该方法适用于如下情况:在应用程序中I2C中断不拥有最高优先级或I2C用于轮询
该方法:
l DATA(N-2)未被读取,以至于在DATA(N-1)之后,通信被stretched(RxNE和BTF都被置1)
l 之后,ACK位必须在读取DR寄存器中的DATA(N-2)之前被复位以确保该位在DATAN的应答脉冲之到来前被复位
l 此后,在读取DATA(N-2)之后,软件必须将STOP和START位置1,并读取 DATA(N-1)。将RxNE置1后,读DATAN
详见时序图
当最后3个字节还没读的时候:
l RxNE=1=>什么都不用做(没有读DATA(N-2))
l 总线接收DATA(N-1)
l BTF=1,因为移位寄存器和数据寄存器都是满的:DR寄存器中存放DATA(N-2)移位寄存器中存放DATA(N-1) :SCL锁定为低电平:不会再接收总线上的其它数据
l 复位ACK位
l 读取DR寄存器中的DATA(N-2) =>这使DATAN装入移位寄存器
l 总线接收DATAN(with a NACK)
l 编程 START和STOP
l 读取DATAN-1
l RxNE=1
l 读取DATAN
//注释:编程START和STOP那步,官方例程里边没有做START,只做了STOP
//注意看勘误
上述过程适用于N>2的情况。对于只接收1个字节与2个字节的情况有不同的处理方法,描述如下:
l 接收1个字节的情况:
-在ADDR事件期间,复位ACK
-复位ADDR
-编程STOP和START位
-在RxNE标志置1后读取数据
l 接收2个字节的情况:
-将POS和ACK置1
-等待直到ADDR标志被置1
-复位ADDR
-复位ACK
-等待直到BTF置1
-编程STOP
-读取DR寄存器2次
EV5:SB=1,通过读取SR1寄存器可清除SB,接下来向DR寄存器写入地址
EV6:
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
勘误
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
1.3.1 I2C事件管理
描述
就像在STM8L101xx微控制器参考手册(RM0013)的I2C部分描述的一样,应用程序固件在发送当前字节之前必须管理很多软件事件。在前当字节被传送之前,如果EV7,EV7_1,EV6_1,EV6_3,EV2,EV8和EV3事件没被处理,即会发生储如接收到额外字节,读到同一数据两次,或丢失数据的现象。
替代方案
在当前字节被发送之前,在ACK控制位响应脉冲变化之前,当EV7,EV7_1,EV6_1,EV6_3,EV2,EV8和EV3事件没被处理的情况下,必须让I2C中断用nested模式以确保这些事件不能被应用程序中(提高中断优先级到最高优先级的中断)所中断。
该局限无修正计划
1.3.2主机读取模式接收最后读取数据错误
条件
在主机读取模式,当使用方法2关闭通信的时候,最后读取数据会出错。该局限请关注下面两条:
1. 当N=2时主机读取时序
a) BTF=1(DATA(N-1) in DR and DATAN in shift register)
b) Program STOP=1
c) Read DR twice(Read DATA(N-1) and DATAN) just after programming the STOP bit
2. 当N>2时主机读取时序
a) BTF=1(DATA(N-2) in DR and Data DATA(N-1) in shift register)
b) Program ACK=0
c) Read DATA(N-2) in DR
d) Program STOP bit to 1
e) Read DATA(N-1)
描述
如果用户软件在总线上产生停止条件之前不能读取DATA(N-1),Shift寄存器的内容(DATAN)被毁坏(DATAN左移1位),此种情况,读取DATAN返回错误数据。
替代方案
方案1
-时序1
当时序1使用方法2关闭通信时,在programming停止位和读取DATA(N-1)之间,屏蔽所有可用中断
-时序2
当时序2使用方法2关闭通信时,在读取DATA(N-2),programming停止位和屏蔽DATA(N-1)之间,屏蔽所有可用中断
该局限无修正计划
1.3.3 I2C外设工作于主机模式在错位的停止条件下行为错误
描述
如果总线上产生了一个错位的停止条件,I2C外设不能正确的进入主机模式。下列条件会发生上述错误。
l 如果接收到一个空信息(停止条件后紧跟着一个开始条件):BERR标志位未被置1,并且I2C外设在I2C_CR2寄存器写入START bit后不能在总线上发送起始条件。
l 在其它停止条件错位的情况下,I2C_CR2寄存器的BERR标志被置1。如果I2C_CR2的起始位已经被置1,总线不能正确的产生起始条件将引起总线错误。
替代方案
在I2C标准中,在所有字节被发送前(8 bits+acknowledge)不允许发送一个停止条件。其它衍生协议如CBUS则允许,但I2C外设不支持此做法。
在噪声环境下可能会发生意外的总线错误,因此要求增加超时以确保START control bit 置1后SB标志位被置1。在这种情况下,超时时间被消耗,外设必须通过设置I2C_CR2控制寄存器的SWRST位来复位。在I2C_CR2中的START位置1的时候,如果BERR被检测到(为1)I2C外设将会以同样的方式复位
该局限无修正计划
1.3.4 重复起始条件的建立时间的时序参数不匹配
描述
在重复起始条件的情况下,重复起始条件的建立时间参数(手册中 tSU(STA),I2C标准规范中sta)可能会存在较小的误差,当I2C工作于主机标准模式,频率范围从88kHz到100KHz时tSU(STA)最小值可能是4us而非4.7us。
下列条件将发生上述错误
1. I2C设备工作于主机标准模式,频率从88kHz到100kHz(快速模式无错误)
2. SCL上升没沿满足下列条件之一
-从机不stretch时钟,并且SCL上升沿大于300ns(上升沿小于300ns时无错误)
替代方案
降低频率到88kHz以下或如从设备支持快速模式则使用快速模式。
1.3.4 在从机“NOSTRETCH”模式下,会发生underrun错误和总线错误
描述
I2C标准描述的数据有效时间(tVD;DAT,tVD;ACK)和最大当前数据保持时间(tHD; DAT)
在下述情况下可能会出错。
此外,写入数据寄存器太晚或接近SCL的上升沿,总线可能会发生错误:当SCL为高电平时SDA会翻转。因为OVR标志没有被置位(no transmit buffer underrun is detected),故这个溢出不能被检测出。
这个错误在下列条件下发生:
1. 当clock stretching disabled,I2C外设工作于从机发送模式时。
2. 应用程序写DR data register 较迟,但又不够太迟以至于OVR标志位置1(在SCL上升沿之前写完data register)
替代方案
如果主设备支持,通过编程I2C_CR1寄存器的NOSTRETCH=0来使用clock stretching mechanim
如果主设备不支持,确保写data register的操作在TXE或DDDR事件之后执行。你可以使用TXE或ADDR中断标志拉,并使其优先级最高。
使用慢速I2C模式下使用”NOSTRETCH”可以阻止应用程序写入DR register太迟。
注意
在清除ADDR标志位后,在下一个SCL的上升沿到来之前,发送的第1个数据必须写入data register ,故往data register写入第1个数据的窗口时间小于tLOW
该局限无修正计划
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
以上两处是我在调试STM8L101F3P6的硬件IIC接口时阅读手册的翻译资料,目前该部分还没有调试成功,时间还得从工作中挤。
我就不信手册都看懂了,勘误都看懂了,还在网上乱叫说STM8硬件IIC不好使,不知道这种人认真的看手册了没有。。。从勘误中也可以看出,是有问题,但是并不是没有解决方案,蔑视在网络上乱叫的人。。。
2013.10.07 10:20
于家中