STM32 驅(qū)動(dòng) INA226 測(cè)量電流電壓功率

一、INA226簡(jiǎn)介

INA226 是一款分流/功率監(jiān)視器,具有 I2C或SMBUS 兼容接口。 該器件 監(jiān)視分流壓降和總線電源電壓。 可編程校準(zhǔn)值、轉(zhuǎn)換時(shí)間和取平均值功能與內(nèi)部乘法器相結(jié)合,可實(shí)現(xiàn)電流值(單位為安培)和功率值(單位為瓦)的直接讀取。

二、引腳功能

IN+ 電流輸入
IN- 電流輸出
GND 電源地
VS 電源正
SCL 時(shí)鐘線
SDA 數(shù)據(jù)線
A0 IIC地址設(shè)置引腳
A1 IIC地址設(shè)置引腳
Alert 報(bào)警輸出引腳
VBUS 總線電壓輸入引腳

INA226有兩個(gè)地址引腳,A0和A1。下圖描述了16個(gè)可能地址中的每一個(gè)的引腳邏輯。由原理圖可知 INA226 模塊 A0 A1 引腳被下拉至 GND ,故 IIC 地址則為 Write:1000 0000 0x80 Read:1000 0001 0x81

三、寄存器介紹

1.配置寄存器 0x00

配置寄存器設(shè)置控制設(shè)備的工作模式。該寄存器控制分流和總線電壓測(cè)量以及所用的平均模式的轉(zhuǎn)換時(shí)間設(shè)置。
Bit 字段 類型 默認(rèn)值(二進(jìn)制) 描述
15 RST R/W 0 設(shè)置成1 復(fù)位
14-12 NC R/W 100 無功能 保留
11-9 AVG R/W 000 采樣平均次數(shù)
000 1次
001 4次
010 16次
011 64次
...
6-8 VBUSCT R/W 100 總線采樣時(shí)間
000 140μs
001 204μs
010 332 μs
011 588 μs
100 1.1ms
101 2.116ms
110 4.156ms
111 8.244ms
3-5 VSHCT R/W 100 分流采樣時(shí)間
同上
0:2 MODE R/W 111 操作模式
000 關(guān)閉
001 分流電壓 觸發(fā)
010 總線電壓 觸發(fā)
011 分流及總線電壓 觸發(fā)
100 關(guān)閉
101 分流電壓 連續(xù)測(cè)量
110 總線電壓 連續(xù)測(cè)量
111 分流及總線電壓 連續(xù)測(cè)量

2.分流電壓寄存器 0x01

用于存儲(chǔ)當(dāng)前的分流電壓讀數(shù) Vshunt。負(fù)數(shù)采用二進(jìn)制補(bǔ)碼格式表示。生成一個(gè)負(fù)數(shù)的補(bǔ)碼方法是:對(duì)其絕對(duì)值的二進(jìn)制數(shù)取反,然后加 1。如果最高有效位(MSB)為 '1',則表示這是一個(gè)負(fù)數(shù)。最小分辨率(Vshunt _LSB)為 2.5uV。

注意分流電壓最大81.92mV,而該模塊的采樣電阻是0.1R,故最大電流為 81.92mV / 0.1R = 819.2mA
分流電壓計(jì)算:Vshunt = 寄存器值 * Vshunt _LSB(2.5uV)

3.總線電壓寄存器 0x02

用于存儲(chǔ)最近一次的總線電壓讀數(shù) Vbus。如果啟用了平均功能,則該寄存器顯示的是平均后的數(shù)值。滿量程范圍為 40.96V(對(duì)應(yīng) 7FFF);最小分辨率(Vbus_LSB)為 1.25 mV。


總線電壓計(jì)算:Vbus = 寄存器值 * Vbus_LSB(1.25 mV )

4.功率寄存器 0x03

用于存儲(chǔ)功率讀數(shù) Power ,如果啟用了平均功能,該寄存器將顯示平均值。功率寄存器的最低有效位(LSB)在內(nèi)部被設(shè)定為等于 Current_LSB 所設(shè)定值的 25 倍。功率寄存器通過將電流寄存器的十進(jìn)制值與總線電壓寄存器的十進(jìn)制值相乘來記錄以瓦特(Watts)為單位的功率。

功率計(jì)算: Power = 寄存器值 * Power_ LSB
由手冊(cè)可知 Power_LSB(功率最小分辨率) = Current_LSB(電流最小分辨率) * 25
Current_LSB 手冊(cè)給出了計(jì)算公式,如下

Current_LSB = 最大電流 / 2^15 = 819.2mA / 2^15 = 0.025mA

