【发布时间】:2017-03-22 22:56:01
【问题描述】:
所以我根据this计算了校准寄存器值:
我的分流电阻值为 0.01 欧姆。即使我根据我的分流值校准它,我的电流也会关闭
所有电流显示错误值(例如它应该显示7.8mA,它显示1mA
以下是我的代码:
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <endian.h>
#include <string.h>
#include <time.h>
#include <getopt.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <linux/i2c-dev.h>
#define CONFIG_REG 0
#define SHUNT_REG 1
#define BUS_REG 2
#define POWER_REG 3
#define CURRENT_REG 4
#define CALIBRATION_REG 5
#define INA_ADDRESS1 0x40
#define INA_ADDRESS2 0x41
int interval = 60;
int i2c_bus = 1;
int i2c_address1 = INA_ADDRESS1;
int i2c_address2 = INA_ADDRESS2;
int handle;
int i2c_read( void *buf, int len )
{
int rc = 0;
if ( read( handle, buf, len ) != len )
{
printf( "I2C read failed: %s\n", strerror( errno ) );
rc = -1;
}
return 0;
}
int i2c_write( void *buf, int len )
{
int rc = 0;
if ( write( handle, buf, len ) != len )
{
printf( "I2C write failed: %s\n", strerror( errno ) );
rc = -1;
}
return rc;
}
int register_read( unsigned char reg, unsigned short *data )
{
int rc = -1;
unsigned char bite[ 4 ];
bite[ 0 ] = reg;
if ( i2c_write( bite, 1 ) == 0 )
{
if ( i2c_read( bite, 2 ) == 0 )
{
*data = ( bite[ 0 ] << 8 ) | bite[ 1 ];
rc = 0;
}
}
return rc;
}
int register_write( unsigned char reg, unsigned short data )
{
int rc = -1;
unsigned char bite[ 4 ];
bite[ 0 ] = reg;
bite[ 1 ] = ( data >> 8 ) & 0xFF;
bite[ 2 ] = ( data & 0xFF );
if ( i2c_write( bite, 3 ) == 0 )
{
rc = 0;
}
return rc;
}
int get_voltage( float *mv )
{
short bus;
if ( register_read( BUS_REG, (unsigned short*)&bus ) != 0 )
{
return -1;
}
*mv = ( float )( ( bus & 0xFFF8 ) >> 1 );
return 0;
}
int get_current( float *ma )
{
short shunt;
if ( register_read( SHUNT_REG, &shunt ) != 0 )
{
return -1;
}
*ma = (float)shunt / 10;
return 0;
}
void show_current( void )
{
float ma;
if ( get_current( &ma ) )
{
fprintf( stderr, "Error reading current\n" );
return;
}
}
void show_voltage( void )
{
float mv;
if ( get_voltage( &mv ) )
{
fprintf( stderr, "Error reading voltage\n" );
return;
}
printf( "%4.0f\n", mv );
}
void show_voltage_current( void )
{
float mv, ma;
if ( get_current( &ma ) || get_voltage( &mv ) )
{
fprintf( stderr, "Error reading voltage/current\n" );
return;
}
else
{
printf( "Load Voltage: %g Current: %4.1fmA\n", (mv/1000), (ma) );
}
}
int main( int argc, char *argv[] )
{
char filename[ 20 ];
register_write(CALIBRATION_REG, 4096);
snprintf( filename, 19, "/dev/i2c-%d", i2c_bus );
handle = open( filename, O_RDWR );
if ( handle < 0 )
{
fprintf( stderr, "Error opening bus %d: %s\n", i2c_bus, strerror( errno ) );
exit( 1 );
}
if ( ioctl( handle, I2C_SLAVE, i2c_address1 ) < 0 )
{
fprintf( stderr, "Error setting address %02X: %s\n", i2c_address1, strerror( errno ) );
exit( 1 );
}
show_voltage_current();
sleep(1);
if ( ioctl( handle, I2C_SLAVE, i2c_address2 ) < 0 )
{
fprintf( stderr, "Error setting address %02X: %s\n", i2c_address2, strerror( errno ) );
exit( 1 );
show_voltage_current();
sleep(1);
}
return 0;
}
【问题讨论】:
标签: linux i2c calibration