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这个脚要高电平还是低电平复位呢?
谢谢!
我看了规格书,是不是要先禁止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------------- wanglituan1112 发表于 2024-11-7 09:11
我看了规格书,是不是要先禁止I2C,再启动?改成如下
//--------V14 add----------
I2CCFG = 0 ...
重启i2c应该是可以的。
不过主机如果是发送数据过程中卡死,会导致i2c卡在等待函数中。
建议把i2c重启放在等待函数中,检测到等待函数中等待时间过长就对i2c重启 我按上面的方式试了,也还不行。等待函数是哪个位置呢?
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;
} wanglituan1112 发表于 2024-11-7 10:32
我按上面的方式试了,也还不行。等待函数是哪个位置呢?
if (I2CSLST & 0x40)
{
就是wait()函数,里面有个while的等待。
中断是指触发信号后进入的。
大部分i2c掉线都是不会触发中断的。仿真会显示直接卡死在wait中 王昱顺 发表于 2024-11-7 10:52
就是wait()函数,里面有个while的等待。
中断是指触发信号后进入的。
大部分i2c掉线都是不会触发中断的 ...
我现在用的是查询I2C从模式,没有wait()函数; wanglituan1112 发表于 2024-11-7 12:01
我现在用的是查询I2C从模式,没有wait()函数;
奥,忘记了,你这个是i2c从机模式
建议可以用更简单的方法,比如从接受start信号开始使能,接受stop信号算作结束。中间增加一个软件计时,发现io无电平变化的时候就开始计时,发现有数据中断的时候就清空。
如果计时超过某个数,可以视为通讯卡死。此时将i2c关闭再重新开启。防止被时序混乱卡住 解决了吗 主机断电我这边能识别到,那是不是可以识别到主机断电后下如下指令。
I2CSLST &= ~0x08; //处理STOP事件
因为主机开机后的I2C又正常了,不知道上面的指令能否结束前面的I2C通信? 王昱顺 发表于 2024-11-7 12:58
奥,忘记了,你这个是i2c从机模式
建议可以用更简单的方法,比如从接受start信号开始使能,接受stop信号 ...
就是主机突然断电,没有stop信号。
页:
[1]
2