大家好,这个问题搞了几天了,头大,不知道问题在哪里,单片机跟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
不知道为什么,是我的代码有问题吗,请大家帮我看看,谢谢!
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
void I2C_Start(void)
{
// I2C_SDAOut();
SDA_out();
SDA_H();
SCL_H();
delay_nus(28);
SDA_L();
delay_nus(2);
SCL_L();
delay_nus(15);
}
void I2C_Stop(void)
{
// I2C_SDAOut();
SDA_out();
SCL_L();
SDA_L();
delay_nus(2);
SCL_H();
delay_nus(2);
SDA_H();
delay_nus(8);
}
void I2C_Ack(void)
{
// I2C_SDAOut();
SCL_L();
SDA_out();
SDA_H();
delay_nus(17);
SCL_H();
delay_nus(4);
SCL_L();
}
void I2C_NoAck(void)
{
// I2C_SDAOut();
SCL_L();
SDA_out();
SDA_H();
delay_nus(17);
SDA_L();
delay_nus(2);
SCL_H();
delay_nus(4);
SCL_L();
}
u8 I2C_WaitACK(void)
{
u8 errtime = 0;
// I2C_SDAIn();
SDA_in();
//SDA_H();
delay_nus(2);
SCL_L();
delay_nus(2);
while(Read_SDA())
{
errtime++;
if(errtime>250)
{
delay_ms(65530);
I2C_Stop();
return 1;
}
}
SCL_H();
delay_nus(4);
SCL_L();
//SDA_out();
//SDA_H();
//delay_nus(24);
return 0;
}
void I2C_WRData(u8 data)
{
u8 i;
SDA_out();
// I2C_SDAOut();
//SCL_L();
//SDA_L();
//delay_nus(15);
SDA_H();
delay_nus(6);
for(i=0;i<8;i++)
{
//I2C_SDA = (data&0x80)>>7;
if((data&0x80)>>7)
{
SDA_H();
}
else
{
SDA_L();
}
data<<=1;
delay_nus(4);// 2.4us
SCL_H();
delay_nus(2);
SCL_L();
delay_nus(4);
}
}
u8 I2C_RDData(u8 ack)
{
u8 i,data=0;
// I2C_SDAIn();
SDA_in();
for(i=0;i<8;i++)
{
SCL_L();
delay_nus(4);
SCL_H();
data<<=1;
if(Read_SDA()) data++;
delay_nus(4);
}
if(ack) I2C_Ack();
else I2C_NoAck();
return data;
}
void I2C_SDAOut(void)
{
GPIO_Init(GPIOC , GPIO_Pin_0 , GPIO_Mode_Out_PP_High_Slow);
}
void I2C_SDAIn(void)
{
GPIO_Init(GPIOC , GPIO_Pin_0 , GPIO_Mode_In_PU_No_IT);
}
void INA226_SendData(u8 addr,u8 reg,u16 data)
{
u8 temp=0;
I2C_Start();
I2C_WRData(addr);
I2C_WaitACK();
I2C_WRData(reg);
I2C_WaitACK();
temp = (u8)(data>>8);
I2C_WRData(temp);
I2C_WaitACK();
temp = (u8)(data&0x00FF);
I2C_WRData(temp);
I2C_WaitACK();
I2C_Stop();
}
void INA226_Init(void)
{
GPIO_Init(GPIOC , GPIO_Pin_0 , GPIO_Mode_Out_PP_High_Slow);
GPIO_Init(GPIOC , GPIO_Pin_1 , GPIO_Mode_Out_PP_High_Slow);
INA226_SendData(INA226_ADDR1,CFG_REG,0x43FF);
INA226_SendData(INA226_ADDR1,CAL_REG,1024);
}
void INA226_SetRegPointer(u8 addr,u8 reg)
{
I2C_Start();
I2C_WRData(addr);
I2C_WaitACK();
SDA_H();
SCL_L();
delay_nus(16);
I2C_WRData(reg);
I2C_WaitACK();
SDA_H();
SCL_L();
delay_nus(16);
I2C_Stop();
}
u16 INA226_ReadData(u8 addr)
{
u16 temp=0;
I2C_Start();
I2C_WRData(addr+1);
I2C_WaitACK();
temp = I2C_RDData(0);
temp<<=8;
temp |= I2C_RDData(0);
I2C_Stop();
return temp;
}
u8 INA226_AlertAddr(void)
{
u8 temp;
I2C_Start();
I2C_WRData(INA226_GETALADDR);
I2C_WaitACK();
temp = I2C_RDData(1);
I2C_Stop();
return temp;
}
// 1mA/bit
u16 INA226_GetCurrent(u8 addr)
{
u16 temp=0;
INA226_SetRegPointer(addr,SV_REG);
temp = INA226_ReadData(addr);
if(temp&0x8000)
{
temp = ~(temp - 1);
temp = (temp*25 + 5) / 10 / 5;
}
else
{
INA226_SetRegPointer(addr,CUR_REG);
temp = INA226_ReadData(addr);
temp = temp&0x7fff;
}
return temp;
}
// 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;
}
// .5uV/bit
u16 INA226_GetShuntVoltage(u8 addr)
{
u32 temp=0;
INA226_SetRegPointer(addr,SV_REG);
temp = INA226_ReadData(addr);
if(temp&0x8000) temp = ~(temp - 1);
temp = (temp*25 + 5) / 10;
return (u16)temp;
}
u16 getcurrent,getvol,getshutvol;
void INA226_Test(void)
{
getcurrent = INA226_GetCurrent(INA226_ADDRESS);
delay_nus(200); // 668us
getvol = INA226_GetVoltage(INA226_ADDRESS);
delay_nus(200); // 668us
getshutvol = INA226_GetShuntVoltage(INA226_ADDRESS);
delay_nus(200); // 668us
}
u16 GetCurrent_INA226(void)
{
return getcurrent;
}
一周热门 更多>