找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 6827|回复: 10
收起左侧

STM32同时采集电压电流的芯片INA219源程序

  [复制链接]
ID:636709 发表于 2019-11-13 17:38 | 显示全部楼层 |阅读模式
在Keil5环境下编译的STM32驱动INA219采集芯片,可直接使用,采集的是负载端的电压,对一下因负载变化而造成电压波动,需要电压补偿的应用场合来说,非常实用,你懂的!

单片机源程序如下:
  1. #include "ina219.h"

  2. void INA_REG_Write(unsigned char reg,unsigned int data);

  3. #ifdef INA_INSIDE_IIC
  4. void INA_IIC_Delay()
  5. {unsigned char x;
  6.         for(x=1;x>0;x--)
  7.         {
  8.                 __NOP();__NOP();__NOP();__NOP();__NOP();
  9.         }
  10. }
  11. void INA_IIC_INIT(void)                //IIC初始化
  12. {
  13.         GPIO_InitTypeDef GPIO_INIT;
  14.         RCC_APB2PeriphClockCmd(IIC_RCC,ENABLE);
  15.         
  16.         GPIO_INIT.GPIO_Mode=GPIO_Mode_Out_PP;
  17.         GPIO_INIT.GPIO_Pin=IIC_SDA | IIC_SCL;
  18.         GPIO_INIT.GPIO_Speed=GPIO_Speed_50MHz;
  19.         GPIO_Init(IIC_PORT,&GPIO_INIT);
  20.         
  21.         IIC_SDA_H;
  22.         IIC_SCL_H;
  23. }

  24. void INA_IIC_SDA_OUT(void)        //SDA配置为输出
  25. {
  26.         GPIO_InitTypeDef GPIO_INIT;
  27.         GPIO_INIT.GPIO_Mode=GPIO_Mode_Out_PP;
  28.         GPIO_INIT.GPIO_Pin=IIC_SDA ;
  29.         GPIO_INIT.GPIO_Speed=GPIO_Speed_50MHz;
  30.         GPIO_Init(IIC_PORT,&GPIO_INIT);
  31. }
  32. void INA_IIC_SDA_IN(void)        //SDA配置为输入
  33. {
  34.         GPIO_InitTypeDef GPIO_INIT;
  35.         GPIO_INIT.GPIO_Mode=GPIO_Mode_IPU;
  36.         GPIO_INIT.GPIO_Pin=IIC_SDA ;
  37.         GPIO_INIT.GPIO_Speed=GPIO_Speed_50MHz;
  38.         GPIO_Init(IIC_PORT,&GPIO_INIT);
  39. }

  40. void INA_IIC_Start(void)        //开始信号
  41. {
  42.         IIC_SDA_H;
  43.         IIC_SCL_H;
  44.         INA_IIC_Delay();
  45.         IIC_SDA_L;
  46.         INA_IIC_Delay();
  47.         IIC_SDA_L;
  48. }
  49. void INA_IIC_Stop(void )        //结束信号
  50. {
  51.         IIC_SDA_L;
  52.         IIC_SCL_H;
  53.         INA_IIC_Delay();
  54.         IIC_SDA_H;
  55.         INA_IIC_Delay();
  56.         IIC_SCL_L;
  57.         
  58.         IIC_SCL_H;
  59.         IIC_SDA_H;
  60. }
  61. bool INA_IIC_ACK_Read(void)        //读取应答信号
  62. {
  63.         bool ack;
  64.         IIC_SDA_H;
  65.         INA_IIC_SDA_IN();

  66.         IIC_SCL_H;
  67.         INA_IIC_Delay();
  68.         if(IIC_SDA_READ() == SET) ack=false;
  69.         else ack=true;
  70.         IIC_SCL_L;
  71.         INA_IIC_SDA_OUT();
  72.         return ack;
  73. }
  74. void INA_IIC_ACK_Send(bool ack)        //发送应答信号
  75. {
  76.         IIC_SCL_L;
  77.         if(ack == true)
  78.                 IIC_SDA_L;
  79.         else IIC_SDA_H;
  80.         IIC_SCL_H;
  81.         INA_IIC_Delay();
  82.         IIC_SCL_L;
  83. }
  84. void INA_IIC_Send_Byte(unsigned char byte)        //IIC发送一位数据
  85. {
  86.         unsigned char i;
  87.         IIC_SCL_L;
  88.         for(i=0;i<8;i++)
  89.         {
  90.                 if(byte & 0x80 )        IIC_SDA_H;
  91.                 else IIC_SDA_L;
  92.                 IIC_SCL_H;
  93.                 INA_IIC_Delay();
  94.                 IIC_SCL_L;
  95.                 INA_IIC_Delay();
  96.                 byte<<=1;
  97.         }
  98.         INA_IIC_ACK_Read();
  99. }
  100. unsigned char  INA_IIC_Read_Byte(void)        //IIC读取一位数据
  101. {
  102.         unsigned char i,byte=0;
  103.         INA_IIC_SDA_IN();
  104.         for(i=0;i<8;i++)
  105.         {
  106.                 IIC_SCL_H;
  107.                 byte<<=1;
  108.                 if(IIC_SDA_READ() == SET) byte |= 0x01;
  109.                 else byte &= 0xFE;
  110.                 IIC_SCL_L;
  111.                 INA_IIC_Delay();
  112.         }
  113.         INA_IIC_SDA_OUT();
  114.         return byte;
  115. }
  116. #endif
  117. void INA_Read_Byte_s(unsigned char reg,unsigned char *data)        //读两位数据
  118. {
  119.         INA_IIC_Start();
  120.         INA_IIC_Send_Byte(INA219_ADDRESS);        //发送INA219地址s
  121.         INA_IIC_Send_Byte(reg);
  122.         
  123.         INA_IIC_Start();
  124.         INA_IIC_Send_Byte(INA219_ADDRESS+0x01);        //设置iic为读模式
  125.         *data=INA_IIC_Read_Byte();
  126.         data++;
  127.         INA_IIC_ACK_Send(1);
  128.         *data=INA_IIC_Read_Byte();
  129.         INA_IIC_ACK_Send(0);
  130.         INA_IIC_Stop();
  131. }
  132. void INA_REG_Write(unsigned char reg,unsigned int data)        //写寄存器                测试成功
  133. {
  134.         unsigned char data_temp[2];
  135.         data_temp[0]=(unsigned char )(data>>8);
  136.         data_temp[1]=(unsigned char )(data & 0xFF);
  137.         INA_IIC_Start();
  138.         INA_IIC_Send_Byte(INA219_ADDRESS);        //发送INA219地址
  139.         INA_IIC_Send_Byte(reg);                                                        //发送寄存器地址
  140.         INA_IIC_Send_Byte(data_temp[0]);                                                //发送高8位数据
  141.         data++;
  142.         INA_IIC_Send_Byte(data_temp[1])        ;                                        //发送低8位数据
  143.         INA_IIC_Stop();
  144. }

  145. void INA_Init(void )        
  146. {
  147.         INA_IIC_INIT();
  148.         INA_REG_Write(INA219_REG_CONFIG,INA219_CONFIG_value);
  149.         INA_REG_Write(INA219_REG_CALIBRATION,INA_CAL);
  150. }
  151. unsigned int INA_GET_Voltage_MV(void)        //获取电压(单位:mv)
  152. {
  153.         unsigned char data_temp[2];
  154.         INA_Read_Byte_s(0x02,data_temp);
  155.         return (int)((((data_temp[0]<<8)+data_temp[1]) >> 3)*4);        //右移3为去掉:bit2,CNVR,OVF三位,再乘以 4MV (官方文档规定),得到当前总线的电压值
  156. }
  157. unsigned int INA_GET_Current_MA(void)                //获取电流(单位:mA)
  158. {
  159.         unsigned char data_temp[2];
  160.         INA_REG_Write(INA219_REG_CONFIG,INA219_CONFIG_value);
  161.         INA_Read_Byte_s(INA219_REG_CURRENT,data_temp);
  162.         return (int)((((data_temp[0]<<8)+data_temp[1]))*IAN_I_LSB);                //得到寄存器的值在乘以每位对应的值(IAN_I_LSB)得到实际的电流
  163. }
  164. unsigned int INA_GET_Power_MW(void)                //获取当前功率(单位:mw)
  165. {
  166.         unsigned char data_temp[2];
  167.         INA_Read_Byte_s(INA219_REG_POWER,data_temp);
  168.         return (int)(((data_temp[0]<<8)+data_temp[1])*INA_Power_LSB);        //得到寄存器的值在乘以每位对应的值(INA_Power_LSB)得到实际的功率
  169. }
