方法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不好使,不知道这种人认真的看手册了没有。。。从勘误中也可以看出,是有问题,但是并不是没有解决方案,蔑视在网络上乱叫的人。。。
|