wanglituan1112 发表于 2024-11-7 09:01:52

I2C通讯异常后重新配置问题

本帖最后由 DebugLab 于 2024-11-7 10:46 编辑

单片机型号:AI8H8K64U,24M

应用:I2C从机模式查询模式
问题:主机发送过来的I2C数据可能就断电异常了,但是STC单片机这边是一直通电,当主机重启后重新发送I2C数据过来前面的数据会丢失。
希望的解决方式:STC可以检测到主机掉电,这时可以重新对I2C配置,按如下配置还是会有问题,看下哪里的问题?

                  P_SW2 = 0x80;
                  I2CCFG = 0x81;                              //使能I2C从机模式
                  I2CSLADR = 0x8a;                            //设置从机设备地址寄存器I2CSLADR=0101_1010B
                                                                //即I2CSLADR=010_1101B,MA=0B。
                                                                //由于MA为0,主机发送的的设备地址必须与
                                                                //I2CSLADR相同才能访问此I2C从机设备。
                                                                //主机若需要写数据则要发送5AH(0101_1010B)
                                                                //主机若需要读数据则要发送5BH(0101_1011B)
                  I2CSLST = 0x00;
                  I2CSLCR = 0x00;                           //禁止从机模式中断



SLRST这个脚要高电平还是低电平复位呢?


谢谢!

wanglituan1112 发表于 2024-11-7 09:11:09

我看了规格书,是不是要先禁止I2C,再启动?改成如下
                  //--------V14 add----------
                  I2CCFG = 0x01;                        //禁止I2C
                        delay_us(10);

                  P_SW2 = 0x80;
                  I2CCFG = 0x81;                              //使能I2C从机模式
                  I2CSLADR = 0x8a;                            //设置从机设备地址寄存器I2CSLADR=0101_1010B
                                                                //即I2CSLADR=010_1101B,MA=0B。
                                                                //由于MA为0,主机发送的的设备地址必须与
                                                                //I2CSLADR相同才能访问此I2C从机设备。
                                                                //主机若需要写数据则要发送5AH(0101_1010B)
                                                                //主机若需要读数据则要发送5BH(0101_1011B)
                  I2CSLST = 0x00;
                  I2CSLCR = 0x00;                           //禁止从机模式中断
                        //--------V14-------------

王昱顺 发表于 2024-11-7 10:28:55

wanglituan1112 发表于 2024-11-7 09:11
我看了规格书,是不是要先禁止I2C,再启动?改成如下
                  //--------V14 add----------
                  I2CCFG = 0 ...

重启i2c应该是可以的。
不过主机如果是发送数据过程中卡死,会导致i2c卡在等待函数中。
建议把i2c重启放在等待函数中,检测到等待函数中等待时间过长就对i2c重启

wanglituan1112 发表于 2024-11-7 10:32:07

我按上面的方式试了,也还不行。等待函数是哪个位置呢?
      if (I2CSLST & 0x40)
      {
            I2CSLST &= ~0x40;                   //处理START事件
      }
      else if (I2CSLST & 0x20)
      {
            I2CSLST &= ~0x20;                   //处理RECV事件
            if (isda)
            {
                isda = 0;                     //处理RECV事件(RECV DEVICE ADDR)
            }
            else if (isma)
            {
                isma = 0;                     //处理RECV事件(RECV MEMORY ADDR)
                //if(power_flash==1)
                                addr=0;//要这样处理才行,只接收前面2个数据
                       
                                buffer=I2CRXD;
                                addr++;
            }
            else
            {
                                buffer = I2CRXD;      //处理RECV事件(RECV DATA)
                //buffer = I2CRXD;      //处理RECV事件(RECV DATA)
                addr++;
            }
      }
      else if (I2CSLST & 0x10)
      {
            I2CSLST &= ~0x10;                   //处理SEND事件
            if (I2CSLST & 0x02)
            {
                I2CTXD = 0xff;                  //接收到NAK则停止读取数据
            }
            else
            {
                I2CTXD = buffer;      //接收到ACK则继续读取数据
            }
      }
      
      else if (I2CSLST & 0x08)
      {
            I2CSLST &= ~0x08;                   //处理STOP事件
            isda = 1;
            isma = 1;
      }

王昱顺 发表于 2024-11-7 10:52:16

wanglituan1112 发表于 2024-11-7 10:32
我按上面的方式试了,也还不行。等待函数是哪个位置呢?
      if (I2CSLST & 0x40)
      {


就是wait()函数,里面有个while的等待。
中断是指触发信号后进入的。
大部分i2c掉线都是不会触发中断的。仿真会显示直接卡死在wait中

wanglituan1112 发表于 2024-11-7 12:01:07

王昱顺 发表于 2024-11-7 10:52
就是wait()函数,里面有个while的等待。
中断是指触发信号后进入的。
大部分i2c掉线都是不会触发中断的 ...

我现在用的是查询I2C从模式,没有wait()函数;

王昱顺 发表于 2024-11-7 12:58:56

wanglituan1112 发表于 2024-11-7 12:01
我现在用的是查询I2C从模式,没有wait()函数;

奥,忘记了,你这个是i2c从机模式
建议可以用更简单的方法,比如从接受start信号开始使能,接受stop信号算作结束。中间增加一个软件计时,发现io无电平变化的时候就开始计时,发现有数据中断的时候就清空。
如果计时超过某个数,可以视为通讯卡死。此时将i2c关闭再重新开启。防止被时序混乱卡住

wlhet 发表于 2024-11-7 13:06:17

解决了吗

wanglituan1112 发表于 2024-11-7 13:42:58

主机断电我这边能识别到,那是不是可以识别到主机断电后下如下指令。
I2CSLST &= ~0x08;                   //处理STOP事件

因为主机开机后的I2C又正常了,不知道上面的指令能否结束前面的I2C通信?

wanglituan1112 发表于 2024-11-7 13:43:55

王昱顺 发表于 2024-11-7 12:58
奥,忘记了,你这个是i2c从机模式
建议可以用更简单的方法,比如从接受start信号开始使能,接受stop信号 ...

就是主机突然断电,没有stop信号。
页: [1] 2
查看完整版本: I2C通讯异常后重新配置问题