5

基于STM32电压检测和电流检测

 2 years ago
source link: https://blog.51cto.com/u_15688123/5396986
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

基于STM32电压检测和电流检测

1.硬件平台

  • CPU:STM32F103C8
  • 屏幕:0.96寸OLED屏幕(SPI接口)
  • 电压测量模块:INA226(IIC接口)
  • 点流测量模块:ACS712(ADC采集)

2.功能实现

1.可测量直流电压0~36V,适用于低电压电子电路中。

2.可测量直流电0~5A范围内,目前采用的ACS712测量量程为5A,该模块有多个量程,可测量到20A。

3.实时功率监测。

4.电池电量监测(采用电压压降方式计算)。

3.硬件介绍

3.1 INA226模块

  INA226是具有I2C™或SMBUS兼容接口的电流分流器和功率监控器。该设备同时监视并联电压降和总线电源电压。可编程的校准值,转换时间和平均值与内部乘法器结合使用,可以直接读取以安培为单位的电流和以瓦特为单位的功率。INA226感应共模总线电压上的电流,该电压可在0 V至36 V之间变化,与电源电压无关。该器件采用2.7V至5.5V单电源供电,典型功耗为330 µA。该器件的额定工作温度范围为–40°C至125 \ xC2°C,并且在I 2 C兼容接口上具有多达16个可编程地址。

基于STM32电压检测和电流检测_ACS712

根据实物和原理图可看出IN和OUT 之间进接了一个0.002R电阻。在官方提供说明文档介绍改模块是可以测量直流电压0~36V,可测量总线共模电流,测量电流范围为-20A ~ 20A之间。测量精度为±1%。但在实际使用过程中发现仅能测量测量到电压值。测量电压时接线方式为:

 INPUT接电源正极,GND接电源负极。

按照模块使用说明提示在将模块串联接入电路(即OUPUT接入到负载),实际测量发现无法获取到正常电流值,因此采用ACS712模块通过ADC方式完成电流测量。

3.2 INA226模块相关寄存器和设备地址

 1.INA226一共有6个寄存器(0x0~0x5),关于各个寄存器详细介绍这里则不展开介绍,可自行下载相关资料。

基于STM32电压检测和电流检测_IIC_02

2.INA226模块采用IIC通讯,根据原理图可知地址A1 A0 ==00,再参考官方技术文档可知模块设备地址为:0x40

基于STM32电压检测和电流检测_ADC_03

基于STM32电压检测和电流检测_电压电流测量_04

从时序可以看出,第8位为读写使能位,则地址和读写为组合则为:读0x81,写0x80

基于STM32电压检测和电流检测_INA226_05

3.3 INA226模块时序图

 在时钟下降沿沿时发送数据,上升沿读取数据。

基于STM32电压检测和电流检测_INA226_06

3.4 INA226模块驱动

#include "sys.h"
#include "myiic.h"
#define CFG_REG 0x00 //
#define SV_REG 0x01 //分流电压
#define BV_REG 0x02 //总线电压
#define PWR_REG 0x03 //电源功率
#define CUR_REG 0x04 //电流
#define CAL_REG 0x05 //校准,设定满量程范围以及电流和功率测数的
#define ONFF_REG 0x06 //屏蔽 使能 警报配置和转换准备就绪
#define AL_REG 0x07 //包含与所选警报功能相比较的限定值
#define INA226_GET_ADDR 0XFF /
//初始化INA226
void INA226_Init(void)
{

IIC_Init();
INA226_SendData(INA226_ADDR1,CFG_REG,0x8000); //重新启动

INA226_SendData(INA226_ADDR1,CFG_REG,0x484f); //设置转换时间204us,求平均值次数128,采样时间为204*128,设置模式为分流和总线连续模式
INA226_SendData(INA226_ADDR1,CAL_REG,CAL); //设置分辨率
//INA226_SendData(INA226_ADDR1,CAL_REG,0x0012);//设置分流电压转电流转换参数
INA226_Get_ID(INA226_ADDR1); //获取ina226的id
}
//设置寄存器指针
void INA226_SetRegPointer(u8 addr,u8 reg)
{
IIC_Start();

IIC_Send_Byte(addr);
IIC_Wait_Ack();

IIC_Send_Byte(reg);
IIC_Wait_Ack();

IIC_Stop();
}

//发送,写入数据
void INA226_SendData(u8 addr,u8 reg,u16 data)
{
u8 temp=0;
IIC_Start();

IIC_Send_Byte(addr);
IIC_Wait_Ack();

IIC_Send_Byte(reg);
IIC_Wait_Ack();

temp = (u8)(data>>8);
IIC_Send_Byte(temp);
IIC_Wait_Ack();

temp = (u8)(data&0x00FF);
IIC_Send_Byte(temp);
IIC_Wait_Ack();

IIC_Stop();
}

//读取数据
u16 INA226_ReadData(u8 addr)
{
u16 temp=0;
IIC_Start();

IIC_Send_Byte(addr+1);
IIC_Wait_Ack();

temp = IIC_Read_Byte(1);
temp<<=8;
temp |= IIC_Read_Byte(0);

IIC_Stop();
return temp;
}
//1mA/bit
u16 INA226_GetShunt_Current(u8 addr)
{
u16 temp=0;
INA226_SetRegPointer(addr,CUR_REG);
temp = INA226_ReadData(addr);
if(temp&0x8000) temp = ~(temp - 1);
return temp;
}

