bq4050芯片SMBUS(IIC/i2c)使用

 说明书中bq4050的默认设备地址为0x16。

很多人做i2c的时候,是这样操作的: (0x16<<1)|0x01  ,通过这样的方式来设置读写位为1,也就是读取,但是不知道是我这个电池的问题还是什么的,说明书中的0x16这个地址位其实是包含了读写位的,也就是说写的地址是0x16,读的地址是0x17,如果左移的话,地址反而不对了。

更坑到我的是我用的atmel atmega 4809的芯片,直接调用系统的硬件i2c发送,会自动左移1位,也就是说,0x16发送出来变成0x2c了,那么这时候,就要反其道而行,先右移1位,变成0xb,然后调用系统的硬件i2c函数,发送出来就变成0x16了。

#define slave_adr 0x0b

i2c_error_t I2C_0_do_transfer(uint8_t adr, uint8_t *data, uint8_t size)
{
	/* timeout is used to get out of twim_release, when there is no device connected to the bus*/
	uint16_t              timeout = I2C_TIMEOUT;
	transfer_descriptor_t d       = {data, size};

	while (I2C_BUSY == I2C_0_open(slave_adr) && --timeout)
		; // sit here until we get the bus..
	if (!timeout)
		return I2C_BUSY;

	// This callback specifies what to do after the first write operation has completed
	// The parameters to the callback are bundled together in the aggregate data type d.
	I2C_0_set_data_complete_callback(I2C_0_read_handler, &d);
	// If we get an address NACK, then try again by sending SLA+W
	I2C_0_set_address_nack_callback(i2c_cb_restart_write, NULL);
	// Transmit specified number of bytes
	I2C_0_set_buffer((void *)&adr, 1);
	// Start a Write operation
	I2C_0_master_operation(false);
	timeout = I2C_TIMEOUT;
	while (I2C_BUSY == I2C_0_close() && --timeout)
		; // sit here until finished.
	if (!timeout)
		return I2C_FAIL;

	return I2C_NOERR;
}

uint16_t I2C_get_Capacity(void)
{
	uint16_t value;
	I2C_0_do_transfer(0x0D, read_data, 2);
	value = read_data[1];
	value <<= 8;
	value += read_data[0];	
	return value;
}
uint16_t I2C_get_Voltage(void)
{
	uint16_t value;
	I2C_0_do_transfer(0x09, read_data, 2);
	value = read_data[1];
	value <<= 8;
	value += read_data[0];
	return value;
}
int16_t I2C_get_Current(void)
{
	int16_t value;
	I2C_0_do_transfer(0x0a, read_data, 2);
	value = read_data[1];
	value <<= 8;
	value += read_data[0];
	return value;
}

下面分析一下读取到的时序

电量Capacity

注:红色字体为master发送,蓝色字体为slave发送

                          0x16(写入)      ack

0     0     0     1     0     1     1     0     0

                        0x0d(电量地址)  ack

0     0     0      0     1     1     0     1     0

                               0x17(读取)  ack

0     0     0      1     0     1     1     1     0

               0x33(电量51%)          ack

0     0     1      1     0     0    1     1      0

                0x0(电量0%)            nack

0     0     0      0    0     0     0     0      1

至此电量读取过程结束

电压Voltage

注:红色字体为master发送,蓝色字体为slave发送

                        0x16(写入)      ack

0     0     0     1     0     1     1     0     0

                        0x09(电压地址)  ack

0     0     0      0     1     0     0     1     0

                               0x17(读取)  ack

0     0     0      1     0     1     1     1     0

               0x73                                ack

0     1     1      1     0     0    1     1      0

                0x1c                               nack

0     0     0      0    0     0     0     0      1

至此电压读取过程结束

返回的数据位小端模式,即0x1c73,转换为10进制为7283,即7.283V

电流Current

注:红色字体为master发送,蓝色字体为slave发送

                        0x16(写入)      ack

0     0     0     1     0     1     1     0     0

                        0x0A(电流地址)  ack

0     0     0      0     1     0     1     0     0

                               0x17(读取)  ack

0     0     0      1     0     1     1     1     0

               0x1c                                ack

0     0     0      1     1     1    0     0      0

                0xfd                              nack

1     1     1      1    1     1     0     1      1

至此电流读取过程结束

返回的数据位小端模式,即0xfd1c,转换为10进制为64796,难道电流有64.796A?

注意这个数是有符号数,是个负数,使用的是补码,先转化到反码为0xfd1b,再转换为原码为-740,所谓最终我们测到的电流是-740mA。

注意:负数是电池放电,正数是电池充电

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值