STM8L152通过模拟IIC读取INA226电压电流问题,求解各位

2019-07-19 20:28发布

大家好,这个问题搞了几天了,头大,不知道问题在哪里,单片机跟INA226就是通过IIC通讯,没别的连接了,通过软件模拟IIC的方式,我想是不是我的读取代码有问题,特意贴出来,请求大家帮我看看,谢谢!
#define SCL_H()   (GPIO_SetBits(GPIOC,GPIO_Pin_1))
#define SCL_L()   (GPIO_ResetBits(GPIOC,GPIO_Pin_1))

#define SDA_H()   (GPIO_SetBits(GPIOC,GPIO_Pin_0))
#define SDA_L()   (GPIO_ResetBits(GPIOC,GPIO_Pin_0))

#define SDA_out() (GPIO_Init(GPIOC,GPIO_Pin_0,GPIO_Mode_Out_PP_High_Slow))
#define SDA_in()  (GPIO_Init(GPIOC,GPIO_Pin_0,GPIO_Mode_In_PU_No_IT))
#define Read_SDA()  (GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_0))


#define INA226_ADDRESS    0x80

#define                CFG_REG                 0x00
#define                SV_REG                         0x01
#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_GETALADDR        0x14


void delay_nus(u16 i)
{
    while(i --);
}


//------------------------------------------------------------------------------
//子程序IIC_Start
//------------------------------------------------------------------------------
void IIC_Start(void)
{
        SDA_out();
        delay_nus(2);// 1us
        SDA_H();
        SCL_H();
        delay_nus(8); // 4us
        SDA_L();
        delay_nus(8); // 4us
        SCL_L();
        delay_nus(8);    // 4us
}

//------------------------------------------------------------------------------
//子程序IIC_Stop(void)
//------------------------------------------------------------------------------
void IIC_Stop(void)
{
        SDA_out();
        SCL_L();                              //
        delay_nus(8); // 4us
        SDA_L();                               
        delay_nus(8); // 4us
        SCL_H();
        delay_nus(8);// 4us
        SDA_H();
        delay_nus(8);// 4us
}

u8 IIC_WaitAck(void)
{           
        u8 ucErrTime=0;
        SDA_in();   
        SDA_H();delay_nus(2);// 1us           
        SCL_H();delay_nus(2);         // 1us
        while(Read_SDA())
        {
                ucErrTime++;
                if(ucErrTime>250)
                {
                        IIC_Stop();
                        return 1;
                }
        }
        SCL_L();
        return 0;            
}

void IIC_Ack(void)
{      
        SDA_out();
        SCL_L();
        delay_nus(4); // 2us
        SDA_L();
        delay_nus(4);// 2us
        SCL_H();
        delay_nus(4);// 2us
        SCL_L();
        delay_nus(4);// 2us
}

void IIC_NoAck(void)
{      
        SDA_out();
        SCL_L();
        delay_nus(4);// 2us
        SDA_H();
        delay_nus(4);// 2us
        SCL_H();
        delay_nus(4);// 2us
        SCL_L();
        delay_nus(4);// 2us
}

void IIC_WriteByte(u8 byte)
{             
        u8 i = 0;
        SDA_out();
        for(i = 0; i < 8; i++)
        {
                SCL_L();
                delay_nus(4);// 2us
                if(byte & 0x80)
                {
                        SDA_H();
                }
                else
                {
                        SDA_L();
                }
                delay_nus(4);
                SCL_H();
                delay_nus(4);
                byte<<=1;
        }
        SCL_L();
        delay_nus(4);
}

u8 IIC_ReadByte(u8 ack)
{
        u8 i,ReadByte;
        SDA_out();      
        SDA_H();
        SDA_in();
        for(i = 0; i < 8; i++)
        {       
                ReadByte <<= 1;
                SCL_L();
                delay_nus(4);// 2us
                SCL_H();
                delay_nus(4);// 2us
                if(Read_SDA())
                {
                        ReadByte |= 0x01;
                }
                else
                {
                        ReadByte &= ~(0x01);       
                }
                delay_nus(6);// 3us
                SCL_L();
                delay_nus(6);// 3us
        }       
        if (!ack)
        IIC_NoAck();
        else
        IIC_Ack();
        SDA_out();
        return ReadByte;
}