复制代码

  1. #include <stdio.h>
  2. #include <string.h>
  3. #include "stm32f10x.h"
  4. #include "stm32f10x_it.h"
  5. #include "io.h"
  6. //#include "key.h"
  7. #include "delay.h"
  8. //#include "timer.h"
  9. #include "usart.h"
  10. #include "adc.h"
  11. //#include "24cxx.h"         
  12. //#include "menu.h"
  13. #include "ina219.h"
  14. void Uart1_PutString(char* buf,u8 len );
  15. u8 Uart1_PutChar(u8 ch);
  16. u8 Uart1_recChar(void);
  17. void judge_command(void);
  18. void manul_test(void);
  19. void auto_test(void);
  20. void debug_test(void);
  21. void emerg(void);
  22. //*DO01ON#----6
  23. //DO01OFF---7
  24. //uchar command_data[7];

  25. //uchar RX_dat;
  26. int STEP_flag;

  27. //u8 count;
  28. void SysInit (void)
  29. {        
  30.         SystemInit();//系统时钟配置 配置为72MHZ
  31.         delay_init();//延时函数初始化        
  32.         NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
  33.         IO_Init();
  34.         //TIM2_Int_Init(99,71);//1Mhz的计数频率,计数到100为0.1ms
  35.         //TIM3_Int_Init(99,7199);//10Khz的计数频率,计数到100为10ms
  36.         Adc_Init();
  37.         Usart_Init();
  38.         INA_Init();
  39. }

  40. int main(void)
  41. {
  42. //        int flag1,flag2,flag3,flag4;
  43.         //flag1=0,flag2=0,flag3=0,flag4=0;
  44.         //float LDR1Adc,LDR2Adc;        

  45.         SysInit();
  46.         delay_ms(1000);
  47.         


  48.         }
