发新帖我要提问
12
返回列表
打印
[STM8]

STM8 硬件 i2c 问题

[复制链接]
楼主: f781831
手机看帖
扫描二维码
随时随地手机跟帖
21
feelhyq| | 2017-6-20 15:30 | 只看该作者 回帖奖励 |倒序浏览
f781831 发表于 2017-6-20 15:27
是啊 一帧 8个字节  速度100k  的时候第一帧8字节都收到了 然后第二帧 只收到第一个字节 SDA 和SCL 线都 ...

SCL是在空闲的时候被拉低是正常的。

使用特权

评论回复
22
f781831|  楼主 | 2017-6-20 15:34 | 只看该作者
feelhyq 发表于 2017-6-20 15:29
自己写个弄个I2C主机 不用维图的,对比下就出来了。

嗯 可以 试试 谢谢你

使用特权

评论回复
23
f781831|  楼主 | 2017-6-20 15:39 | 只看该作者
feelhyq 发表于 2017-6-20 15:29
自己写个弄个I2C主机 不用维图的,对比下就出来了。

我现在还有个问题没搞明白 就是 从站 MCU 把SCL线拉低了

使用特权

评论回复
24
feelhyq| | 2017-6-20 15:44 | 只看该作者
f781831 发表于 2017-6-20 15:39
我现在还有个问题没搞明白 就是 从站 MCU 把SCL线拉低了

时钟CLK都是由主机去产生的,从机是被动地去接收这个时钟,利用时钟将从机数据寄存器里面的数据推出来。

使用特权

评论回复
25
feelhyq| | 2017-6-20 15:44 | 只看该作者
f781831 发表于 2017-6-20 15:39
我现在还有个问题没搞明白 就是 从站 MCU 把SCL线拉低了

你怎么确认是从机把CLK拉低了呢

使用特权

评论回复
26
f781831|  楼主 | 2017-6-21 13:26 | 只看该作者
feelhyq 发表于 2017-6-20 15:44
你怎么确认是从机把CLK拉低了呢

将主机和从机断开连接, 主机的SCL SDA线都为高 。。

使用特权

评论回复
27
f781831|  楼主 | 2017-6-21 13:28 | 只看该作者
我今天发现 当我出错的时候 SR1寄存器的RXNE ,STOPF位都被置1了

使用特权

评论回复
28
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;
        }
       
}

使用特权

评论回复
29
feelhyq| | 2017-6-21 16:31 | 只看该作者
官方给的例子都是demo,我们公司和ST公司一样也是做芯片的,也是基于cortex-M3,cortex-M4的内核做的芯片,平时我就是调芯片驱动这块。

使用特权

评论回复
30
f781831|  楼主 | 2017-6-21 16:40 | 只看该作者
feelhyq 发表于 2017-6-21 16:31
官方给的例子都是demo,我们公司和ST公司一样也是做芯片的,也是基于cortex-M3,cortex-M4的内核做的芯片, ...

速度快起来的时候  RXNE 和STOPF这两位一起被置了 是不是有问题的 能给我做些解释嘛 不是很懂

使用特权

评论回复
31
feelhyq| | 2017-6-21 16:52 | 只看该作者
f781831 发表于 2017-6-21 16:40
速度快起来的时候  RXNE 和STOPF这两位一起被置了 是不是有问题的 能给我做些解释嘛 不是很懂  ...

STM32公司用 I2C外设IP跟我们公司用的I2C外设IP不一样,只有STM32公司提供了他们芯片I2C verilog代码后,我们通过时序分析才能定位问题,否则我跟你一样,获取到的信息只能从STM8的芯片手册上面来

使用特权

评论回复
32
Jay_1989| | 2017-6-21 17:41 | 只看该作者
I2C slave 中断响应不过来。 你的I2C主机不支持SCL sync的话,那就在主机的每个Byte之间加入软件delay, 给slave CPU响应中断的时间。不是太清楚你现在用的slave支不支持stretch。

使用特权

评论回复
33
Jay_1989| | 2017-6-21 17:44 | 只看该作者
波特率可以到400K, 但是从机往往吞吐量都到不了400K。slave在收完一Byte后CPU响应中断处理中断都需要时间。

使用特权

评论回复
34
f781831|  楼主 | 2017-6-22 08:23 | 只看该作者
Jay_1989 发表于 2017-6-21 17:44
波特率可以到400K, 但是从机往往吞吐量都到不了400K。slave在收完一Byte后CPU响应中断处理中断都需要时间 ...

是啊  发现只有主机速度为5kbps的时候 SR1寄存器才不会同时出现两个状态被置位。这算是这个硬件I2C的BUG么

使用特权

评论回复
35
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是否支持。

使用特权

评论回复
36
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同时置位在硬件上来讲是合理的。

使用特权

评论回复
37
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都是硬件的行为。

使用特权

评论回复
38
Jay_1989| | 2017-6-22 10:49 | 只看该作者
Jay_1989 发表于 2017-6-22 10:42
量产的IC一般不会有这么低级的BUG的。RXNE=1和STOPF=1应该是你接收到的最后一byte数据(或者包括前几Byte) ...

看一下slave有没有发生溢出(过载/欠载)错误

使用特权

评论回复
39
f781831|  楼主 | 2017-6-30 09:20 | 只看该作者
Jay_1989 发表于 2017-6-22 10:49
看一下slave有没有发生溢出(过载/欠载)错误

当时 数据能正常交互后,就没有再仔细深究下去了,发生溢出(过载/欠载)错误的话,哪个寄存器的哪个标志位能反应出这个问题呢?

使用特权

评论回复
40
lh18753385| | 2017-7-19 20:24 | 只看该作者
能力有限,不敢用硬件的I2C

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则