数码之家

 找回密码
 立即注册

QQ登录

只需一步,快速开始

微信登录

微信扫一扫,快速登录

搜索
查看: 2420|回复: 14

[C51] INA226测量电压是实际值的两倍,请大家帮忙看看是硬件还是程序有问题

[复制链接]
发表于 2022-5-14 15:56:17 | 显示全部楼层 |阅读模式
本帖最后由 scjp 于 2022-5-14 19:45 编辑



程序里读取电压寄存器的部分
这样调用的       I2C_read_reg(0x80,0x02)*1.25;


unsigned int I2C_read_reg(unsigned int slaveaddr,unsigned int regaddr)
{
   unsigned int error=0;
   unsigned int i=0;
   unsigned int readbuffer=0;
   
   IIC_Start();
   IIC_Send_Byte(slaveaddr|0x00);
   if(IIC_Wait_Ack())
       error|=0x01;
   
   IIC_Send_Byte(regaddr);
   if(IIC_Wait_Ack())
       error|=0x02;
   IIC_Stop();

   IIC_Start();
   IIC_Send_Byte(slaveaddr|0x01);
   if(~IIC_Wait_Ack())
       //error|=0x04;
    {
        readbuffer=IIC_Read_Byte(1)*256;   
        readbuffer+=IIC_Read_Byte(0);
    }   
    IIC_Stop();   
    return readbuffer;
   
}


程序全部是这样的,网上找的模拟IIC然后改的

void IIC_Start()
{
    INA226_SCL=1;
    INA226_SDA=1;
    I2C_Delay();
    INA226_SDA=0;
    I2C_Delay();
    INA226_SCL=0;
    //I2C_Delay();
}

void IIC_Stop()
{
    INA226_SDA=0;
    INA226_SCL=1;
    I2C_Delay();
    INA226_SDA=1;
    //I2C_Delay();
}

void I2C_ACK(void)        //    ?摎怣崋
{
    INA226_SDA=0;
    I2C_Delay();
    INA226_SCL=1;
    I2C_Delay();
    INA226_SCL=0;
    INA226_SDA=1;
}

void I2C_NACK(void)        //旕?摎怣崋
{
    INA226_SDA=1;
    I2C_Delay();
    INA226_SCL=1;
    I2C_Delay();
    INA226_SCL=0;
    I2C_Delay();
    //INA226_SDA=0;
}

void IIC_Send_Byte(unsigned char send_data)
{
    unsigned int i;
    for(i=0;i<8;i++)
    {
        if(send_data&(0X80>>i))
            INA226_SDA=1;
        else
            INA226_SDA=0;
        I2C_Delay();
        INA226_SCL=1;
        I2C_Delay();
        INA226_SCL=0;
        I2C_Delay();
    }
}

unsigned int IIC_Read_Byte(unsigned int ack)
{
    unsigned int read_data=0;
    unsigned int i;
    unsigned int readbit;
   
    for(i=0;i<8;i++)
    {
        INA226_SCL=1;
        I2C_Delay();
        if(INA226_SDA)
            readbit=0x01;
        else
            readbit=0;         
        INA226_SCL=0;
        I2C_Delay();   
        read_data= (read_data|readbit)<<1;
    }
   
    //I2C_Delay();
    //Delay1ms();
    if(ack==0)
        I2C_NACK();
    else
        I2C_ACK();
   
    return read_data;
}


unsigned int IIC_Wait_Ack()
{
    unsigned int receive;
   
    INA226_SDA=1;
    I2C_Delay();
    INA226_SCL=1;
    I2C_Delay();
    //Delay1ms();
    //Delay1ms();
    if(INA226_SDA)
        receive=1;
    else   
        receive=0;
    INA226_SCL=0;
    I2C_Delay();
    return receive;   
}




本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册 微信登录

x
发表于 2022-5-14 16:15:37 | 显示全部楼层
如果得到的数值比实际的大一倍,把 readbuffer右移一位即可。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-5-14 16:22:36 | 显示全部楼层
温力口 发表于 2022-5-14 16:15
如果得到的数值比实际的大一倍,把 readbuffer右移一位即可。