复制代码

所有资料51hei提供下载:
INA219 程序(20191112).7z (219.81 KB, 下载次数: 295)

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

ID:706347 发表于 2020-3-13 13:44 | 显示全部楼层
您好!依您给的驱动程序我使用STM32F103C8T6+INA219检测电流,精度是1mA。但我知道使用Arduino UON可以达到0.1mV。楼主是否有经验分享。礼尚往来互相学习进步!
回复

使用道具 举报

ID:750792 发表于 2020-5-13 14:27 | 显示全部楼层
兄弟,能不能给个流程图看一下啊,新手刚学,程序看着简单,但是完全不会啊
回复

使用道具 举报

ID:472390 发表于 2020-11-9 10:44 | 显示全部楼层
感谢楼主,最近正好项目用到,非常感谢!
回复

使用道具 举报

ID:787283 发表于 2020-11-18 17:59 | 显示全部楼层
有没有protus
回复

使用道具 举报

ID:87000 发表于 2020-11-20 08:59 | 显示全部楼层
看了一下,就是芯片太贵了
回复

使用道具 举报

ID:1055821 发表于 2022-12-5 17:30 | 显示全部楼层
这么多头文件
回复

使用道具 举报

ID:1097318 发表于 2023-10-30 21:57 | 显示全部楼层
项目有需求,正好学习下
回复

使用道具 举报

ID:1097318 发表于 2023-11-4 22:34 | 显示全部楼层
有实际测试过的吗,测电流的精度能到多少啊
回复

使用道具 举报

ID:163796 发表于 2024-1-27 17:27 | 显示全部楼层
感谢楼主,最近正好项目用到,非常感谢!
回复

使用道具 举报

ID:1110374 发表于 2024-1-30 16:29 | 显示全部楼层
这个测量电压的范围是多少哈?
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表