rocky 发表于 2023-1-10 11:16:14

STC8H3K64S2 I2C从模式时,不回应ACK

初如化代码如下:


void        I2C_config(void)
{
I2C_InitTypeDef                I2C_InitStructure;
I2C_InitStructure.I2C_Mode      = I2C_Mode_Slave;                //Ö÷´ÓÑ¡Ôñ   I2C_Mode_Master, I2C_Mode_Slave
I2C_InitStructure.I2C_Enable    = ENABLE;                                                //I2C¹¦ÄÜʹÄÜ,   ENABLE, DISABLE
I2C_InitStructure.I2C_SL_ESTAI= ENABLE;                                                //´Ó»ú½ÓÊÕSTARTÐźÅÖжÏʹÄÜ,ENABLE, DISABLE
I2C_InitStructure.I2C_SL_ERXI   = ENABLE;                                                //´Ó»ú½ÓÊÕ1×Ö½ÚÊý¾ÝÖжÏʹÄÜ,ENABLE, DISABLE
I2C_InitStructure.I2C_SL_ETXI   = ENABLE;                                                //´Ó»ú·¢ËÍ1×Ö½ÚÊý¾ÝÖжÏʹÄÜ,ENABLE, DISABLE
I2C_InitStructure.I2C_SL_ESTOI= ENABLE;                                                //´Ó»ú½ÓÊÕSTOPÐźÅÖжÏʹÄÜ,   ENABLE, DISABLE
I2C_InitStructure.I2C_SL_MA   = ENABLE;                                                //ʹÄÜ´Ó»úµØÖ·±È½Ï¹¦ÄÜ,   ENABLE, DISABLE
I2C_InitStructure.I2C_SL_ADR    = 0x4C;                                                        //´Ó»úÉ豸µØÖ·,0~127(0x2d<<1 = 0x5a)
I2C_InitStructure.I2C_IoUse   = I2C_P33_P32;                        //IO¿ÚÇл»   I2C_P14_P15, I2C_P24_P25, I2C_P33_P32

I2C_Init(&I2C_InitStructure);
}


中断函数如下:


u8   tttt=0x00;

void I2C_Isr() interrupt I2C_VECTOR
{
char store;       
static index =0;

store = P_SW2;
P_SW2 |= 0x80;
tttt = I2CSLST;
       
if (I2CSLST & 0x40)
{
    I2CSLST &= ~0x41;                     //I2C START SIGNAL
    index=0;
}
else if (I2CSLST & 0x20)                  // RECEIVED 1 byte from host
{
    I2CSLST &= ~0x21;
    I2C_Buffer = I2CRXD;
    if (I2CIsr.is_reg_addr)
    {
      I2CIsr.is_reg_addr = 0;
    }
    else if (I2CIsr.isma)
    {
      I2CIsr.isma = 0;
    }
    else
    {
    }
}
else if (I2CSLST & 0x10)
{
    I2CSLST &= ~0x10;                     //???¨ªSEND????
    if (I2CSLST & 0x02)
    {
      I2CTXD = 0xff;
    }
    else
    {
      I2CTXD = I2C_Buffer[++I2CIsr.addr];
    }
}
else if (I2CSLST & 0x08)
{
    I2CSLST &= ~0x08;                     //???¨ªSTOP????
    I2CIsr.is_reg_addr = 1;
    I2CIsr.isma = 1;
}
P_SW2 = store;       
tttt = I2CSLST;
}


最后我用逻辑仪抓到的波形如下:



芯片没有回应主机的设备地址的ACK, 求解决办法


rocky 发表于 2023-1-10 11:17:49

我这边要监控的I2C设备地址是
I2C_InitStructure.I2C_SL_ADR    = 0x4C;      
就算我把 I2C_InitStructure.I2C_SL_MA 改成DISABLE,
一样没有ACK回应主机。

乘风飞扬 发表于 2023-1-10 13:27:23

中断函数里面最后两条代码的顺序调换一下:

P_SW2 = store;      
tttt = I2CSLST;改成:
tttt = I2CSLST;
P_SW2 = store;因为I2C的寄存器是扩展寄存器,读写前需要设置扩展寄存器访问使能,所以 I2CSLST 读取代码需要放在 P_SW2 的扩展寄存器使能位被恢复之前。

梁工 发表于 2023-1-10 14:31:26

P_SW2 |= 0x80;
程序已开始设置这一句,后面都不需要设置了。

rocky 发表于 2023-1-10 14:59:57

tttt = I2CSLST;

这一行本来就没有的,是我调试时,为了查看 I2CSLST寄存的值 加进去的。没加之前,也没有ACK出来。



rocky 发表于 2023-1-10 15:02:57

