TI中文支持网
TI专业的中文技术问题搜集分享网站

OPT3001

大家好我使用单片机读取OPT3001得数据,一点反应也没有ACK信号也没有,ADDR接地地址是0x44,下面我贴出我的代码请大神指点

void I2CStart( void ){ GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.Pin = E2PROM_SDA;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
HAL_GPIO_WritePin(GPIOA, E2PROM_SCL, GPIO_PIN_SET); HAL_GPIO_WritePin(GPIOA, E2PROM_SDA, GPIO_PIN_SET); DelayMs(10);// GPIO_SetBits( GPIOA, E2PROM_SCL ); HAL_GPIO_WritePin(GPIOA, E2PROM_SCL, GPIO_PIN_SET); DelayMs(10);// GPIO_ResetBits( GPIOA, E2PROM_SDA ); HAL_GPIO_WritePin(GPIOA, E2PROM_SDA, GPIO_PIN_RESET); DelayMs(10);HAL_GPIO_WritePin(GPIOA, E2PROM_SCL, GPIO_PIN_RESET); DelayMs(10);// GPIO_ResetBits( GPIOA, E2PROM_SCL );}

void I2CStop( void ){ GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.Pin = E2PROM_SDA;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
HAL_GPIO_WritePin(GPIOA, E2PROM_SCL, GPIO_PIN_RESET); DelayMs(10); HAL_GPIO_WritePin(GPIOA, E2PROM_SCL, GPIO_PIN_SET); HAL_GPIO_WritePin(GPIOA, E2PROM_SDA, GPIO_PIN_RESET); DelayMs(10); HAL_GPIO_WritePin(GPIOA, E2PROM_SDA, GPIO_PIN_SET); DelayMs(10);

HAL_GPIO_WritePin(GPIOA, E2PROM_SDA, GPIO_PIN_RESET); DelayMs(10);

}

unsigned char I2c_getAck(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.Pin = E2PROM_SDA;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
char ack; HAL_GPIO_WritePin(GPIOA, E2PROM_SDA, GPIO_PIN_SET); HAL_GPIO_WritePin(GPIOA, E2PROM_SCL, GPIO_PIN_SET); DelayMs(10); ack = HAL_GPIO_ReadPin( GPIOA, E2PROM_SDA ); HAL_GPIO_WritePin(GPIOA, E2PROM_SCL, GPIO_PIN_RESET); return ack;
}

void I2CWriteByte( unsigned char byte ){ unsigned char i;

for( i=0; i<8; i++ ) { if( 0X80 & byte ) {
HAL_GPIO_WritePin(GPIOA, E2PROM_SDA, GPIO_PIN_SET); }
else
{
HAL_GPIO_WritePin(GPIOA, E2PROM_SDA, GPIO_PIN_RESET); } byte <<= 1; DelayMs(10);

HAL_GPIO_WritePin(GPIOA, E2PROM_SCL, GPIO_PIN_SET); DelayMs(10); HAL_GPIO_WritePin(GPIOA, E2PROM_SCL, GPIO_PIN_RESET); DelayMs(10); }// HAL_GPIO_WritePin(GPIOA, E2PROM_SCL, GPIO_PIN_SET);// DelayMs(10); I2c_getAck();
}

unsigned char I2CReadByte( void ){ unsigned char i; unsigned char ReadValue = 0; GPIO_InitTypeDef GPIO_InitStruct; unsigned char bit; GPIO_InitStruct.Pin = E2PROM_SDA;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
for( i=0; i<8; i++ ) { HAL_GPIO_WritePin(GPIOA, E2PROM_SCL, GPIO_PIN_SET); DelayMs(10); if( SET == HAL_GPIO_ReadPin( GPIOA, E2PROM_SDA ) ) bit = 0X01; else bit = 0x00; ReadValue = (ReadValue<<1)|bit; HAL_GPIO_WritePin(GPIOA, E2PROM_SCL, GPIO_PIN_RESET);// DelayMs(10); }// HAL_GPIO_WritePin(GPIOA, E2PROM_SCL, GPIO_PIN_SET);
// DelayMs(10);// GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;// GPIO_Init( GPIOB, &GPIO_InitStruct ); GPIO_InitStruct.Pin = E2PROM_SDA;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
return ReadValue;}

void I2c_toDevice(unsigned char deviceAdd,unsigned char datAdd,unsigned char dat)
{
I2CStart();
I2CWriteByte(deviceAdd);
I2CWriteByte(datAdd);
I2CWriteByte(dat);
I2CWriteByte(0x10);
I2CStop();
}
unsigned short I2c_fromDevice(unsigned char deviceAdd,unsigned char datAdd )
{
unsigned short dat;
I2CStart();
I2CWriteByte(deviceAdd);
I2CWriteByte(datAdd);
// I2CStart();
I2CWriteByte(deviceAdd+1);
dat=I2CReadByte();
I2c_getAck();
dat=dat<<8;
dat|=I2CReadByte();
I2CStop();
return dat;
}

Kailyn Chen:

根据您的0X44地址可以判断ADDR引脚接的是地是吗?这样的话,7bit从机地址为1000100,左移一位,地址应该为0X88。
因此把0X44改为0X88,然后看是否能收到ACK信号呢?

HaiBin li:

回复 Kailyn Chen:

您好,现在是写0x88有ack应答,写配置没有应答

deviceAdd=0x88datAdd=0x01dat=0xc2

void I2c_toDevice(unsigned char deviceAdd,unsigned char datAdd,unsigned char dat)
{I2CStart();I2CWriteByte(deviceAdd);//有ack应答I2CWriteByte(datAdd);//没有ack应答I2CWriteByte(dat);I2CWriteByte(0x10);I2CStop();
}

HaiBin li:

回复 Kailyn Chen:

现在是读写配置有ack应答,但是读数据全是FF

deviceAdd=0x88 datAdd=0x01 dat=0xc2

void I2c_toDevice(unsigned char deviceAdd,unsigned char datAdd,unsigned char dat)
{
I2CStart();
I2CWriteByte(deviceAdd);//有ack应答
I2CWriteByte(datAdd);//有ack应答
I2CWriteByte(dat);//有ack应答
I2CWriteByte(0x10);//有ack应答
I2CStop();
}

unsigned short I2c_fromDevice(unsigned char deviceAdd,unsigned char datAdd)
{unsigned short dat;I2CStart();I2CWriteByte(deviceAdd);//有ack应答I2CWriteByte(datAdd);//有ack应答I2CWriteByte(deviceAdd);//有ack应答dat=I2CReadByte();I2c_getAck();//有ack应答dat=dat<<8;dat|=I2CReadByte();I2CStop();return dat;//dat=0XFFFF
}

Kailyn Chen:

回复 HaiBin li:

7bit从机地址,第八位是读写方向位,为0 的时候表示发送数据,即“写”。 所以主机向从机发送数据,从机地址为0X88。
如果读数据的话,第八位为1,即地址为0X81.

Kailyn Chen:

回复 Kailyn Chen:

不好意思,读数据的话,为10001001,为0X89.

HaiBin li:

回复 Kailyn Chen:

改为0x89也是读出全ff

HaiBin li:

回复 Kailyn Chen:

unsigned short I2c_fromDevice(unsigned char deviceAdd,unsigned char datAdd)
{unsigned short dat;I2CStart();I2CWriteByte(deviceAdd);//0x88I2CWriteByte(datAdd);//0I2CWriteByte(0x89);//0x89dat=I2CReadByte();I2c_getAck();dat=dat<<8;dat|=I2CReadByte();I2CStop();return dat;//全FF
}

HaiBin li:

回复 Kailyn Chen:

您好我把我的程序改了一下现在可以读出正确数据,但是只有一个字节是正确,第二个字节还是全FF

unsigned short I2c_fromDevice(unsigned char deviceAdd,unsigned char datAdd)
{unsigned short dat;I2CStart();I2CWriteByte(deviceAdd);I2CWriteByte(datAdd);I2CStop();//必须停止之后在进行读I2CStart();//从新进行读I2CWriteByte(0x89);dat=I2CReadByte();//能读出跟光照变化的数据
// I2c_getAck();//此处不知道为什么得不到ACK我将此句屏蔽dat=dat<<8;
dat|=I2CReadByte();//得到全FF数据I2CStop();return dat;
}

赞(0)
未经允许不得转载:TI中文支持网 » OPT3001
分享到: 更多 (0)