//获取id
void INA226_Get_ID(u8 addr)
{
u32 temp=0;
INA226_SetRegPointer(addr,INA226_GET_ADDR);
temp = INA226_ReadData(addr);
ina226_data.ina226_id = temp;
}

//获取校准值
u16 INA226_GET_CAL_REG(u8 addr)
{
u32 temp=0;
INA226_SetRegPointer(addr,CAL_REG);
temp = INA226_ReadData(addr);
return (u16)temp;
}

//1.25mV/bit
u16 INA226_GetVoltage(u8 addr)
{
u32 temp = 0;
INA226_SetRegPointer(addr,BV_REG);
temp = INA226_ReadData(addr);
return (u16)temp;
}

//2.5uV/bit
u16 INA226_GetShuntVoltage(u8 addr)
{
int16_t temp = 0;
INA226_SetRegPointer(addr,SV_REG);
temp = INA226_ReadData(addr);
if(temp&0x8000) temp = ~(temp - 1);
return (u16)temp;
}

//获取电压
void GetVoltage(float *Voltage)//mV
{
*Voltage = INA226_GetVoltage(INA226_ADDR1)*Voltage_LSB;
}

3.5 ACS712模块

ACS712基于霍尔感应的原理设计,由一个精确的低偏移线性霍尔传感器电路与位于接近IC表面的铜箔组成(如下图所示),电流流过铜箔时,产生一个磁场, 霍尔元件根据磁场感应出一个线性的电压信号,经过内部的放大、滤波、斩波与修正电路,输出一个电压信号,该信号从芯片的第七脚输出,直接反应出流经铜箔电流的大小。ACS712根据尾缀的不一样,量程分为三个规格:±5A、±20A、±30A 。输入与输出在量程范围内为良好的线性关系,其系数Sensitivity分别为,185 mV/A、100 mV/A、66mV/A。因为斩波电路的原因,其输出将加载于0.5Vcc上。ACS712的Vcc电源 一般建议采用5V。输出与输入的关系为Vout=0.5Vcc+IpSensitivity。一般输出的电压信号介于0.5V~4.5V之间。

​典型的应用:电机领域,载荷检测和管理,开关电源领域,和各种电子产品过电流故障保护。

 器件特点​

  • 80KHZ带宽
  • 总输出误差为1.5%
  • 采用小型贴片SOIC8封装
  • 1.2mΩ内部电阻
  • 左侧大电流引脚(PIN1-4)与右侧低电压引脚(PIN5-8)最小绝缘电压为2100V
  • 5V单电压工作
  • 该器件不可应用于汽车领域

基于STM32电压检测和电流检测_ACS712_07

CS712模块为霍尔传感器,通过ADC采集电压值,载根据电压与电流的线性关系时序电流转换,输入电流与输出电压对应曲线及计算公式:

 ACS712ELCTR-05B电流电压对应关系如下图,Ip=0A即没有输入电流的时候,对应输出电压为2.5V.精确度为185mV/A即为图中斜线的斜率。取VCC=5V,计算公式为:

Vout = 2.5 + 0.185*Ip

基于STM32电压检测和电流检测_ACS712_08

3.6 ACS712驱动

#include "adc.h"
/***************ADC规则通道初始化*************
**硬件接口:PB0 -- ADC1_CH8(模拟)
**
*注:ADC的工作频频率不能超过14MHZ
********************************************/
void ADC1_RegularChannel_Init(void)
{
//1.开时钟
RCC->APB2ENR|=1<<9;//ADC1时钟
RCC->APB2ENR|=1<<3;//PB0时钟
RCC->APB2RSTR|=1<<9;//ADC复位时钟
RCC->APB2RSTR&=~(1<<9);//关复位
/*2.GPIO配置*/
GPIOB->CRL&=0xFFFFFFF0;//模式输入方式
/*3.ADC时钟频率配置*/
RCC->CFGR&=~(0x3<<14);//清除原来配置
RCC->CFGR|=0x2<<14;//ADC工作频率72MHZ/6=12MZH
/*4.配置ADC核心寄存器*/
// ADC1->CR1&=~(0xF<<16);//独立模式
ADC1->CR2|=1<<23;//启动温度传感器(测量CPU温度)
ADC1->CR2|=1<<20;//规则通道外部触发转换模式
ADC1->CR2|=0x7<<17;//外部事件通过开关事件触发
// ADC1->CR2&=~(1<<11);//右对齐(地位对齐,高位补0)
ADC1->SMPR1|=0x7<<18;//温度传感器采样时间通道16
ADC1->SMPR2|=0x7<<24;//通道8采用时间
ADC1->SQR1&=~(0xF<<20);//规则通道转换的通道数目为1个转换
// ADC1->CR2&=~(1<<1);//单次转换模式
ADC1->CR2|=1<<0;//开启ADC
ADC1->CR2|=1<<3;//初始化校准
while(ADC1->CR2&1<<3);//等待初始化校准完成
ADC1->CR2|=1<<2;//开始校准
while(ADC1->CR2&1<<2){}//等待校准完成
}
/****************ADC1规则通道获取数值***************/
u16 ADC1_GetRegularCHx(u8 chx)
{
ADC1->SQR3&=~(0x1F<<0);//清除原来寄存器中的值
ADC1->SQR3|=chx;//要转的通道号
ADC1->CR2|=1<<22;//开启转换规则通过
while(!(ADC1->SR&1<<1)){}//等待转换完成
return ADC1->DR;
}

4.实物测量效果

基于STM32电压检测和电流检测_电压电流测量_09

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK