21ic电子技术开发论坛
标题:
I2C读数据地址无应答,而写数据地址有应答,正常命令有应答?
[打印本页]
作者:
xueyanqin
时间:
2015-7-16 17:56
标题:
I2C读数据地址无应答,而写数据地址有应答,正常命令有应答?
请问有没有遇到过这种情形:
写操作地址有应答,而读数据时按照时序输入读地址(写地址加1),却没有应答,这是为什么?
求教,谢谢。
作者:
airwill
时间:
2015-7-16 18:11
从设备器件应该是就绪的.
我想写相对于读, 设备端存在需要数据准备的过程, 所以可能会需要一定的延迟时间
作者:
xueyanqin
时间:
2015-7-16 18:15
谢谢您
我是从示波器上看,发送完读的地址后,SDA就一直是高电平
而写的地址和命令后,SDA确实变成低电平,有应答
作者:
xueyanqin
时间:
2015-7-16 18:31
我用的是STM32F405,I2C从设备是气压传感器MS5611,它的地址是0XEE
//启动
void I2C_Start(void)
{
delay_us(10);
I2C1_SDA_SET();
I2C1_SCL_SET();
delay_us(10);
I2C1_SDA_RESET();
delay_us(10);
I2C1_SCL_RESET();
}
//***************停止**********************
void I2C_Stop(void)
{
//I2C1_SDA_OUT();
delay_us(10);
I2C1_SDA_RESET();
I2C1_SCL_RESET();
delay_us(10);
I2C1_SCL_SET();
delay_us(10);
I2C1_SDA_SET();
}
//********************获取ACK************************
uint8_t I2C_Wait_ACK(void)
{
I2C1_SDA_IN();
delay_us(10);
uint32_t sur_error;
//I2C1_SDA_SET();
delay_us(10);
sur_error = 0;
while(I2C1_READ_ACK() == 1)
{
sur_error++;
if(sur_error>500000)
{
I2C_Stop();
return 1;
}
delay_us(10);
}
return 0;
}
//**********************发送ACK***************************
void I2C_Send_ACK(uint8_t ack)
{
I2C1_SDA_OUT();
delay_us(10);
I2C1_SCL_RESET();
I2C1_SDA_SET();
delay_us(10);
if(ack == 0)
I2C1_SDA_RESET();
else
I2C1_SDA_SET();
I2C1_SCL_SET();
delay_us(10);
I2C1_SCL_RESET();
}
//*******************发送字节*******************
void I2C_Send_Byte(uint8_t Tdata)
{
I2C1_SCL_RESET();
delay_us(10);
for(uint8_t i=0;i<8;i++)
{
delay_us(10);
if((Tdata&0x80) == 0x80)
{
I2C1_SDA_SET();
}
else
{
I2C1_SDA_RESET();
}
delay_us(10);
I2C1_SCL_SET();
delay_us(10);
I2C1_SCL_RESET();
Tdata <<= 1;
}
}
我的主程序中还在用示波器调试,为了看每个波形,所以延时较长
//**********************主程序运行I2C******************
void I2C_Init(void)
{
GPIO_InitStruct.Pin = GPIO_PIN_8|GPIO_PIN_9;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF4_I2C1;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
I2C1_SDA_SET();
I2C1_SCL_SET();
//MS5611复位(这一部分很好,均有应答)
I2C_Start();
I2C_Send_Byte(MS5611_ADDRESS);
delay_us(10);
while(I2C1_READ_ACK()==1);
delay_us(10);
I2C_Send_Byte(MS5611_RESET);
delay_us(10);
while(I2C1_READ_ACK()==1);
I2C_Stop();
delay_us(10);
//*****************************************
//***********开始读取PROM值(还没做具体读数据,因为读地址没有应答)***************
I2C_Start();
I2C_Send_Byte(0xee);
delay_us(10);
while(I2C1_READ_ACK()==1);
HAL_Delay(1000);
I2C_Send_Byte(MS5611_PROM_READ);
HAL_Delay(1000);
I2C_Stop();
delay_us(1000);
I2C_Start();
I2C_Send_Byte(0xef);
delay_us(10);
while(I2C1_READ_ACK()==1); //*最后死在该处?????????????
HAL_Delay(1000);
I2C_Stop();
delay_us(10);
}
作者:
xuxuemin123123
时间:
2019-10-24 09:28
I2C的读数据帧比写数据帧内容多,写成功不能保证读就能成功。写操作地址有应答,说明I2C从设备已经准备就绪了(可以干活了)。而读数据时按照时序输入读地址(写地址加1),没有应答,可能是I2C的写时序帧不符合从设备的需求,所以从设备就不理你了。I2C的读/写帧,不同的I2C外设(从设备),可能存在区别,需要具体看相应的I2C手册(每个I2C外设都有详细的I2C通讯时序图),把正确的时序帧配置好,才能有正确的读应答。不要认为我的I2C驱动以前在其他外设用成功过,今天换了新的I2C外设,老的驱动套上去就一定能成功。
欢迎光临 21ic电子技术开发论坛 (https://bbs.21ic.com/)
Powered by Discuz! X3.5