另外补充一下 IO的初始化,I2C从模式,用的是 P3.3 /P3.2这两个脚,这两个IO口,我用的是芯片默认值 ,没有额外初始化,是否有问题



void IO_init()
{
GPIO_InitTypeDef GPIO_InitStructure;

GPIO_InitStructure.Pin= GPIO_Pin_All;
GPIO_InitStructure.Mode = GPIO_HighZ;
GPIO_Inilize(GPIO_P0, &GPIO_InitStructure);
GPIO_Inilize(GPIO_P1, &GPIO_InitStructure);
GPIO_Inilize(GPIO_P2, &GPIO_InitStructure);
GPIO_Inilize(GPIO_P4, &GPIO_InitStructure);
GPIO_Inilize(GPIO_P5, &GPIO_InitStructure);

GPIO_InitStructure.Pin= GPIO_Pin_2 | GPIO_Pin_6 | GPIO_Pin_7;
GPIO_InitStructure.Mode = GPIO_OUT_PP;
GPIO_Inilize(GPIO_P0, &GPIO_InitStructure);

GPIO_InitStructure.Pin= GPIO_Pin_1 | GPIO_Pin_7;
GPIO_InitStructure.Mode = GPIO_OUT_PP;
GPIO_Inilize(GPIO_P1, &GPIO_InitStructure);

GPIO_InitStructure.Pin= GPIO_Pin_1 |GPIO_Pin_3 |GPIO_Pin_5;;
GPIO_InitStructure.Mode = GPIO_OUT_PP;
GPIO_Inilize(GPIO_P2, &GPIO_InitStructure);

GPIO_InitStructure.Pin=GPIO_Pin_4 | GPIO_Pin_2 ;
GPIO_InitStructure.Mode = GPIO_PullUp;
GPIO_Inilize(GPIO_P2, &GPIO_InitStructure);

GPIO_InitStructure.Pin= GPIO_Pin_4;
GPIO_InitStructure.Mode = GPIO_OUT_PP;
GPIO_Inilize(GPIO_P3, &GPIO_InitStructure);

GPIO_InitStructure.Pin= GPIO_Pin_3 | GPIO_Pin_7;
GPIO_InitStructure.Mode = GPIO_OUT_PP;
GPIO_Inilize(GPIO_P4, &GPIO_InitStructure);

GPIO_InitStructure.Pin=GPIO_Pin_0 | GPIO_Pin_1;
GPIO_InitStructure.Mode = GPIO_OUT_PP;
GPIO_Inilize(GPIO_P5, &GPIO_InitStructure);

GPIO_InitStructure.Pin= GPIO_Pin_3 | GPIO_Pin_2;                        //Ö¸¶¨Òª³õʼ»¯µÄIO, GPIO_Pin_0 ~ GPIO_Pin_7, »ò²Ù×÷
GPIO_InitStructure.Mode = GPIO_PullUp;                        //Ö¸¶¨IOµÄÊäÈë»òÊä³ö·½Ê½,GPIO_PullUp,GPIO_HighZ,GPIO_OUT_OD,GPIO_OUT_PP
GPIO_Inilize(GPIO_P4, &GPIO_InitStructure);        //³õʼ»¯

//GPIO_InitStructure.Pin= GPIO_Pin_3 | GPIO_Pin_2;                       //Ö¸¶¨Òª³õʼ»¯µÄIO, GPIO_Pin_0 ~ GPIO_Pin_7, »ò²Ù×÷
//GPIO_InitStructure.Mode = GPIO_HighZ;                        //Ö¸¶¨IOµÄÊäÈë»òÊä³ö·½Ê½,GPIO_PullUp,GPIO_HighZ,GPIO_OUT_OD,GPIO_OUT_PP
//GPIO_Inilize(GPIO_P3, &GPIO_InitStructure);        //³õʼ»¯
}

rocky 发表于 2023-1-10 15:10:13

P3.3 /P3.2这两个脚 要特别配置不?

rocky 发表于 2023-1-10 15:56:46

可以了,最主要的是SDA脚的配置成 GPIO_PullUp

GPIO_InitStructure.Pin= GPIO_Pin_3 ;                      
GPIO_InitStructure.Mode = GPIO_PullUp;       
GPIO_Inilize(GPIO_P3, &GPIO_InitStructure);

梁工 发表于 2023-1-10 16:10:19

I2C的IO基本都是配置成准双向口,再开通内部附加的4K电阻或外接5.1K上拉电阻。

神农鼎 发表于 2023-1-10 17:22:30

开漏 + 外部上拉或打开内部上拉
页: [1]
查看完整版本: STC8H3K64S2 I2C从模式时,不回应ACK