【无标题】ARDUINO和bq3060通信

ARDUINO和bq3060的通信


前言

手头的一台平板式笔记本的电池因为充电口松动接触不良造成容量严重亏损,开后盖看到智能电池内部使用的是ti的bq3060电池管理芯片,上网查阅都是单片机与之通信的文章,因为手头有很多闲置的arduino教学实验器材,顺手拿一块过来参照相关文章的介绍,模拟SMBus通信格式,理顺时序关系,很快就成功实现了Arduino和bq3060的通信。再次展现了Arduino轻便简洁上手块的强大功能,以下是我的代码介绍。


一、SMBus简介

SMBus(System Management Bus)是Intel与Duracell共同制定的接口,多用于笔记本和电池之间的通信管理,协议类似于I2C接口,但是有比较严格的应答时序,一般不能直接使用I2C协议。我猜测遇到挫折的朋友基本上都是应答时序没有吃透的缘故,个别贡献的文章也多在应答时序埋坑,当然也应该要感谢这些做出贡献的朋友!

二、核心代码

1.通信开始

代码如下:

void SMBus_Start(){//模拟SMBus协议的启动函数,参考SMBus通信协议
  digitalWrite(SDA1 , 1);//预置空闲状态
  digitalWrite(SCL1 , 1); delayMicroseconds(1); //时钟线高电平
  digitalWrite(SDA1 , 0); delayMicroseconds(1); //拉低数据线,SMBus启动
  digitalWrite(SCL1 , 0); delayMicroseconds(12); //时钟线低电平,太小偶尔会出错
}

2.结束通信

代码如下:

void SMBus_Stop(){ //SMBus停止函数,参考SMBus通信协议
  digitalWrite(SCL1 , 0); //delayMicroseconds(1); 
  digitalWrite(SDA1 , 0); delayMicroseconds(1); 
  digitalWrite(SCL1 , 1); delayMicroseconds(1); 
  digitalWrite(SDA1 , 1); //数据线拉高,释放总线
}

3.等待应答

代码如下:


void SMBus_CheckAck(){//从应答函数,等待bq3060应答
    unsigned char i;
    pinMode(SDA1, INPUT_PULLUP); 
    digitalWrite(SCL1 , 1);
    while (digitalRead(SDA1));// 检测有无应答
    pinMode(SDA1, OUTPUT);
    digitalWrite(SCL1 , 0); 
    delayMicroseconds(100);  
}

4.发送应答

代码如下:

void SMBus_SendAck(bool n){
  unsigned char i;
  if (n) {
    digitalWrite(SDA1 , 1);
    delayMicroseconds(1);
  }
  else {
    digitalWrite(SDA1 , 0);
    delayMicroseconds(1);
  }

  digitalWrite(SCL1 , 1);
   delayMicroseconds(1);
  digitalWrite(SCL1 , 0); 
  delayMicroseconds(100);
}

5.读取1个字节

代码如下:

unsigned char SMBus_ReadByte(){
  unsigned char i, k = 0;
  pinMode(SDA1, INPUT_PULLUP);
  for ( i = 0; i < 8; i++ ) 
  {
    digitalWrite(SCL1 , 1); 
    delayMicroseconds(1);
    k = (k << 1) | digitalRead(SDA1); //按位读取
    digitalWrite(SCL1 , 0); 
    delayMicroseconds(1);
  }
  pinMode(SDA1, OUTPUT);
  return k;  
}

6.写入1个字节

代码如下:

void SMBus_WriteByte(unsigned char data){
  unsigned char i;
  temp = data;
  for (i = 0; i < 8; i++)   //按位写入
  {
    digitalWrite(SCL1 , 0); 
    delayMicroseconds(1);
    if ((data << i) & 0x80) {
      digitalWrite(SDA1 , 1);
    }
    else {
      digitalWrite(SDA1 , 0);
    }
    delayMicroseconds(1);
    digitalWrite(SCL1 , 1);
     delayMicroseconds(1);
  }

  digitalWrite(SCL1 , 0);
  delayMicroseconds(1);
  digitalWrite(SDA1 , 1);//拉高数据线,释放总线
  delayMicroseconds(1); 
}

7.通信测试

代码如下:

unsigned int SMBus_ReadTest(unsigned char addr)//参考bq3060通信格式
  unsigned char dataH, dataL;
  unsigned int DATA;
  SMBus_Start();//启动协议
  SMBus_WriteByte(DEV_ADDW);//设备地址
  SMBus_CheckAck();//等待应答
  SMBus_WriteByte(addr);//Reg地址
  SMBus_CheckAck();//等待应答
  SMBus_Start();//再次启动
  SMBus_WriteByte(DEV_ADDR);//设备地址
 SMBus_CheckAck();//等待应答
  dataL = SMBus_ReadByte();//读取低字节
  SMBus_SendAck(0);//发送应答
  dataH = SMBus_ReadByte();// << 8; //读取高字节
  SMBus_SendAck(1);//发送应答
  SMBus_Stop();//停止读取
  DATA=(dataH<<8)+dataL;
  return DATA;//返回数据
}

总结

本文仅仅简单介绍了Arduino和bq3060的通信核心代码,只要是遵循SMBus协议的同类芯片,大同小异都可以使用。

本文参考了以下文章和链接,并致谢贡献者:
SMBus接口协议

用单片机解锁笔记本电池被锁的教程及分析

基于SMBus协议的电池信息监测系统

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值