而手冊(cè)內(nèi)有一段提示:While this value yields the highest resolution, it is common to select a value for the Current_LSB to the nearest round number above this value to simplify the conversion of the Current Register (04h) and Power Register (03h) to amperes and watts respectively
譯文:雖然這個(gè)值可以提供最高的分辨率,但通常會(huì)選擇一個(gè)略高于該值的整數(shù)作為 Current_LSB,以簡(jiǎn)化將電流寄存器(04h)和功率寄存器(03h)轉(zhuǎn)換為安培(Amperes)和瓦特(Watts)的過程
也就是可以自己根據(jù)公式計(jì)算出的結(jié)果,選擇一個(gè)合適的 Current_LSB 值,便于計(jì)算,這里公式得出的 Current_LSB = 0.025mA,本文重新選擇為 0.05mA,之所以選擇 0.05 也為了便于后續(xù) CAL (基準(zhǔn)值) 的計(jì)算,詳見寄存器 0x05 說明

故 Power_LSB = 0.05mA * 25 = 1.25mW
功率計(jì)算: Power = 寄存器值 * Power_ LSB(1.25mW)

5.電流寄存器 0x04

用于存儲(chǔ)電流讀數(shù) Current,如果啟用了平均功能,該寄存器將顯示平均值。電流寄存器的值是通過將分流電壓寄存器中的十進(jìn)制值與校準(zhǔn)寄存器中的十進(jìn)制值相乘來計(jì)算的。

電流值 = 寄存器值 * Current_LSB(0.05mA) (Current_LSB 的計(jì)算在上文功率寄存器小節(jié)已經(jīng)給出)

6.基準(zhǔn)寄存器 0x05

該寄存器為器件提供用于產(chǎn)生測(cè)量差分電壓的分流電阻值。它還設(shè)置電流寄存器的分辨率。編程該寄存器可設(shè)置 Current_LSB 和 Power_LSB。該寄存器也適用于整體系統(tǒng)校準(zhǔn)。

該寄存器主要是是設(shè)置系統(tǒng)基準(zhǔn)的,將 基準(zhǔn)值(CAL) 寫入寄存器即可

Current_LSB= 0.05mA (上文功率寄存器小節(jié)已經(jīng)給出) ,根據(jù)原理圖可知 Rshunt = 0.1R
CAL = 0.00512 / (0.00005A * 0.1R) = 1024 = 0x0400

實(shí)測(cè)調(diào)試發(fā)現(xiàn)所測(cè)出電流偏大,采用手冊(cè)校準(zhǔn)公式

5V 測(cè)試條件下 MeasShuntCurrent = 490 mV INA226_Current = 520mV
Corrected_Full_Scale_Cal = 490 * 1024 / 520 = 964.9 約等于 965 = 0x03C5

修改程序重新寫入基準(zhǔn)值CAL =0x03C5,再次測(cè)量輸出與儀器顯示數(shù)據(jù)基本一致

其它寄存器是報(bào)警功能及ID,本文未使用則不做說明

四、IIC 時(shí)序說明

1.寫時(shí)序

    MyI2C_Start();                       //I2C起始
    MyI2C_SendByte(INA226_W);            //發(fā)送從機(jī)地址,讀寫位為0,表示即將寫入
    MyI2C_ReceiveAck();                  //接收應(yīng)答
    MyI2C_SendByte(Register);            //發(fā)送寄存器地址
    MyI2C_ReceiveAck();                  //接收應(yīng)答
    MyI2C_SendByte(Data_H);              //發(fā)送要寫入寄存器的數(shù)據(jù)高位
    MyI2C_ReceiveAck();                  //接收應(yīng)答
    MyI2C_SendByte(Data_L);              //發(fā)送要寫入寄存器的數(shù)據(jù)低位
    MyI2C_ReceiveAck();                  //接收應(yīng)答
    MyI2C_Stop();                        //I2C終止

2.讀時(shí)序

該時(shí)序前還應(yīng)加一個(gè)發(fā)送寄存器地址的時(shí)序:起始信號(hào)---IIC地址---ACK---寄存器地址---ACK

    MyI2C_Start();                        //I2C起始
    MyI2C_SendByte(INA226_W);             //發(fā)送從機(jī)地址
    MyI2C_ReceiveAck();                   //接收應(yīng)答
    MyI2C_SendByte(RegAddress);           //發(fā)送寄存器地址
    MyI2C_ReceiveAck();                   //接收應(yīng)答
    
    MyI2C_Start();                        //I2C重復(fù)起始
    MyI2C_SendByte(INA226_R);             //發(fā)送從機(jī)地址
    MyI2C_ReceiveAck();                   //接收應(yīng)答
    Data = MyI2C_ReceiveByte();           //接收指定寄存器的高位數(shù)據(jù)
    MyI2C_SendAck(0);                     //發(fā)送應(yīng)答
    Data = (Data << 8)| MyI2C_ReceiveByte();//接收指定寄存器的低位數(shù)據(jù)
    MyI2C_Stop();                         //I2C終止

