数码之家

 找回密码
 立即注册
搜索
查看: 2057|回复: 6

BQ3060读取数据错误

[复制链接]
发表于 2021-1-25 17:58:15 | 显示全部楼层 |阅读模式
不知道什么情况,时序是对的,读错数据。

本帖子中包含更多资源

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

x
发表于 2021-1-25 23:24:28 | 显示全部楼层
怎么个错法,这样看正常呀,0x00的命令返回数据不是固定的。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-1-26 20:13:55 | 显示全部楼层
zj97czb 发表于 2021-1-25 23:24
怎么个错法,这样看正常呀,0x00的命令返回数据不是固定的。

搞了一天还是不行,IIC没问题,我读了其他几个IIC的芯片都能正常,这个芯片就不行了,好奇怪啊。
这个红色镜头出现一个不知名脉冲,不晓得是啥。
                IIC_Start();


                IIC_Send_Byte(0x16);

                IIC_Send_Byte(0x00);

                IIC_Stop();

               

                IIC_Start();

                IIC_Send_Byte(0x17);

                temp[0] = IIC_Read_Byte(1);

                temp[1] = IIC_Read_Byte(0);

                IIC_Stop();

               

                HAL_Delay(500);

                printf("temp[0] = %d \r\n ",temp[0]);

                printf("temp[1] = %d \r\n ",temp[1]);



本帖子中包含更多资源

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

x
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-1-26 20:40:11 | 显示全部楼层
zj97czb 发表于 2021-1-25 23:24
怎么个错法,这样看正常呀,0x00的命令返回数据不是固定的。


读0X09寄存器,还是一样,好奇怪哦。。

本帖子中包含更多资源

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

x
回复 支持 反对

使用道具 举报

发表于 2021-1-26 22:39:11 | 显示全部楼层
它这个虽然也是IIC总线,但它是叫SMBUS,速率不能超过100kHz,它的应答时间也要长,最好是等它应答了才进行下一个。你可试着用我的程序移植,应该行的。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-1-27 08:33:11 | 显示全部楼层
zj97czb 发表于 2021-1-26 22:39
它这个虽然也是IIC总线,但它是叫SMBUS,速率不能超过100kHz,它的应答时间也要长,最好是等它应答了才进行 ...

M币不够,好尴尬:mad:
回复 支持 反对

使用道具 举报

发表于 2021-1-27 14:46:47 | 显示全部楼层
extern void          _nop_     (void);
//#define delay32us(); {_nop_();_nop_();_nop_();_nop_();};//6us定时

sbit SDA=P3^4;
sbit SCL=P3^5;

void delay32us()         //32微秒,STC15单片机,6MHz晶振
{                                                                        //20微秒,STC15单片机,12MHz晶振
  unsigned char us=15;
  while(us--);
                               
}

void delay12us()         //12微秒,STC15单片机,6MHz晶振
{                                                                        //7微秒,STC15单片机,12MHz晶振
  unsigned char us=5;
  while(us--);
                               
}

void delay(unsigned int z)//
{
unsigned int y;
  while(z--)
  {
    for(y=0;y<268;y++)//(123传统51单片机,12MHz晶振),268,STC12单片机,6MHz晶振
        {}
  }
}

void iic_start(void)
{
        SDA = 1;//时钟保持高,数据线从高到低一次跳变,I2C通信开始
        _nop_();
        SCL = 1;
        delay32us();// 延时33us
        SDA = 0;
        delay32us();
        SCL = 0;
        delay32us();
}
//-------------------------------------------------------------------
// 函数名称: iic_stop()
// 函数功能: 停止I2C总线数据传送子程序
//-------------------------------------------------------------------
void iic_stop(void)
{
        SCL = 0;
        SDA = 0;//时钟保持高,数据线从低到高一次跳变,I2C通信停止
        _nop_();
        SCL = 1;
        delay32us();
        SDA = 1;
}
//------------------------------------------------------------------
// 函数名称: iicInit_()
// 函数功能: 初始化I2C总线子程序
//------------------------------------------------------------------
/*void iicInit(void)
   {
    SDA=1;
        SCL=1;
   }*/
//-------------------------------------------------------------------
// 函数名称: slave_ACK
// 函数功能: 从机发送应答位子程序(OK)
//{
//                        time++;
//                        if(time>5500)
//                        {
        //                        iic_sotp();
        //                        return;
                               
//                        }
//                }
//-------------------------------------------------------------------
void check_ACK(void)
{
        //unsigned int time;
        //delay32us();
        SCL = 0;
        SDA = 0;
    delay32us();
        SDA=1;
        _nop_();
        while(SDA);//等待从机拉低数据线,表示不忙
               
        SCL = 1;
        delay32us();
        //delay32us();
        SCL = 0;
        delay32us();
        delay32us();
       
       
}
//-------------------------------------------------------------------
// 函数名称: master_ACK
// 函数功能: 主机发送应答位子程序(OK)
//-------------------------------------------------------------------
void master_ACK(void)
{
        //delay32us();
        SCL = 0;
        //SDA = 0;
    delay32us();
        _nop_();
        SCL = 1;
        _nop_();
        SDA=0;
        _nop_();
        //SCL = 1;
        delay32us();
        SDA=1;
        _nop_();
        //delay32us();
        SCL = 0;
       
        delay32us();//延时要>100us
        delay32us();
        delay32us();
       
}

