根据INA226数据手册得知,如果想读取INA226的数据的话,需要用IIC访问以下的寄存器。
而这里需要注意一点的是,如果要想读取电流的数据的话,一定要先校准INA226, 也就是往INA226的0x05寄存器中写入数据。
可以用过下面的公式计算出来校准寄存器里应该写入的数值。
比如说现在期望读取的最大的电流为5A, 用5/2^15 可以得到电流的lowest significant bit (LSB) 然后使用上面的公式 0.00512 /(LSB * 分流电阻的阻值), 计算的结果大概等于335。换算到代码中则为以下:
static void ina266_init(hosal_i2c_dev_t *i2c)
{
uint16_t calibration_value = 335;
ina266_set_calibration(i2c, calibration_value);
}
完整的读取代码如下:
#include
#include
#include
#include
#include
#include
#define INA266_DEFAULT_ADDR 0x40
#define INA266_REG_CURRENT 0x04
#define INA266_REG_CALIBRATION 0x05
#define INA266_REG_BUS_VOLTAGE 0x02
static void ina266_set_calibration(hosal_i2c_dev_t *i2c, uint16_t calibration_value)
{
uint8_t data[3];
data[0] = INA266_REG_CALIBRATION;
data[1] = (calibration_value >> 8) & 0xFF;
data[2] = calibration_value & 0xFF;
hosal_i2c_master_send(i2c, INA266_DEFAULT_ADDR, data, sizeof(data), 100);
}
static void ina266_init(hosal_i2c_dev_t *i2c)
{
uint16_t calibration_value = 335;
ina266_set_calibration(i2c, calibration_value);
}
static float ina266_read_current(hosal_i2c_dev_t *i2c)
{
uint8_t reg_addr = INA266_REG_CURRENT;
uint8_t data[2];
int16_t raw_current;
hosal_i2c_master_send(i2c, INA266_DEFAULT_ADDR, ®_addr, sizeof(reg_addr), 100);
hosal_i2c_master_recv(i2c, INA266_DEFAULT_ADDR, data, sizeof(data), 100);
raw_current = (data[0] << 8) | data[1];
float current = raw_current * 0.000152;
return current;
}
static float ina266_read_voltage(hosal_i2c_dev_t *i2c)
{
uint8_t reg_addr = INA266_REG_BUS_VOLTAGE;
uint8_t data[2];
int16_t raw_voltage;
hosal_i2c_master_send(i2c, INA266_DEFAULT_ADDR, ®_addr, sizeof(reg_addr), 100);
hosal_i2c_master_recv(i2c, INA266_DEFAULT_ADDR, data, sizeof(data), 100);
raw_voltage = (data[0] << 8) | data[1];
float voltage = raw_voltage * 0.00125;
return voltage;
}
int main(void)
{
static hosal_i2c_dev_t i2c0 = {
.config = {
.address_width = HOSAL_I2C_ADDRESS_WIDTH_7BIT,
.freq = 50000,
.mode = HOSAL_I2C_MODE_MASTER,
.scl = 12,
.sda = 3,
},
.port = 0,
};
hosal_i2c_init(&i2c0);
ina266_init(&i2c0);
for (;;)
{
float current = ina266_read_current(&i2c0);
blog_info("Current: %.3f A\r\n", current);
float voltage = ina266_read_voltage(&i2c0);
blog_info("Voltage: %.3f V\r\n", voltage);
vTaskDelay(portTICK_RATE_MS * 500);
}
return 0;
}
实验现象:
那么根据实际情况,加上对UT89XD的测量,电压的误差大概在0.1v 电流的误差大概在0.06MA。
库文件
main.c
#include
#include
#include
#include
#include
#include
#include "ina226.h"
int main(void)
{
static hosal_i2c_dev_t i2c0 = {
.config = {
.address_width = HOSAL_I2C_ADDRESS_WIDTH_7BIT,
.freq = 50000,
.mode = HOSAL_I2C_MODE_MASTER,
.scl = 12,
.sda = 3,
},
.port = 0,
};
hosal_i2c_init(&i2c0);
ina266_init(&i2c0);
for (;;)
{
float current = ina266_read_current(&i2c0);
blog_info("Current: %.3f A\r\n", current);
float voltage = ina266_read_voltage(&i2c0);
blog_info("Voltage: %.3f V\r\n", voltage);
vTaskDelay(portTICK_RATE_MS * 500);
}
return 0;
}
ina226.c
#include "ina226.h"
void ina266_set_calibration(hosal_i2c_dev_t *i2c, uint16_t calibration_value)
{
uint8_t data[3];
data[0] = INA266_REG_CALIBRATION;
data[1] = (calibration_value >> 8) & 0xFF;
data[2] = calibration_value & 0xFF;
hosal_i2c_master_send(i2c, INA266_DEFAULT_ADDR, data, sizeof(data), 100);
}
void ina266_init(hosal_i2c_dev_t *i2c)
{
uint16_t calibration_value = 335;
ina266_set_calibration(i2c, calibration_value);
}
float ina266_read_current(hosal_i2c_dev_t *i2c)
{
uint8_t reg_addr = INA266_REG_CURRENT;
uint8_t data[2];
int16_t raw_current;
hosal_i2c_master_send(i2c, INA266_DEFAULT_ADDR, ®_addr, sizeof(reg_addr), 100);
hosal_i2c_master_recv(i2c, INA266_DEFAULT_ADDR, data, sizeof(data), 100);
raw_current = (data[0] << 8) | data[1];
float current = raw_current * 0.000152;
return current;
}
float ina266_read_voltage(hosal_i2c_dev_t *i2c)
{
uint8_t reg_addr = INA266_REG_BUS_VOLTAGE;
uint8_t data[2];
int16_t raw_voltage;
hosal_i2c_master_send(i2c, INA266_DEFAULT_ADDR, ®_addr, sizeof(reg_addr), 100);
hosal_i2c_master_recv(i2c, INA266_DEFAULT_ADDR, data, sizeof(data), 100);
raw_voltage = (data[0] << 8) | data[1];
float voltage = raw_voltage * 0.00125;
return voltage;
}
ina226.h
#include
#include
#define INA266_DEFAULT_ADDR 0x40
#define