- 打卡等级:常住居民III
- 打卡总天数:114
- 最近打卡:2026-03-07 09:00:07
已绑定手机
中级会员
- 积分
- 246
|
基于INA226+STC8H1K08的电压电流功率表,
可检测实时电压电流功率和最大最小电压电流功率,
还实现了某个时间内总功率(wh)。
看视频(本视频是无大小功率版本,有大小功率的没录 ):
原理图:
pcb:
实物图:
亚克力做了个外壳
代码片段
volatile uint16_t tick_1ms;
static uint16_t ms = 0;
static uint8_t ms10_acc = 0; // 10ms 计数
static uint8_t ms200_acc = 0; // 200ms 计数
static uint32_t run_seconds = 0;
// 测量值
static uint16_t V_inst = 0, I_inst = 0;
static uint16_t V_max = 0, V_min = 0xFFFF;
static uint16_t I_max = 0, I_min = 0xFFFF;
static uint32_t P_inst = 0;
static uint16_t P_max = 0, P_min = 0xFFFF;
// 功率平均用
static uint32_t P_sum = 0;
static uint16_t P_cnt = 0;
// 能量累计:单位 mW·秒(mWs)
static uint32_t energy_mWs = 0;
// 标记是否已采到第一个有效值
static uint8_t first_valid_sample = 1;
void Timer0_Isr(void) interrupt 1
{
tick_1ms++;
}
void Timer0_Init(void) // 1毫秒@24.000MHz
{
AUXR |= 0x80; // 1T mode
TMOD &= 0xF0;
TL0 = 0x40;
TH0 = 0xA2;
TF0 = 0;
TR0 = 1;
ET0 = 1;
}
void task_10ms(void)
{
V_inst = INA226_ReadVoltage_mV();
I_inst = INA226_ReadCurrent_mA();
// 无电流时,功率为0,并跳过极值和累积
if (I_inst == 0)
{
P_inst = 0;
return;
}
P_inst = INA226_ReadPower_mW();
// 第一次有效采样:初始化 min/max
if (first_valid_sample)
{
V_max = V_min = V_inst;
I_max = I_min = I_inst;
P_max = P_min = P_inst;
first_valid_sample = 0;
}
else
{
if (V_inst > V_max)
V_max = V_inst;
if (V_inst < V_min)
V_min = V_inst;
if (I_inst > I_max)
I_max = I_inst;
if (I_inst < I_min)
I_min = I_inst;
if (P_inst > P_max)
P_max = P_inst;
if (P_inst < P_min)
P_min = P_inst;
}
// 累积功率(用于平均)
P_sum += P_inst;
P_cnt++;
}
void task_1s(void)
{
if (P_cnt > 0)
{
uint32_t P_avg = P_sum / P_cnt; // 单位:mW
energy_mWs += P_avg;
run_seconds++;
P_sum = 0;
P_cnt = 0;
}
}
void task_200ms(void)
{
uint32_t energy_mWh = energy_mWs / 3600; // 显示时再转 mWh
displayOled(V_inst,
I_inst,
(uint16_t)P_inst,
V_max,
V_min == 0XFFFF ? 0 : V_min,
I_max,
I_min == 0XFFFF ? 0 : I_min,
P_max,
P_min == 0XFFFF ? 0 : P_min,
run_seconds,
energy_mWh);
}
void main(void)
{
uint16_t local;
P1M0 = 0x00;
P1M1 = 0x00;
P3M0 = 0x00;
P3M1 = 0x00;
OledInit();
INA226_Init();
Timer0_Init();
EA = 1;
while (1)
{
EA = 0;
local = tick_1ms;
tick_1ms = 0;
EA = 1;
while (local--)
{
ms++;
ms10_acc++;
ms200_acc++;
if (ms10_acc >= 50)
{
ms10_acc = 0;
task_10ms();
}
if (ms200_acc >= 200)
{
ms200_acc = 0;
task_200ms();
}
if (ms >= 1000)
{
ms = 0;
task_1s();
}
}
}
}
完整代码传下面了:
嘉立创开源地址:https://oshwhub.com/huyiwei/ina226
|
1
喜欢他/她就送朵鲜花吧,赠人玫瑰,手有余香!
-
+2
楼主威武~
|