我一开始也是这么想的,把移8位改成移7位。想知道问题出在哪里了。
回复 支持 反对

使用道具 举报

发表于 2022-5-14 16:27:25 | 显示全部楼层
采样电阻33欧?CAL校准过了吗?
回复 支持 反对

使用道具 举报

发表于 2022-5-14 16:51:05 | 显示全部楼层
arduino直接加载了无脑直接用
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-5-14 17:21:03 | 显示全部楼层
ww5223017240 发表于 2022-5-14 16:27
采样电阻33欧?CAL校准过了吗?

33毫欧,只读电压,电压应该是不用校准的吧。
回复 支持 反对

使用道具 举报

发表于 2022-5-14 17:37:40 | 显示全部楼层
应该是程序问题
回复 支持 反对

使用道具 举报

发表于 2022-5-14 18:34:13 | 显示全部楼层
计算过程呢?
断点看看寄存器高低两个8位读到的是什么。
回复 支持 反对

使用道具 举报

发表于 2022-5-14 19:01:47 | 显示全部楼层
一直都是用片内adc。。。也还行
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-5-14 19:47:54 | 显示全部楼层
crazy0qwer 发表于 2022-5-14 18:34
计算过程呢?
断点看看寄存器高低两个8位读到的是什么。

就是寄存器值x1.25,没有别的计算。
stc的单片机,没有调试环境。
已经把程序全文传上来了,怀疑是不是IIC时序有问题。
回复 支持 反对

使用道具 举报

发表于 2022-5-14 20:05:18 | 显示全部楼层
上两天刚刚使用了INA3221,感觉测量电压还是很准的,测量电流精度同取样电阻有关
回复 支持 反对

使用道具 举报

发表于 2022-5-14 20:52:52 | 显示全部楼层
scjp 发表于 2022-5-14 19:47
就是寄存器值x1.25,没有别的计算。
stc的单片机,没有调试环境。
已经把程序全文传上来了,怀疑是不是II ...

这应该还不是全部代码。

两倍说明你实际值的前一位总是1,IIC时序没看出有什么问题。
建议你直接输出读取到的高低八位数据,不要处理,先确认读取正确再看后面转换过程。
回复 支持 反对

使用道具 举报

发表于 2022-5-14 21:29:24 | 显示全部楼层
for(i=0;i<8;i++)
    {
        INA226_SCL=1;
        I2C_Delay();
        if(INA226_SDA)
            readbit=0x01;
        else
            readbit=0;         
        INA226_SCL=0;
        I2C_Delay();   
        read_data= (read_data|readbit)<<1;
    }


read_data= (read_data|readbit)<<1;这里有问题
这个左移操作放在for循环最后面相当于左移了8次,仔细想想是不是最后一次移位操作是多余的?
把这一步拆开来,分为或运算与左移,左移放在for循环最前面,或运算放在for循环最后面。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-5-14 21:31:45 | 显示全部楼层
crazy0qwer 发表于 2022-5-14 20:52
这应该还不是全部代码。

两倍说明你实际值的前一位总是1,IIC时序没看出有什么问题。

感谢你提供思路,已经找到问题了,直接输出后发现寄存器多了一位,读取数据时多移位了一次,导致所有数据都左移了一位。
  for(i=0;i<8;i++)
    {
        INA226_SCL=1;
        I2C_Delay();
        if(INA226_SDA)
            readbit=0x01;
        else
            readbit=0;         
        INA226_SCL=0;
        I2C_Delay();   
        read_data= (read_data|readbit)<<1;这里执行了8次,应该最后一次不移位
    }
回复 支持 反对

使用道具 举报

发表于 2022-5-19 14:03:37 | 显示全部楼层
0位没计。清人忘了自己
回复 支持 反对

使用道具 举报

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

本版积分规则

APP|手机版|小黑屋|关于我们|联系我们|法律条款|技术知识分享平台

闽公网安备35020502000485号

闽ICP备2021002735号-2

GMT+8, 2025-7-23 11:04 , Processed in 0.124800 second(s), 11 queries , Redis On.

Powered by Discuz!

© 2006-2025 MyDigit.Net

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