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, 求解决办法
我这边要监控的I2C设备地址是
I2C_InitStructure.I2C_SL_ADR = 0x4C;
就算我把 I2C_InitStructure.I2C_SL_MA 改成DISABLE,
一样没有ACK回应主机。
中断函数里面最后两条代码的顺序调换一下:
P_SW2 = store;
tttt = I2CSLST;改成:
tttt = I2CSLST;
P_SW2 = store;因为I2C的寄存器是扩展寄存器,读写前需要设置扩展寄存器访问使能,所以 I2CSLST 读取代码需要放在 P_SW2 的扩展寄存器使能位被恢复之前。
P_SW2 |= 0x80;
程序已开始设置这一句,后面都不需要设置了。 tttt = I2CSLST;
这一行本来就没有的,是我调试时,为了查看 I2CSLST寄存的值 加进去的。没加之前,也没有ACK出来。
另外补充一下 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); //³õʼ»¯
} P3.3 /P3.2这两个脚 要特别配置不? 可以了,最主要的是SDA脚的配置成 GPIO_PullUp
GPIO_InitStructure.Pin= GPIO_Pin_3 ;
GPIO_InitStructure.Mode = GPIO_PullUp;
GPIO_Inilize(GPIO_P3, &GPIO_InitStructure); I2C的IO基本都是配置成准双向口,再开通内部附加的4K电阻或外接5.1K上拉电阻。 开漏 + 外部上拉或打开内部上拉
页:
[1]