五、程序

INA226.C

#include "stm32f10x.h"                  // Device header
#include "MyI2C.h"

/*IIC 地址---------------------------------------------------------------------------------------------*/
#define INA226_W 0x80
#define INA226_R 0x81
/*寄存器地址--------------------------------------------------------------------------------------------*/
#define INA226_Configuration                          0x00
#define INA226_Shuntvoltage                           0x01
#define INA226_Busvoltage                             0x02
#define INA226_Power                                  0x03
#define INA226_Current                                0x04
#define INA226_Calibration                            0x05
#define INA226_Mask                                   0x06
#define INA226_AlertLimit                             0x07
#define INA226_ManufacturerID                         0xFE
#define INA226_DieID                                  0xFF
/* INA226_curation Bit15-0 --------------------------------------------------------------------------*/
#define RST                     0       // 0   設(shè)置成1復(fù)位 (Bit15)
#define Reservation       0x04  // 100 (Bit14-12 保留)
#define AVG                             0x01  // 001 平均次數(shù) 4 (Bit11-9)
#define VBUSCT                      0x04    // 100 總線電壓轉(zhuǎn)換時(shí)間 1.1ms (Bit116-8)
#define VSHCT                       0x04    // 100 分流電壓轉(zhuǎn)換時(shí)間 1.1ms(Bit3-5)
#define MODE                0x07    // 111 運(yùn)行模式  連續(xù)檢測(cè)(默認(rèn))(Bit0–2)

#define Configuration_H (RST << 7)|(Reservation << 4)|(AVG << 1)|(VBUSCT >> 2)
#define Configuration_L ((VBUSCT & 0x03) << 6)|(VSHCT << 3)|(MODE)

/* INA226_Calibration ---------------------------------------------------------------------------------*/
//#define Calibration_H 0x04
//#define Calibration_L 0x00

//MAX_Current = Full-scale range / R·SHUNT = 81.92mV / 0.1R = 819.2mA
//Current_LSB = 819.2mA / 2^15 = 0.025mA 
//選擇接近值:0.05mA = 0.00005A 手冊(cè)推薦1mA 但是便于CAL計(jì)算和實(shí)際調(diào)試則重新選擇為 0.05mA
//(手冊(cè):While this value yields the highest resolution, it is common to select a value for the Current_LSB to the nearest round number above this value to simplify the conversion of the Current Register (04h) and Power Register (03h) to amperes and watts respectively.)
//(雖然該值產(chǎn)生最高分辨率,但通常為Current_LSB選擇一個(gè)值,使其與高于該值的最接近的整數(shù)相匹配,以簡(jiǎn)化電流寄存器(04h)和功率寄存器(03h)分別轉(zhuǎn)換為安培和瓦的過程。)
//CAL = 0.00512 / (Current_LSB * R·SHUNT) = 0.00512 / (0.00005A * 0.1R) = 1024 = 0x0400
//Power_LSB = Current_LSB * 25 = 0.05mA * 25 = 1.25mW
//(手冊(cè):The power LSB has a fixed ratio to the Current_LSB of 25)
//(power LSB與Current_LSB的固定比率為25)

