标题:
STM32同时采集电压电流的芯片INA219源程序
[打印本页]
作者:
lp060120
时间:
2019-11-13 17:38
标题:
STM32同时采集电压电流的芯片INA219源程序
在Keil5环境下编译的STM32驱动INA219采集芯片,可直接使用,采集的是负载端的电压,对一下因负载变化而造成电压波动,需要电压补偿的应用场合来说,非常实用,你懂的!
单片机源程序如下:
#include "ina219.h"
void INA_REG_Write(unsigned char reg,unsigned int data);
#ifdef INA_INSIDE_IIC
void INA_IIC_Delay()
{unsigned char x;
for(x=1;x>0;x--)
{
__NOP();__NOP();__NOP();__NOP();__NOP();
}
}
void INA_IIC_INIT(void) //IIC初始化
{
GPIO_InitTypeDef GPIO_INIT;
RCC_APB2PeriphClockCmd(IIC_RCC,ENABLE);
GPIO_INIT.GPIO_Mode=GPIO_Mode_Out_PP;
GPIO_INIT.GPIO_Pin=IIC_SDA | IIC_SCL;
GPIO_INIT.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(IIC_PORT,&GPIO_INIT);
IIC_SDA_H;
IIC_SCL_H;
}
void INA_IIC_SDA_OUT(void) //SDA配置为输出
{
GPIO_InitTypeDef GPIO_INIT;
GPIO_INIT.GPIO_Mode=GPIO_Mode_Out_PP;
GPIO_INIT.GPIO_Pin=IIC_SDA ;
GPIO_INIT.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(IIC_PORT,&GPIO_INIT);
}
void INA_IIC_SDA_IN(void) //SDA配置为输入
{
GPIO_InitTypeDef GPIO_INIT;
GPIO_INIT.GPIO_Mode=GPIO_Mode_IPU;
GPIO_INIT.GPIO_Pin=IIC_SDA ;
GPIO_INIT.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(IIC_PORT,&GPIO_INIT);
}
void INA_IIC_Start(void) //开始信号
{
IIC_SDA_H;
IIC_SCL_H;
INA_IIC_Delay();
IIC_SDA_L;
INA_IIC_Delay();
IIC_SDA_L;
}
void INA_IIC_Stop(void ) //结束信号
{
IIC_SDA_L;
IIC_SCL_H;
INA_IIC_Delay();
IIC_SDA_H;
INA_IIC_Delay();
IIC_SCL_L;
IIC_SCL_H;
IIC_SDA_H;
}
bool INA_IIC_ACK_Read(void) //读取应答信号
{
bool ack;
IIC_SDA_H;
INA_IIC_SDA_IN();
IIC_SCL_H;
INA_IIC_Delay();
if(IIC_SDA_READ() == SET) ack=false;
else ack=true;
IIC_SCL_L;
INA_IIC_SDA_OUT();
return ack;
}
void INA_IIC_ACK_Send(bool ack) //发送应答信号
{
IIC_SCL_L;
if(ack == true)
IIC_SDA_L;
else IIC_SDA_H;
IIC_SCL_H;
INA_IIC_Delay();
IIC_SCL_L;
}
void INA_IIC_Send_Byte(unsigned char byte) //IIC发送一位数据
{
unsigned char i;
IIC_SCL_L;
for(i=0;i<8;i++)
{
if(byte & 0x80 ) IIC_SDA_H;
else IIC_SDA_L;
IIC_SCL_H;
INA_IIC_Delay();
IIC_SCL_L;
INA_IIC_Delay();
byte<<=1;
}
INA_IIC_ACK_Read();
}
unsigned char INA_IIC_Read_Byte(void) //IIC读取一位数据
{
unsigned char i,byte=0;
INA_IIC_SDA_IN();
for(i=0;i<8;i++)
{
IIC_SCL_H;
byte<<=1;
if(IIC_SDA_READ() == SET) byte |= 0x01;
else byte &= 0xFE;
IIC_SCL_L;
INA_IIC_Delay();
}
INA_IIC_SDA_OUT();
return byte;
}
#endif
void INA_Read_Byte_s(unsigned char reg,unsigned char *data) //读两位数据
{
INA_IIC_Start();
INA_IIC_Send_Byte(INA219_ADDRESS); //发送INA219地址s
INA_IIC_Send_Byte(reg);
INA_IIC_Start();
INA_IIC_Send_Byte(INA219_ADDRESS+0x01); //设置iic为读模式
*data=INA_IIC_Read_Byte();
data++;
INA_IIC_ACK_Send(1);
*data=INA_IIC_Read_Byte();
INA_IIC_ACK_Send(0);
INA_IIC_Stop();
}
void INA_REG_Write(unsigned char reg,unsigned int data) //写寄存器 测试成功
{
unsigned char data_temp[2];
data_temp[0]=(unsigned char )(data>>8);
data_temp[1]=(unsigned char )(data & 0xFF);
INA_IIC_Start();
INA_IIC_Send_Byte(INA219_ADDRESS); //发送INA219地址
INA_IIC_Send_Byte(reg); //发送寄存器地址
INA_IIC_Send_Byte(data_temp[0]); //发送高8位数据
data++;
INA_IIC_Send_Byte(data_temp[1]) ; //发送低8位数据
INA_IIC_Stop();
}
void INA_Init(void )
{
INA_IIC_INIT();
INA_REG_Write(INA219_REG_CONFIG,INA219_CONFIG_value);
INA_REG_Write(INA219_REG_CALIBRATION,INA_CAL);
}
unsigned int INA_GET_Voltage_MV(void) //获取电压(单位:mv)
{
unsigned char data_temp[2];
INA_Read_Byte_s(0x02,data_temp);
return (int)((((data_temp[0]<<8)+data_temp[1]) >> 3)*4); //右移3为去掉:bit2,CNVR,OVF三位,再乘以 4MV (官方文档规定),得到当前总线的电压值
}
unsigned int INA_GET_Current_MA(void) //获取电流(单位:mA)
{
unsigned char data_temp[2];
INA_REG_Write(INA219_REG_CONFIG,INA219_CONFIG_value);
INA_Read_Byte_s(INA219_REG_CURRENT,data_temp);
return (int)((((data_temp[0]<<8)+data_temp[1]))*IAN_I_LSB); //得到寄存器的值在乘以每位对应的值(IAN_I_LSB)得到实际的电流
}
unsigned int INA_GET_Power_MW(void) //获取当前功率(单位:mw)
{
unsigned char data_temp[2];
INA_Read_Byte_s(INA219_REG_POWER,data_temp);
return (int)(((data_temp[0]<<8)+data_temp[1])*INA_Power_LSB); //得到寄存器的值在乘以每位对应的值(INA_Power_LSB)得到实际的功率
}
复制代码
#include <stdio.h>
#include <string.h>
#include "stm32f10x.h"
#include "stm32f10x_it.h"
#include "io.h"
//#include "key.h"
#include "delay.h"
//#include "timer.h"
#include "usart.h"
#include "adc.h"
//#include "24cxx.h"
//#include "menu.h"
#include "ina219.h"
void Uart1_PutString(char* buf,u8 len );
u8 Uart1_PutChar(u8 ch);
u8 Uart1_recChar(void);
void judge_command(void);
void manul_test(void);
void auto_test(void);
void debug_test(void);
void emerg(void);
//*DO01ON#----6
//DO01OFF---7
//uchar command_data[7];
//uchar RX_dat;
int STEP_flag;
//u8 count;
void SysInit (void)
{
SystemInit();//系统时钟配置 配置为72MHZ
delay_init();//延时函数初始化
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
IO_Init();
//TIM2_Int_Init(99,71);//1Mhz的计数频率,计数到100为0.1ms
//TIM3_Int_Init(99,7199);//10Khz的计数频率,计数到100为10ms
Adc_Init();
Usart_Init();
INA_Init();
}
int main(void)
{
// int flag1,flag2,flag3,flag4;
//flag1=0,flag2=0,flag3=0,flag4=0;
//float LDR1Adc,LDR2Adc;
SysInit();
delay_ms(1000);
}
复制代码
所有资料51hei提供下载:
INA219 程序(20191112).7z
(219.81 KB, 下载次数: 326)
2019-11-13 22:22 上传
点击文件名下载附件
下载积分: 黑币 -5
作者:
lgb51hei
时间:
2020-3-13 13:44
您好!依您给的驱动程序我使用STM32F103C8T6+INA219检测电流,精度是1mA。但我知道使用Arduino UON可以达到0.1mV。楼主是否有经验分享。礼尚往来互相学习进步!
作者:
1101192016
时间:
2020-5-13 14:27
兄弟,能不能给个流程图看一下啊,新手刚学,程序看着简单,但是完全不会啊
作者:
江上远帆
时间:
2020-11-9 10:44
感谢楼主,最近正好项目用到,非常感谢!
作者:
qwjsh
时间:
2020-11-18 17:59
有没有protus
作者:
西点钟灵毓秀
时间:
2020-11-20 08:59
看了一下,就是芯片太贵了
作者:
llchuan
时间:
2022-12-5 17:30
这么多头文件
作者:
rufong13
时间:
2023-10-30 21:57
项目有需求,正好学习下
作者:
rufong13
时间:
2023-11-4 22:34
有实际测试过的吗,测电流的精度能到多少啊
作者:
聆听风声
时间:
2024-1-27 17:27
感谢楼主,最近正好项目用到,非常感谢!
作者:
Chyyy06
时间:
2024-1-30 16:29
这个测量电压的范围是多少哈?
作者:
fyy020806
时间:
2024-7-14 15:41
lgb51hei 发表于 2020-3-13 13:44
您好!依您给的驱动程序我使用STM32F103C8T6+INA219检测电流,精度是1mA。但我知道使用Arduino UON可以达到 ...
这个是怎么用的呀,引脚怎么连的嘞
作者:
chuailiwei
时间:
2024-9-2 09:55
缺少反向电流的判断!
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1