//------------------------------------------------------------------------------
//子程序config_INA226
//------------------------------------------------------------------------------
void config_INA226()
{
    IIC_Start();
    IIC_WriteByte(0x80); //写命令。从器件地址为1000,0000(最后一位为R/W),A1 A0:GND GND
    IIC_WriteByte(0x00); //写地址。配置寄存器地址。
    IIC_WriteByte(0x43); //配置寄存器。0100'010,1'01,11'0,111(16个平均数,总线2.116ms,分流4.156,共100.352ms)
    IIC_WriteByte(0xff);
    IIC_Stop();
}

//------------------------------------------------------------------------------
//子程序cal_INA226
//------------------------------------------------------------------------------
void cal_INA226()
{
    IIC_Start();
    IIC_WriteByte(0x80); //写命令。从器件地址为1000,0000(最后一位为R/W),A1 A0:GND GND
    IIC_WriteByte(0x05); //写地址。校准寄存器地址。
    IIC_WriteByte(0x04); //最大电流取6A,Current_LSB=6/(2^15)=0.00018,取0.0002A,R_shut=0.025,CAL=1024(0x0400)
    IIC_WriteByte(0x00);
    IIC_Stop();
}

u16 INA226_ReadData(u8 addr)
{
        u16 temp=0;
        IIC_Start();
        IIC_WriteByte(addr);
        IIC_Stop();
       
        IIC_Start();
        IIC_WriteByte(addr+1);
        IIC_WaitAck();
        temp = IIC_ReadByte(1);
        temp<<=8;       
        temp |= IIC_ReadByte(0);
        IIC_Stop();
        return temp;
}

void INA226_SetRegPointer(u8 addr,u8 reg)
{
        //IIC_Start();
        //IIC_WriteByte(addr);
        //IIC_WriteByte(reg);
        //IIC_Stop();

        IIC_Start();
        IIC_WriteByte(addr);
        IIC_WaitAck();
        IIC_WriteByte(reg);
        IIC_WaitAck();
        IIC_Stop();       
}

u16 INA226_GetCurrent(u8 addr)
{
        u32 temp1=0;

        INA226_SetRegPointer(addr,SV_REG);
        temp1 = INA226_ReadData(addr);
        if(temp1&0x8000)
        {
                temp1 = ~(temp1 - 1);       
                temp1 = (temp1*25 + 5) / 10 / 5;               
        }
        else
        {
                INA226_SetRegPointer(addr,CUR_REG);
                temp1 = INA226_ReadData(addr);
                temp1 = temp1&0x7fff;
        }
        return temp1;
}

// 1.25mV/bit
u16 INA226_GetVoltage(u8 addr)
{
        u32 temp=0;
        INA226_SetRegPointer(addr,BV_REG);
        temp = INA226_ReadData(addr);
        temp = (temp*125 + 50)/100;
        return (u16)temp;       
}

// 2.5uV/bit
u16 INA226_GetShuntVoltage(u8 addr)
{
        u32 temp1=0;
        INA226_SetRegPointer(addr,SV_REG);
        temp1 = INA226_ReadData(addr);
        if(temp1&0x8000)        temp1 = ~(temp1 - 1);       
        temp1 = (temp1*25 + 5) / 10;
        return (u16)temp1;       
}


u16 getcurrent,getvol,getshutvol;

void INA226_Test(void)
{
        getcurrent = INA226_GetCurrent(INA226_ADDRESS);
        getvol = INA226_GetVoltage(INA226_ADDRESS);
        getshutvol = INA226_GetShuntVoltage(INA226_ADDRESS);
}

然后对下面几个变量进行在线观察,结果如下:
getcurrent 一直为:0x3852
getvol一直为:0x3fff
getshutvol一直为:0x199C

不知道为什么,是我的代码有问题吗,请大家帮我看看,谢谢!
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。