之前要做一个电量计,采用INA219电流检测芯片,参考了网上大神的代码后发现在STM32上可用,移植到STM8后不可用,后来找到了官方的示例demo,综合网上大神代码调试后成功驱动,测电流、电压、功率,精确度很高。
现在分享出来供大家参考,直接贴代码:
main.c
int main(void) { ina219_init(); while(1) { //根据具体需求调用检测电流电压的函数 } }
ina219.c
#include "ina219.h" u8 ina219_busVolt_LSB_mV = 4; // Bus Voltage LSB value = 4mV u8 ina219_shuntVolt_LSB_uV = 10; // Shunt Voltage LSB value = 10uV unsigned short ina219_calValue = 0; u32 ina219_current_LSB_uA; u32 ina219_power_LSB_mW; INA219_DATA ina219_data; void INA_SCL_OUT(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(INA219_I2C_GPIO_CLOCK, ENABLE); /* Configure I2C1 pins: PB12->SCL->OUT */ GPIO_InitStructure.GPIO_Pin = INA219_I2C_SCL_PIN; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_Init(INA219_I2C_PORT, &GPIO_InitStructure); GPIO_SetBits(INA219_I2C_PORT, INA219_I2C_SCL_PIN); } void INA_SDA_OUT(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(INA219_I2C_GPIO_CLOCK, ENABLE); /* Configure I2C1 pins: PB14->SDA-OUT */ GPIO_InitStructure.GPIO_Pin = INA219_I2C_SDA_PIN; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_Init(INA219_I2C_PORT, &GPIO_InitStructure); GPIO_SetBits(INA219_I2C_PORT, INA219_I2C_SDA_PIN); } void INA_SDA_IN(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(INA219_I2C_GPIO_CLOCK, ENABLE); /* Configure I2C1 pins: PB14->SDA-IN */ GPIO_InitStructure.GPIO_Pin = INA219_I2C_SDA_PIN; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; GPIO_Init(INA219_I2C_PORT, &GPIO_InitStructure); } void INA_IIC_Start(void) { INA_SDA_OUT(); INA_SCL_OUT(); INA_SDA_SET; INA_SCL_SET; INA_SDA_CLR; INA_SCL_CLR; } void INA_IIC_Stop(void) { INA_SDA_OUT(); INA_SDA_CLR; INA_SCL_SET; INA_SDA_SET; } void INA_IIC_Set_Ack(unsigned char ack) { INA_SDA_OUT(); if(ack) { INA_SDA_SET; } else { INA_SDA_CLR; } INA_SCL_SET; INA_SCL_CLR; } unsigned char INA_IIC_Get_Ack(void) { unsigned char ack; INA_SDA_IN(); INA_SDA_SET; INA_SCL_SET; if(INA_SDA_TST) { ack = 1; } else { ack = 0; } INA_SCL_CLR; return(ack); } void INA_IIC_Write_8bits(unsigned char dat) { unsigned char i; INA_SDA_OUT(); for(i = 8; i; i--) { if(dat & 0x80) { INA_SDA_SET; } else { INA_SDA_CLR; } INA_SCL_SET; dat <<= 1; INA_SCL_CLR; } } unsigned char INA_IIC_Read_8bits(void) { unsigned char i, dat; INA_SDA_IN(); INA_SDA_SET; dat = 0; for(i = 8; i; i--) { INA_SCL_SET; dat <<= 1; if(INA_SDA_TST) dat++; INA_SCL_CLR; } return(dat); } void INA_IIC_Write_Byte(unsigned char reg, unsigned char dat) { unsigned char dev = INA219_I2C_ADDRESS; INA_IIC_Start(); // dev &= ~0x01; INA_IIC_Write_8bits(dev); INA_IIC_Get_Ack(); INA_IIC_Write_8bits(reg); INA_IIC_Get_Ack(); INA_IIC_Write_8bits(dat); INA_IIC_Get_Ack(); INA_IIC_Stop(); } unsigned char INA_IIC_Read_Byte(unsigned char reg) { unsigned char dat; unsigned char dev = INA219_I2C_ADDRESS; INA_IIC_Start(); // dev &= ~0x01; INA_IIC_Write_8bits(dev); INA_IIC_Get_Ack(); INA_IIC_Write_8bits(reg); INA_IIC_Get_Ack(); INA_IIC_Start(); dev |= 0x01; INA_IIC_Write_8bits(dev); INA_IIC_Get_Ack(); dat = INA_IIC_Read_8bits(); INA_IIC_Set_Ack(1); INA_IIC_Stop(); return (dat); } void INA_IIC_Write_Bytes(unsigned char reg, unsigned char *dat, unsigned char num) { unsigned char dev = INA219_I2C_ADDRESS; INA_IIC_Start(); // dev &= ~0x01; INA_IIC_Write_8bits(dev); INA_IIC_Get_Ack(); INA_IIC_Write_8bits(reg); INA_IIC_Get_Ack(); while(num--) { INA_IIC_Write_8bits(*dat); INA_IIC_Get_Ack(); dat++