Part Number:HDC2080
发送从机设备地址,有ACK响应,继续发送寄存器地址,此时无ACK响应
Kailyn Chen:
您好,您详细说一下吗? 是每个寄存器地址发送完之后都收不到ACK吗?
时序附上我这边看下。
,
tangziyu tang:
下午好,是发送每个寄存器地址都无ACK应答,这是时序图,麻烦帮忙看看,谢谢!
,
tangziyu tang:
你好,还在吗
,
Kailyn Chen:
好的,还在,我看下您的时序图哈。
,
tangziyu tang:
好的,这很奇怪,如果需要电路图我也可以发给你
,
Kailyn Chen:
从机地址1000000,最后一位为0,说明是写。
然后我看了下ACK之后,寄存器地址为0x00,可是这个寄存器是只读寄存器。0x00-0x03都是只读寄存器。您尝试配置其他可写的寄存器再试试呢 。
,
tangziyu tang:
读的时序是:SA(W) + REG + SA(R),所以是先发送写的地址,之后再发送读地址。尝试过所有寄存器地址,都是NACK
,
Kailyn Chen:
那如果先写,后读的话。时序应该这样的: Start–slave address(W)——ACK——RegisterAddress—ACK—data—ACK—Repeat start———slave address(R)–ACK–Register address–ACK—Data—NACK—Stop
那目前先不说写完后读的时序 ,只是先进行写的时序,从机地址Start–slave address(W)——ACK——RegisterAddress—ACK—data—ACK-这个过程,再Register Address之后就没有收到ACK对吧?
另外,就是HDC2080上电稳定之后,至少需要等3ms的delay,在进行I2C通讯。这个上电时序保证了吗?
,
tangziyu tang:
是发送Register Address之后就无应答了,确保是上电稳定之后再通讯的,目前板子没有跑程序,就只是在测试I2C通讯
,
Kailyn Chen:
如果上电没问题,那么建议在从机地址收到ACK之后,先写0x0E=00,使得器件进入normal operation mode。
麻烦您写0x0E地址之后,把时序附上,我这边再看下。
,
tangziyu tang:
早上好!
上图是往0x0E中写0x00的时序图,仍然是寄存器无ACK应答,电路图也附上,请帮忙看看,谢谢!
,
Kailyn Chen:
SDA和SCL都通过上拉电阻上拉到VDD了吗?这两个引脚是开漏输出,需要上拉。
,
tangziyu tang:
已经上拉了的,I2C总线上挂了几个从设备,其他通讯都是正常的,可以排除I2C的问题,实在是不知道为啥了….
,
Kailyn Chen:
是的,一般从机地址能收到ACK的话,不会因寄存器地址收不到ACK的。
总线上挂接了几个从设备?方便断开下,单独测试下HDC2080吗?因为I2C总线受电容负载的限制,如果从机数比较多,再加上layout的寄生电容大致容性负载过大,也是会导致通信问题的。
,
tangziyu tang:
其他的从设备刚刚全部拆掉了,还是一样的,好像也不是电容负载影响的。
,
tangziyu tang:
void hdc2080_read(uint8_t *pbuf, uint8_t length, HDL_IIC_RES *Res )
{
int i2c_false_flag = false;
/* send a start condition to I2C bus */
i2c_start_on_bus(I2C0);/* wait until SBSEND bit is set */
while(!i2c_flag_get(I2C0, I2C_FLAG_SBSEND));/* send slave address to I2C bus */
i2c_master_addressing(I2C0, Res->SLAVE_ADDR, I2C_RECEIVER);/* wait until ADDSEND bit is set */
while(!i2c_flag_get(I2C0, I2C_FLAG_ADDSEND))
{
static int num = 0;
num++;
if(num == 10000)
{
num = 0;
i2c_false_flag = true;
goto read_false;
}
}/* clear the ADDSEND bit */
i2c_flag_clear(I2C0,I2C_FLAG_ADDSEND);if(1 == length){
/* send a stop condition to I2C bus */
i2c_stop_on_bus(I2C0);
}/* while there is data to be read */
while(length){
if(3 == length){
/* wait until BTC bit is set */
while(!i2c_flag_get(I2C0, I2C_FLAG_BTC));/* disable acknowledge */
i2c_ack_config(I2C0,I2C_ACK_DISABLE);
}
if(2 == length){
/* wait until BTC bit is set */
while(!i2c_flag_get(I2C0, I2C_FLAG_BTC));/* send a stop condition to I2C bus */
i2c_stop_on_bus(I2C0);
}/* wait until the RBNE bit is set and clear it */
if(i2c_flag_get(I2C0, I2C_FLAG_RBNE)){
/* read a byte from the EEPROM */
*pbuf = i2c_data_receive(I2C0);/* point to the next location where the byte read will be saved */
pbuf++;/* decrement the read bytes counter */
length–;
}
}/* wait until the stop condition is finished */
while(I2C_CTL0(I2C0)&0x0200);/* enable acknowledge */
i2c_ack_config(I2C0,I2C_ACK_ENABLE);i2c_ackpos_config(I2C0,I2C_ACKPOS_CURRENT);
read_false:
if(i2c_false_flag == true)
{
*pbuf = 0x00;
/* send a stop condition to I2C bus */
i2c_stop_on_bus(I2C0);/* wait until the stop condition is finished */
while(I2C_CTL0(I2C0)&0x0200);}
}这是我们其他芯片关于hdc2080的I2C读代码,我看了好像没有发送寄存器地址,感觉很奇怪
,
Kailyn Chen:
这个应该是不对的,没有寄存器地址,怎么去读取寄存器的值。
并且数据手册中也给出读写时序:
您改一下从机地址再试试,比如将ADDR接到VDD。