此教程案例可以直接在正点原子stm32f429运行
ina226配置文件,ina226.c
#include "ina226.h"
#include "usart.h"
#include "delay.h"
/*
不确定具体电阻大小
*/
INA226 INA226_data;
void INA226_Init(void)
{
IIC_Init();
delay_ms(10);
INA226_SendData(INA226_ADDR1,CFG_REG,0x484f);//设置转换时间204us,求平均值次数128,采样时间为204*128,设置模式为分流和总线连续模式
INA226_SendData(INA226_ADDR1,CAL_REG,0x0012);//设置分流电压转电流转换参数
}
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;
}
/*
u8 INA226_AlertAddr()
{
u8 temp;
IIC_Start();
IIC_Send_Byte(INA226_GETALADDR);
IIC_Wait_Ack();
temp = IIC_Read_Byte(1);
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
u16 INA226_Get_ID(u8 addr)
{
u32 temp=0;
INA226_SetRegPointer(addr,INA226_GET_ADDR);
temp = INA226_ReadData(addr);
return (u16)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,感觉这个值是测不准的,所以下面改成2.2了
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;
}
u16 INA226_Get_Power(u8 addr)
{
int16_t temp=0;
INA226_SetRegPointer(addr,PWR_REG);
temp = INA226_ReadData(addr);
return (u16)temp;
}
void GetVoltage(float *Voltage)//mV
{
Voltage[0] = INA226_GetVoltage(INA226_ADDR1)*1.25f;
}
void Get_Shunt_voltage(float *Voltage)//uV
{
Voltage[0] = (INA226_GetShuntVoltage(INA226_ADDR1)*2.2);//这里原来乘的系数是2.5
}
void Get_Shunt_Current(float *Current)//mA
{
Current[0] = (INA226_GetShunt_Current(INA226_ADDR1)* 2.5f);
}
void GetPower()//W
{
GetVoltage(&INA226_data.voltageVal); //mV
Get_Shunt_voltage(&INA226_data.Shunt_voltage); //uV
Get_Shunt_Current(&INA226_data.Shunt_Current); //mA
INA226_data.powerVal=INA226_data.voltageVal*0.001f * INA226_data.Shunt_Current*0.001f;
}
/*
void Get_Power(float *Current)//W
{
Current[0] = (INA226_Get_Power(INA226_ADDR1)*50);
}
*/
ina226.h
#ifndef __INA226_H
#define __INA226_H
#include "sys.h"
#include "myiic.h"
#define CFG_REG 0x00 //
#define SV_REG 0x01 //分流电压, 此处分流电阻为 0.1欧
#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 //包含唯一的芯片标识号
#define INA226_ADDR1 0x80
//#define INA226_GETALADDR 0x14
typedef struct
{
float voltageVal; //mV
float Shunt_voltage; //uV
float Shunt_Current; //mA
float powerVal;
}INA226;
void INA226_Init(void);
void INA226_SetRegPointer(u8 addr,u8 reg);
void INA226_SendData(u8 addr,u8 reg,u16 data);
u16 INA226_ReadData(u8 addr);
//u8 INA226_AlertAddr(void);
u16 INA226_Get_ID(u8 addr); //获取 id
u16 INA226_GetVoltage( u8 addr); //获取总线电压
u16 INA226_GetShunt_Current(u8 addr); //获取分流电流
u16 INA226_GetShuntVoltage(u8 addr); //分流电压
u16 INA226_Get_Power(u8 addr); //获取功率
u16 INA226_GET_CAL_REG(u8 addr);
void GetVoltage(float *Voltage);
void Get_Shunt_voltage(float *Current);
void Get_Shunt_Current(float *Current);
//void Get_Power(float *Current);
void GetPower();//W
extern INA226 INA226_data;
#endif
模拟iic:使用官方库提供的iic通道
iic.c
#include "myiic.h"
#include "delay.h"
//////////////////////////////////////////////////////////////////////////////////
//本程序只供学习使用,未经作者许可,不得用于其它任何用途
//ALIENTEK STM32F429开发板
//IIC驱动代码
//正点原子@ALIENTEK
//技术论坛:www.openedv.com
//创建日期:2016/1/13
//版本:V1.0
//版权所有,盗版必究。
//Copyright(C) 广州市星翼电子科技有限公司 2014-2024
//All rights reserved
//////////////////////////////////////////////////////////////////////////////////
//IIC初始化
void IIC_Init(void)
{
GPIO_InitTypeDef GPIO_Initure;
__HAL_RCC_GPIOH_CLK_ENABLE(); //使能GPIOH时钟
//PH4,5初始化设置
GPIO_Initure.Pin=GPIO_PIN_4|GPIO_PIN_5;
GPIO_Initure.Mode=GPIO_MODE_OUTPUT_PP; //推挽输出
GPIO_Initure.Pull=GPIO_PULLUP; //上拉
GPIO_Initure.Speed=GPIO_SPEED_FAST; //快速
HAL_GPIO_Init(GPIOH,&GPIO_Initure);
IIC_SDA=1;
IIC_SCL=1;
}
//产生IIC起始信号
void IIC_Start(void)
{
SDA_OUT(); //sda线输出
IIC_SDA=1;
IIC_SCL=1;
delay_us(4);
IIC_SDA=0;//START:when CLK is high,DATA change form high to low
delay_us(4);
IIC_SCL=0;//钳住I2C总线,准备发送或接收数据
}
//产生IIC停止信号
void IIC_Stop(void)
{
SDA_OUT();//sda线输出
IIC_SCL=0;
IIC_SDA=0;//STOP:when CLK is high DATA change form low to high
delay_us(4);
IIC_SCL=1;
delay_us(4);
IIC_SDA=1;//发送I2C总线结束信号
}
//等待应答信号到来
//返回值:1,接收应答失败
// 0,接收应答成功
u8 IIC_Wait_Ack(void)
{
u8 ucErrTime=0;
SDA_IN(); //SDA设置为输入
IIC_SDA=1;delay_us(1);
IIC_SCL=1;delay_us(1);
while(READ_SDA)
{
ucErrTime++;
if(ucErrTime>250)
{
IIC_Stop();
return 1;
}
}
IIC_SCL=0;//时钟输出0
return 0;
}
//产生ACK应答
void IIC_Ack(void)
{
IIC_SCL=0;
SDA_OUT();
IIC_SDA=0;
delay_us(2);
IIC_SCL=1;
delay_us(2);
IIC_SCL=0;
}
//不产生ACK应答
void IIC_NAck(void)
{
IIC_SCL=0;
SDA_OUT();
IIC_SDA=1;
delay_us(2);
IIC_SCL=1;
delay_us(2);
IIC_SCL=0;
}
//IIC发送一个字节
//返回从机有无应答
//1,有应答
//0,无应答
void IIC_Send_Byte(u8 txd)
{
u8 t;
SDA_OUT();
IIC_SCL=0;//拉低时钟开始数据传输
for(t=0;t<8;t++)
{
IIC_SDA=(txd&0x80)>>7;
txd<<=1;
delay_us(2); //对TEA5767这三个延时都是必须的
IIC_SCL=1;
delay_us(2);
IIC_SCL=0;
delay_us(2);
}
}
//读1个字节,ack=1时,发送ACK,ack=0,发送nACK
u8 IIC_Read_Byte(unsigned char ack)
{
unsigned char i,receive=0;
SDA_IN();//SDA设置为输入
for(i=0;i<8;i++ )
{
IIC_SCL=0;
delay_us(2);
IIC_SCL=1;
receive<<=1;
if(READ_SDA)receive++;
delay_us(1);
}
if (!ack)
IIC_NAck();//发送nACK
else
IIC_Ack(); //发送ACK
return receive;
}
iic.h
#ifndef _MYIIC_H
#define _MYIIC_H
#include "sys.h"
//////////////////////////////////////////////////////////////////////////////////
//本程序只供学习使用,未经作者许可,不得用于其它任何用途
//ALIENTEK STM32F429开发板
//IIC驱动代码
//正点原子@ALIENTEK
//技术论坛:www.openedv.com
//创建日期:2016/1/13
//版本:V1.0
//版权所有,盗版必究。
//Copyright(C) 广州市星翼电子科技有限公司 2014-2024
//All rights reserved
//////////////////////////////////////////////////////////////////////////////////
//IO方向设置
#define SDA_IN() {GPIOH->MODER&=~(3<<(5*2));GPIOH->MODER|=0<<5*2;} //PH5输入模式
#define SDA_OUT() {GPIOH->MODER&=~(3<<(5*2));GPIOH->MODER|=1<<5*2;} //PH5输出模式
//IO操作
#define IIC_SCL PHout(4) //SCL
#define IIC_SDA PHout(5) //SDA
#define READ_SDA PHin(5) //输入SDA
//IIC所有操作函数
void IIC_Init(void); //初始化IIC的IO口
void IIC_Start(void); //发送IIC开始信号
void IIC_Stop(void); //发送IIC停止信号
void IIC_Send_Byte(u8 txd); //IIC发送一个字节
u8 IIC_Read_Byte(unsigned char ack);//IIC读取一个字节
u8 IIC_Wait_Ack(void); //IIC等待ACK信号
void IIC_Ack(void); //IIC发送ACK信号
void IIC_NAck(void); //IIC不发送ACK信号
void IIC_Write_One_Byte(u8 daddr,u8 addr,u8 data);
u8 IIC_Read_One_Byte(u8 daddr,u8 addr);
#endif