[STM8] STM8 硬件 i2c 问题

[复制链接]
4698|39
feelhyq 发表于 2017-6-20 15:30 | 显示全部楼层
f781831 发表于 2017-6-20 15:27
是啊 一帧 8个字节  速度100k  的时候第一帧8字节都收到了 然后第二帧 只收到第一个字节 SDA 和SCL 线都 ...

SCL是在空闲的时候被拉低是正常的。
 楼主| f781831 发表于 2017-6-20 15:34 | 显示全部楼层
feelhyq 发表于 2017-6-20 15:29
自己写个弄个I2C主机 不用维图的,对比下就出来了。

嗯 可以 试试 谢谢你
 楼主| f781831 发表于 2017-6-20 15:39 | 显示全部楼层
feelhyq 发表于 2017-6-20 15:29
自己写个弄个I2C主机 不用维图的,对比下就出来了。

我现在还有个问题没搞明白 就是 从站 MCU 把SCL线拉低了
feelhyq 发表于 2017-6-20 15:44 | 显示全部楼层
f781831 发表于 2017-6-20 15:39
我现在还有个问题没搞明白 就是 从站 MCU 把SCL线拉低了

时钟CLK都是由主机去产生的,从机是被动地去接收这个时钟,利用时钟将从机数据寄存器里面的数据推出来。
feelhyq 发表于 2017-6-20 15:44 | 显示全部楼层
f781831 发表于 2017-6-20 15:39
我现在还有个问题没搞明白 就是 从站 MCU 把SCL线拉低了

你怎么确认是从机把CLK拉低了呢
 楼主| f781831 发表于 2017-6-21 13:26 | 显示全部楼层
feelhyq 发表于 2017-6-20 15:44
你怎么确认是从机把CLK拉低了呢

将主机和从机断开连接, 主机的SCL SDA线都为高 。。
 楼主| f781831 发表于 2017-6-21 13:28 | 显示全部楼层
我今天发现 当我出错的时候 SR1寄存器的RXNE ,STOPF位都被置1了
 楼主| f781831 发表于 2017-6-21 16:10 | 显示全部楼层
感觉可以结贴了 主要发现两个问题1.在传输过程中,特别当速度快的时候,当从机处于接收状态时, 有些时候,SR1寄存器中RXNE和STOPF两个状态位同时被置1,不知道这种情况是不是被允许的,然而官方给的示例代码里没有对这种状态进行处理,导致I2C传输失败;当从机处于发送状态时,SR1寄存器中BTF和TXE两个状态位同时被置1,相同的,官方给的示例代码里没有对这种状态进行处理,导致I2C传输失败。
下面是官方给的中断中的示例代码,其中default中的内容为我修改的内容,主要是对传输过程中,SR1寄存器中有两个状态位同时被置的处理。经修改后,能正常通信。但是不知道是不是真的是这个问题,希望大虾们拍砖。
void bsp_i2c_slave_received_for_isr(void){
        //static uint8_t a=0;
        /* Read SR2 register to get I2C error */
        if ((I2C->SR2) != 0)
        {
        /* Clears SR2 register */
        I2C->SR2 = 0;

        }
        i2c_slave.Event = I2C_GetLastEvent();
        switch (i2c_slave.Event)
        {
          /******* Slave transmitter ******/
          /* check on EV1 */
        case I2C_EVENT_SLAVE_TRANSMITTER_ADDRESS_MATCHED:
          i2c_slave.Tx_Idx = 0;
          break;

          /* check on EV3 */
        case I2C_EVENT_SLAVE_BYTE_TRANSMITTING:
          /* Transmit data */
          I2C_SendData(i2c_slave.Slave_Buffer_Rx[i2c_slave.Tx_Idx++]);
          break;
          /******* Slave receiver **********/
          /* check on EV1*/
        case I2C_EVENT_SLAVE_RECEIVER_ADDRESS_MATCHED:
          break;

          /* Check on EV2*/
        case I2C_EVENT_SLAVE_BYTE_RECEIVED:
          i2c_slave.Slave_Buffer_Rx[i2c_slave.Rx_Idx++] = I2C_ReceiveData();
         
          break;

          /* Check on EV4 */
        case (I2C_EVENT_SLAVE_STOP_DETECTED):
                        /* write to CR2 to clear STOPF flag */
                        I2C->CR2 |= I2C_CR2_ACK;

          break;

        default:
          if ((I2C->SR1&0x40) != 0)
          {
          /* Clears SR2 register */
            i2c_slave.Slave_Buffer_Rx[i2c_slave.Rx_Idx++] = I2C_ReceiveData();

          }
          if ((I2C->SR1&0x04) != 0)
          {
          /* Clears SR2 register */
            I2C_SendData(i2c_slave.Slave_Buffer_Rx[i2c_slave.Tx_Idx++]);

          }
          break;
        }
       
}
feelhyq 发表于 2017-6-21 16:31 | 显示全部楼层
官方给的例子都是demo,我们公司和ST公司一样也是做芯片的,也是基于cortex-M3,cortex-M4的内核做的芯片,平时我就是调芯片驱动这块。
 楼主| f781831 发表于 2017-6-21 16:40 | 显示全部楼层