#define Calibration_H 0x03
#define Calibration_L 0xC5
//實(shí)測(cè)發(fā)現(xiàn)電流偏大,采用手冊(cè)校準(zhǔn)公式 Corrected_Full_Scale_Cal = (Cal * MeasShuntCurrent) / INA226_Current 
//5V 測(cè)試條件下 MeasShuntCurrent = 490 mV   INA226_Current = 520mV  Corrected_Full_Scale_Cal = 490 * 1024 / 520 = 964.9 = 965 = 0x03C5
void INA226_WriteReg(uint8_t Register, uint8_t Data_H, uint8_t Data_L)
{
    MyI2C_Start();                        //I2C起始
    MyI2C_SendByte(INA226_W);     //發(fā)送從機(jī)地址,讀寫位為0,表示即將寫入
    MyI2C_ReceiveAck();                 //接收應(yīng)答
    MyI2C_SendByte(Register);       //發(fā)送寄存器地址
    MyI2C_ReceiveAck();                 //接收應(yīng)答
    MyI2C_SendByte(Data_H);         //發(fā)送要寫入寄存器的數(shù)據(jù)高位
    MyI2C_ReceiveAck();                 //接收應(yīng)答
    MyI2C_SendByte(Data_L);         //發(fā)送要寫入寄存器的數(shù)據(jù)低位
    MyI2C_ReceiveAck();                 //接收應(yīng)答
    MyI2C_Stop();                           //I2C終止
}
uint32_t INA226_ReadReg(uint8_t RegAddress)
{
    uint32_t Data;
    
    MyI2C_Start();                        //I2C起始
    MyI2C_SendByte(INA226_W);     //發(fā)送從機(jī)地址
    MyI2C_ReceiveAck();                 //接收應(yīng)答
    MyI2C_SendByte(RegAddress); //發(fā)送寄存器地址
    MyI2C_ReceiveAck();                 //接收應(yīng)答
    
    MyI2C_Start();                      //I2C重復(fù)起始
    MyI2C_SendByte(INA226_R);     //發(fā)送從機(jī)地址
    MyI2C_ReceiveAck();                 //接收應(yīng)答
    Data = MyI2C_ReceiveByte(); //接收指定寄存器的高位數(shù)據(jù)
    MyI2C_SendAck(0);                   //發(fā)送應(yīng)答
    Data = (Data << 8)| MyI2C_ReceiveByte();    //接收指定寄存器的低位數(shù)據(jù)
    MyI2C_Stop();                           //I2C終止
    
    return Data;
}
void INA226_Init(void)
{
    INA226_WriteReg(INA226_Configuration,Configuration_H,Configuration_L);   //4次平均  1.1ms轉(zhuǎn)換時(shí)間  連續(xù)檢測(cè)
    INA226_WriteReg(INA226_Calibration,Calibration_H,Calibration_L);         //基準(zhǔn)值 0x0200
}
uint32_t INA226_GetShuntVoltage(void)//分流電壓值 =  寄存器值 * LSB(2.5uA)
{
    uint32_t ShuntVoltage;
    ShuntVoltage = (uint32_t)((INA226_ReadReg(INA226_Shuntvoltage)) * 2.5 / 1000);
    
    return ShuntVoltage;
}
uint32_t INA226_GetBusVoltage(void)//總線電壓值 =  寄存器值 * LSB(1.25mV)
{
    uint32_t BusVoltage;
    BusVoltage = (uint32_t)((INA226_ReadReg(INA226_Busvoltage)) * 1.25);
    
    return BusVoltage;
}
uint32_t INA226_GetCurrent(void)//電流值 = 寄存器值 * Current_LSB(0.05mA)
{
    uint32_t Current;
    Current = (uint32_t)((INA226_ReadReg(INA226_Current)) * 0.05);
    
    return Current;
}
uint32_t INA226_GetPower(void)//功率 = 寄存器值 * Power_LSB(1.25mW)
{
    uint32_t Power;
    Power = (uint32_t)((INA226_ReadReg(INA226_Power)) * 1.25);
    
    return Power;
}

main.c

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"
#include "INA226.h"
#include "MyI2C.h"

uint32_t ShuntVoltage=0, BusVoltage=0, Current=0, Power=0;          //定義用于存放各個(gè)數(shù)據(jù)的變量
int main(void)
{
    Delay_ms(2000);//上電延時(shí)
    /*模塊初始化*/
    MyI2C_Init();
    OLED_Init();    
    INA226_Init();
    Delay_ms(1000);//初始化延時(shí)
    while (1)
    {
        ShuntVoltage = INA226_GetShuntVoltage();Delay_ms(50);
        BusVoltage = INA226_GetBusVoltage();Delay_ms(50);
        Current = INA226_GetCurrent();Delay_ms(50);
        Power = INA226_GetPower();
        OLED_ShowString(1,1,"ShuntV:");OLED_ShowSignedNum(1, 9, ShuntVoltage, 6);//單位mV,由于OLED行限制,單位暫不顯示
        OLED_ShowString(2,1,"BusV:");OLED_ShowSignedNum(2, 9, BusVoltage, 6);//單位mV
        OLED_ShowString(3,1,"Current:");OLED_ShowSignedNum(3, 9, Current, 6);//單位mA
        OLED_ShowString(4,1,"Power:");OLED_ShowSignedNum(4, 9, Power, 6);//單位mW
        Delay_ms(1000);
    }
}

六、實(shí)驗(yàn)現(xiàn)象

1.線路圖

2.輸出數(shù)據(jù)

負(fù)載儀恒阻模式 10R

3V 測(cè)試

5V 測(cè)試

以上內(nèi)容個(gè)人理解,如有不正歡迎指正,需要資料及工程可留言郵箱

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容