找回密码
 立即注册
查看: 691|回复: 14

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

[复制链接]
已绑定手机

4

主题

12

回帖

58

积分

注册会员

积分
58
发表于 2024-11-7 09:01:52 | 显示全部楼层 |阅读模式
本帖最后由 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[7:1]=010_1101B,MA=0B。
                                                                //由于MA为0,主机发送的的设备地址必须与
                                                                //I2CSLADR[7:1]相同才能访问此I2C从机设备。
                                                                //主机若需要写数据则要发送5AH(0101_1010B)
                                                                //主机若需要读数据则要发送5BH(0101_1011B)
                    I2CSLST = 0x00;
                    I2CSLCR = 0x00;                             //禁止从机模式中断



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


谢谢!
截图202411070900153870.jpg
回复

使用道具 举报 送花

已绑定手机

4

主题

12

回帖

58

积分

注册会员

积分
58
发表于 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[7:1]=010_1101B,MA=0B。
                                                                //由于MA为0,主机发送的的设备地址必须与
                                                                //I2CSLADR[7:1]相同才能访问此I2C从机设备。
                                                                //主机若需要写数据则要发送5AH(0101_1010B)
                                                                //主机若需要读数据则要发送5BH(0101_1011B)
                    I2CSLST = 0x00;
                    I2CSLCR = 0x00;                             //禁止从机模式中断
                        //--------V14-------------

点评

重启i2c应该是可以的。 不过主机如果是发送数据过程中卡死,会导致i2c卡在等待函数中。 建议把i2c重启放在等待函数中,检测到等待函数中等待时间过长就对i2c重启  详情 回复 发表于 2024-11-7 10:28
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:458
  • 最近打卡:2025-05-01 07:48:22
已绑定手机
已实名认证

110

主题

2219

回帖

5452

积分

版主

积分
5452
发表于 2024-11-7 10:28:55 | 显示全部楼层
wanglit*** 发表于 2024-11-7 09:11
我看了规格书,是不是要先禁止I2C,再启动?改成如下
                    //--------V14 add----------
                    I2CCFG = 0 ...

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

使用道具 举报 送花

已绑定手机

4

主题

12

回帖

58

积分

注册会员

积分
58
发表于 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[addr]=I2CRXD;
                                addr++;
            }
            else
            {
                                buffer[addr] = I2CRXD;        //处理RECV事件(RECV DATA)
                //buffer[addr++] = I2CRXD;        //处理RECV事件(RECV DATA)
                addr++;
            }
        }
        else if (I2CSLST & 0x10)
        {
            I2CSLST &= ~0x10;                   //处理SEND事件
            if (I2CSLST & 0x02)
            {
                I2CTXD = 0xff;                  //接收到NAK则停止读取数据
            }
            else
            {
                I2CTXD = buffer[0];        //接收到ACK则继续读取数据
            }
        }
        
        else if (I2CSLST & 0x08)
        {
            I2CSLST &= ~0x08;                   //处理STOP事件
            isda = 1;
            isma = 1;
        }

点评

就是wait()函数,里面有个while的等待。 中断是指触发信号后进入的。 大部分i2c掉线都是不会触发中断的。仿真会显示直接卡死在wait中  详情 回复 发表于 2024-11-7 10:52
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:458
  • 最近打卡:2025-05-01 07:48:22
已绑定手机
已实名认证

110

主题

2219

回帖

5452

积分

版主

积分
5452
发表于 2024-11-7 10:52:16 | 显示全部楼层
wanglit*** 发表于 2024-11-7 10:32
我按上面的方式试了,也还不行。等待函数是哪个位置呢?
        if (I2CSLST & 0x40)
        {

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

使用道具 举报 送花

已绑定手机

4

主题

12

回帖

58

积分

注册会员

积分
58
发表于 2024-11-7 12:01:07 | 显示全部楼层
王*** 发表于 2024-11-7 10:52
就是wait()函数,里面有个while的等待。
中断是指触发信号后进入的。
大部分i2c掉线都是不会触发中断的 ...

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

点评

奥,忘记了,你这个是i2c从机模式 建议可以用更简单的方法,比如从接受start信号开始使能,接受stop信号算作结束。中间增加一个软件计时,发现io无电平变化的时候就开始计时,发现有数据中断的时候就清空。 如果计时  详情 回复 发表于 2024-11-7 12:58
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:458
  • 最近打卡:2025-05-01 07:48:22
已绑定手机
已实名认证

110

主题

2219

回帖

5452

积分

版主

积分
5452
发表于 2024-11-7 12:58:56 | 显示全部楼层
wanglit*** 发表于 2024-11-7 12:01
我现在用的是查询I2C从模式,没有wait()函数;

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

使用道具 举报 送花

  • 打卡等级:常住居民III
  • 打卡总天数:154
  • 最近打卡:2025-04-30 08:40:57
已绑定手机

15

主题

630

回帖

730

积分

高级会员

积分
730
发表于 2024-11-7 13:06:17 | 显示全部楼层
解决了吗
STC 666 888
回复

使用道具 举报 送花

已绑定手机

4

主题

12

回帖

58

积分

注册会员

积分
58
发表于 2024-11-7 13:42:58 | 显示全部楼层
主机断电我这边能识别到,那是不是可以识别到主机断电后下如下指令。
I2CSLST &= ~0x08;                   //处理STOP事件

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

点评

这个是结束不了的,因为你这个是清除中断标志位。 都没有接收到,中断来不了,何来清除一说? 需要通过关闭i2c模块再开启的方式重置一次  详情 回复 发表于 2024-11-7 17:32
回复 支持 反对

使用道具 举报 送花

已绑定手机

4

主题

12

回帖

58

积分

注册会员

积分
58
发表于 2024-11-7 13:43:55 | 显示全部楼层
王*** 发表于 2024-11-7 12:58
奥,忘记了,你这个是i2c从机模式
建议可以用更简单的方法,比如从接受start信号开始使能,接受stop信号 ...

就是主机突然断电,没有stop信号。
回复 支持 反对

使用道具 举报 送花

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|小黑屋|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2025-5-2 02:43 , Processed in 0.308671 second(s), 111 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表