feelhyq 发表于 2017-6-21 16:31
官方给的例子都是demo,我们公司和ST公司一样也是做芯片的,也是基于cortex-M3,cortex-M4的内核做的芯片, ...

速度快起来的时候  RXNE 和STOPF这两位一起被置了 是不是有问题的 能给我做些解释嘛 不是很懂
feelhyq 发表于 2017-6-21 16:52 | 显示全部楼层
f781831 发表于 2017-6-21 16:40
速度快起来的时候  RXNE 和STOPF这两位一起被置了 是不是有问题的 能给我做些解释嘛 不是很懂  ...

STM32公司用 I2C外设IP跟我们公司用的I2C外设IP不一样,只有STM32公司提供了他们芯片I2C verilog代码后,我们通过时序分析才能定位问题,否则我跟你一样,获取到的信息只能从STM8的芯片手册上面来
Jay_1989 发表于 2017-6-21 17:41 | 显示全部楼层
I2C slave 中断响应不过来。 你的I2C主机不支持SCL sync的话,那就在主机的每个Byte之间加入软件delay, 给slave CPU响应中断的时间。不是太清楚你现在用的slave支不支持stretch。
Jay_1989 发表于 2017-6-21 17:44 | 显示全部楼层
波特率可以到400K, 但是从机往往吞吐量都到不了400K。slave在收完一Byte后CPU响应中断处理中断都需要时间。
 楼主| f781831 发表于 2017-6-22 08:23 | 显示全部楼层
Jay_1989 发表于 2017-6-21 17:44
波特率可以到400K, 但是从机往往吞吐量都到不了400K。slave在收完一Byte后CPU响应中断处理中断都需要时间 ...

是啊  发现只有主机速度为5kbps的时候 SR1寄存器才不会同时出现两个状态被置位。这算是这个硬件I2C的BUG么
 楼主| f781831 发表于 2017-6-22 08:28 | 显示全部楼层
Jay_1989 发表于 2017-6-21 17:41
I2C slave 中断响应不过来。 你的I2C主机不支持SCL sync的话,那就在主机的每个Byte之间加入软件delay, 给s ...

主机的话 用的是一个上位机工具,好像没有延时设置,你说的slave stretch是什么意思。我也不知道stm8s003的硬件I2C是否支持。
Jay_1989 发表于 2017-6-22 10:42 | 显示全部楼层
f781831 发表于 2017-6-22 08:23
是啊  发现只有主机速度为5kbps的时候 SR1寄存器才不会同时出现两个状态被置位。这算是这个硬件I2C的BUG ...

量产的IC一般不会有这么低级的BUG的。RXNE=1和STOPF=1应该是你接收到的最后一byte数据(或者包括前几Byte)CPU没来得及读走,master又在Bus上发送了stop信号。 这两个flag同时置位在硬件上来讲是合理的。
Jay_1989 发表于 2017-6-22 10:47 | 显示全部楼层
f781831 发表于 2017-6-22 08:28
主机的话 用的是一个上位机工具,好像没有延时设置,你说的slave stretch是什么意思。我也不知道stm8s003 ...

粗略看了下STM8的手册,slave硬件上支持SCL stretch。stretch就是slave在接收到的数据没有读走/发送的新数据没有写入  之前slave硬件会主动拉低SCL。 而master想继续下一byte数据传输时,由于检测到SCL一直为低电平,所以master会等待。等待SCL变为高电平后再继续传输,这是master的时钟同步(SCL sync)。slave的stretch和master的SCL sync都是硬件的行为。
Jay_1989 发表于 2017-6-22 10:49 | 显示全部楼层
Jay_1989 发表于 2017-6-22 10:42
量产的IC一般不会有这么低级的BUG的。RXNE=1和STOPF=1应该是你接收到的最后一byte数据(或者包括前几Byte) ...

看一下slave有没有发生溢出(过载/欠载)错误
 楼主| f781831 发表于 2017-6-30 09:20 | 显示全部楼层
Jay_1989 发表于 2017-6-22 10:49
看一下slave有没有发生溢出(过载/欠载)错误

当时 数据能正常交互后,就没有再仔细深究下去了,发生溢出(过载/欠载)错误的话,哪个寄存器的哪个标志位能反应出这个问题呢?
lh18753385 发表于 2017-7-19 20:24 | 显示全部楼层
能力有限,不敢用硬件的I2C
您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 在线客服 返回列表 返回顶部