//-------------------------------------------------------------------
// 函数名称: master_ACK
// 函数功能: 主机发送数据接收完整应答位子程序(OK)
//-------------------------------------------------------------------
void master_ACK_ok(void)
{
        //delay32us();
        SCL = 0;
        //SDA = 0;
    delay32us();
        SDA=1;
        _nop_();
        SCL = 1;
        delay32us();
        //delay32us();
        SCL = 0;
        _nop_();
        SDA=0;
        delay32us();
        delay32us();
        delay32us();
        delay32us();
}
//-------------------------------------------------------------------
// 函数名称: slave_NOACK
// 函数功能: 主机发送非应答位子程序,迫使数据传输过程结束
//-------------------------------------------------------------------
/*void slave_NOACK(void)
{
        SCL = 0;
        SDA = 1;
        _nop_();
        _nop_();
        SCL = 1;
        _nop_();
        _nop_();
        SCL = 0;
}*/
//-------------------------------------------------------------------
// 函数名称: check_ACK
// 函数功能:从机应答位检查子程序,迫使数据传输过程结束
//-------------------------------------------------------------------
/*bit check0_ACK(void)
{
  bit ErrorBit;
  SDA=1;
  SCL=1;
  ErrorBit=SDA;
  SCL=0;
  return(ErrorBit);

}*/

//-------------------------------------------------------------------
// 函数名称: IICSendByte
// 入口参数: ch
// 函数功能: 写一个字节
//-------------------------------------------------------------------
void IICSendByte(unsigned char input)
{
unsigned char temp;
for(temp=8;temp!=0;temp--)
{
  SDA=(bit)(input&0x80);
         delay12us();
        SCL=1;
         delay32us()        ;
  SCL=0;
          delay12us();
        SDA=0;
         delay32us()        ;
  input=input<<1;
}
}

unsigned char IICreceiveByte(void) // 从SDA线上读取一个数据字节,共八位
{
  unsigned char n=8;
unsigned char tdata=0;
//SDA = 1;
while(n--)
{

  SCL = 0;
  delay32us();
  SCL = 1;
         //while(!SCL);
  delay32us();
         while(!SCL);
        tdata =tdata<<1;//左移一位
if(SDA) tdata++;//tdata|0x01;//
                //else tdata=tdata;
  }

return(tdata);
}


//写四个字节到BQ3060中,低位在前
void Write_BQ3060_four(unsigned char address,unsigned dat0,unsigned dat1,unsigned dat2,unsigned dat3)
{
        //unsigned char dat_h,dat_l;
iic_start();
IICSendByte(0x16);
check_ACK();
IICSendByte(address);
check_ACK();
IICSendByte(4);
check_ACK();
       
IICSendByte(dat0);
check_ACK();

IICSendByte(dat1);
check_ACK();
IICSendByte(dat2);
check_ACK();
IICSendByte(dat3);
check_ACK();       
iic_stop();
delay(10);//24c02片内写数据时间        (10毫秒)
}
//写两个字节到BQ3060中
void Write_BQ3060_two(unsigned char address,unsigned int dat)
{
        unsigned char dat_h,dat_l;
iic_start();
IICSendByte(0x16);
check_ACK();
IICSendByte(address);
check_ACK();
dat_l=dat%256        ;
IICSendByte(dat_l);
check_ACK();
dat_h=dat/256        ;       
IICSendByte(dat_h);
check_ACK();       
iic_stop();
delay(10);//24c02片内写数据时间        (10毫秒)
}

//写一个字节到BQ3060中
void Write_BQ3060_one(unsigned char address,unsigned char dat)
{
        //unsigned char dat_h,dat_l;
iic_start();
IICSendByte(0x16);
check_ACK();
IICSendByte(address);
check_ACK();
//dat_l=dat%256        ;
IICSendByte(dat);

check_ACK();       
iic_stop();
delay(10);//24c02片内写数据时间        (10毫秒)
}


//从bq3060中读出2个字节
unsigned int Read_bq3060(unsigned char address)
{
unsigned int chh,chl;//ch0,ch1;
unsigned int ch;       
iic_start();
IICSendByte(0x16);//发送器件地址0x16;+1为读
check_ACK();
       
IICSendByte(address);//发送要读出的字的地址
check_ACK();
iic_start();//重新启动总线
IICSendByte(0x17);//发送读命令和器件地址
check_ACK();
chl=IICreceiveByte();
master_ACK();
chh=IICreceiveByte();
master_ACK_ok();
iic_stop();
ch=chh*256+chl;       
return(ch);
}



//从bq3060中读出4个字节,
void Read_bq3060_four(unsigned char address)
{
//unsigned int chh,chl,ad0,ad1;
//unsigned char ch;       
iic_start();
       
IICSendByte(0x16);//发送器件地址0x16;+1为读
check_ACK();
IICSendByte(address);//发送要读出的字的地址
check_ACK();
//IICSendByte(4);//发送要读出的字的数量
//check_ACK();       
iic_start();//重新启动总线
IICSendByte(0x17);//发送读命令和器件地址
check_ACK();
ch=IICreceiveByte();//告诉主机有多少个字节
master_ACK();       
temp[0]=IICreceiveByte();
master_ACK();
temp[1]=IICreceiveByte();
master_ACK();       
temp[2]=IICreceiveByte();
master_ACK();       
temp[3]=IICreceiveByte();
master_ACK_ok();
iic_stop();

}

打赏

参与人数 1家元 +16 收起 理由
q2616444 + 16 只有这么多M币了,清笑纳,O(∩_∩)O哈哈~.

查看全部打赏

回复 支持 3 反对 0

使用道具 举报

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

本版积分规则

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

闽公网安备35020502000485号

闽ICP备2021002735号-2

GMT+8, 2025-5-18 05:15 , Processed in 0.436801 second(s), 12 queries , Redis On.

Powered by Discuz!

© 2006-2025 MyDigit.Net

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